/* Copyright (C) 2012-2013 Denver Gingerich, ** Copyright (C) 2013-2014, 2020 Bradley M. Kuhn, ** Copyright (C) 2016, 2020 Brett Smith. ** License: GPLv3-or-later ** Find a copy of GPL at https://sfconservancy.org/GPLv3 */ var NEW_AMOUNT_EVENT = 'conservancy:newamount'; var flipClass = function(elem, byeClass, hiClass) { var classList = elem.classList; classList.remove(byeClass); classList.add(hiClass); } var buildAmountData = function(amountInput) { var amountData = { minAmount: parseFloat(amountInput.min), newAmount: parseFloat(amountInput.value), } if (amountInput.dataset.oldAmount !== undefined) { amountData.oldAmount = parseFloat(amountInput.dataset.oldAmount); } return amountData; } var supportTypeSelector = function(supportTypeHash) { return $(supportTypeHash + "Selector"); }; var $window = $(window); $window.load(function() { /* We've sometimes published links that say #renew instead of #renewal. Rewrite that to work as intended. */ if (window.location.hash === "#renew") { window.location.hash = "#renewal"; } var $selectorLink = supportTypeSelector(window.location.hash); if ($selectorLink.length > 0) { $window.scrollTop($selectorLink.offset().top); } }); $(document).ready(function() { // Forms start in "invalid" form, with the errors shown, so that // non-Javascript users see the errors by default and know what they must // enter. Now we hide those for JavaScript users: var $formCorrectionNeeded = $('#form-correction-needed'); $formCorrectionNeeded.addClass('hidden'); $('form.supporter-form').each(function(index, form) { var $amountInput = $('input[type=number]', form).first(); var $amountError = $('.form-error', $amountInput.parents('.supporter-form-input')); $amountError.on(NEW_AMOUNT_EVENT, function(event, amountData) { var isValid = amountData.newAmount >= amountData.minAmount; if (amountData.oldAmount === undefined) { if (isValid) { $amountError.addClass('hidden'); } else { flipClass($amountInput[0], 'valid', 'invalid'); $amountError.removeClass('hidden'); } } else if (isValid) { flipClass($amountInput[0], 'invalid', 'valid'); $amountError.fadeOut(); } else if (amountData.oldAmount >= amountData.minAmount) { flipClass($amountInput[0], 'valid', 'invalid'); $amountError.fadeIn(); } }); $amountInput.on('input', function(event) { event.target.classList.remove('invalid'); }).on('focusout', function(event) { var amountInput = event.target; var amountData = buildAmountData(amountInput); $amountError.trigger(NEW_AMOUNT_EVENT, amountData); amountInput.dataset.oldAmount = amountData.newAmount; }).trigger('focusout'); $(form).on('submit', function(event) { var amountData = buildAmountData($amountInput[0]); if (amountData.newAmount >= amountData.minAmount) { $formCorrectionNeeded.addClass('hidden'); } else { $formCorrectionNeeded.removeClass('hidden') .css("font-weight", "bold").css("font-size", "150%"); event.preventDefault(); } }); }); var selectSupportType = function(event) { var $selectedLink = $(event.target); $(".supporter-type-selector a").removeClass("supporter-type-selector-selected"); $selectedLink.addClass("supporter-type-selector-selected"); $(".supporter-type-selection").hide(); $(event.target.hash).show(); $formCorrectionNeeded.addClass('hidden'); return false; }; $(".supporter-type-selector a").bind("click", selectSupportType); var selectSupportTypeFromHash = function() { return supportTypeSelector(window.location.hash).click(); }; $window.bind("hashchange", selectSupportTypeFromHash); if (selectSupportTypeFromHash().length === 0) { supportTypeSelector("#annual").click(); } var want_id = window.location.hash.substr(1) || "do not match any id"; var $expandable_counts = []; // First, build a count of expandable div sections $('div.expandable-section').each(function(index, section) { var $ourid = $(section).attr('id'); if ($ourid == undefined) { $ourid = "__global"; } $expandable_counts[$ourid] = 0; }); $('div[data-read-more]').each(function(index, readmore) { var $readmore = $(readmore) var $header = $readmore.prev('h3'); if ($header.length && $header[0].id === want_id) { // Do nothing, leave it alone } else { var $ourid = $readmore.closest(".expandable-section" ).attr('id'); if ($ourid == undefined) { $ourid = "__global"; } // Set up the link for this specific section using the text from // the data-read-more atrribute on the div specific to this section var $linkpara = $('
'); var $readlink = $linkpara.children('a'); $readlink.append($readmore.data('read-more')); $readlink.on('click', function(event) { // When clicked, we'll restore the actual text and fade it in // quickly, and also see if there are any remaining // expandable sections left in this particular expandable // section. If none are left, make the "Expand all" button // (which lives in an 'a' anchor of the class 'expander') disappear. $linkpara.replaceWith($readmore); $readmore.fadeIn('fast'); $expandable_counts[$ourid]--; if ($expandable_counts[$ourid] <= 0) { $readmore.closest(".expandable-section" ) .children('a.expander').each(function(index, element){ $(element).fadeOut('slow'); }) } }); $readmore.hide().replaceWith($linkpara); $expandable_counts[$ourid]++; } }); // Final two each's enable the "Expand All" link. $('a[data-expand-link-text]').each(function(index, element) { var $element = $(element); $element.append($element.data('expand-link-text')); }); $('.expandable-section').each(function(index) { var $expandlink = $(this).children('a.expander'); var $ourexpandablesection = $(this); $expandlink.on('click', function(event) { $expandlink.fadeOut('slow'); $ourexpandablesection.find('.read-more').each(function(index) { $(this).click(); }); }); }); });