Files @ cb5b5ec23fc2
Branch filter:

Location: website/www/conservancy/static/js/supporter-page.js - annotation

cb5b5ec23fc2 4.3 KiB application/javascript Show Source Show as Raw Download as Raw
brett
supporter: Refactor amount-checking JavaScript.

* Separate out amount-parsing and reacting into separate events. This sets
the stage for other elements to react to the custom
'conservancy:newamount' event.
* Set up events in the context of each supporter form, with closures. This
lets us avoid weird CSS selector gymnastics in the event, and instead
drill down from the form to find the elements we need.

There are no functional changes in this code, barring bugs.
01eb8c80c8c1
ec26bfc846e3
ec26bfc846e3
342590123ff5
01eb8c80c8c1
01eb8c80c8c1
01eb8c80c8c1
cb5b5ec23fc2
cb5b5ec23fc2
6392ae3a4313
6392ae3a4313
6392ae3a4313
6392ae3a4313
6392ae3a4313
6392ae3a4313
cb5b5ec23fc2
cb5b5ec23fc2
cb5b5ec23fc2
cb5b5ec23fc2
cb5b5ec23fc2
cb5b5ec23fc2
cb5b5ec23fc2
cb5b5ec23fc2
cb5b5ec23fc2
6392ae3a4313
6392ae3a4313
ab29d4563909
19e744788b7f
ab29d4563909
ab29d4563909
ab29d4563909
ab29d4563909
ab29d4563909
492de3eab3de
492de3eab3de
492de3eab3de
492de3eab3de
492de3eab3de
ab29d4563909
ab29d4563909
ab29d4563909
ab29d4563909
ab29d4563909
ab29d4563909
01eb8c80c8c1
674261e0f0c2
674261e0f0c2
6392ae3a4313
6392ae3a4313
ba0df40639d9
674261e0f0c2
cb5b5ec23fc2
cb5b5ec23fc2
cb5b5ec23fc2
cb5b5ec23fc2
cb5b5ec23fc2
cb5b5ec23fc2
cb5b5ec23fc2
cb5b5ec23fc2
cb5b5ec23fc2
cb5b5ec23fc2
cb5b5ec23fc2
cb5b5ec23fc2
cb5b5ec23fc2
cb5b5ec23fc2
cb5b5ec23fc2
cb5b5ec23fc2
cb5b5ec23fc2
cb5b5ec23fc2
cb5b5ec23fc2
ba0df40639d9
cb5b5ec23fc2
6392ae3a4313
cb5b5ec23fc2
cb5b5ec23fc2
cb5b5ec23fc2
cb5b5ec23fc2
cb5b5ec23fc2
cb5b5ec23fc2
cb5b5ec23fc2
cb5b5ec23fc2
cb5b5ec23fc2
cb5b5ec23fc2
cb5b5ec23fc2
cb5b5ec23fc2
cb5b5ec23fc2
cb5b5ec23fc2
cb5b5ec23fc2
cb5b5ec23fc2
cb5b5ec23fc2
cb5b5ec23fc2
cb5b5ec23fc2
86e780340a2b
b90413809f26
86ef51db5dff
86ef51db5dff
86ef51db5dff
86ef51db5dff
78c474caaccc
78c474caaccc
78c474caaccc
78c474caaccc
78c474caaccc
6392ae3a4313
9d30d7431a1e
86ef51db5dff
86ef51db5dff
86ef51db5dff
86ef51db5dff
9d30d7431a1e
86ef51db5dff
9d30d7431a1e
19e744788b7f
9d30d7431a1e
9d30d7431a1e
44301d386ba0
/* Copyright (C) 2012-2013 Denver Gingerich, 
** Copyright (C) 2013-2014 Bradley M. Kuhn,
** Copyright (C) 2016 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[0].parentNode);

        $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();
        var hashIndex = event.target.href.lastIndexOf('#');
        if (hashIndex > -1) {
            $(event.target.href.slice(hashIndex)).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();
    }
});