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.
This commit is contained in:
parent
5f9a4395f3
commit
cb5b5ec23f
1 changed files with 51 additions and 38 deletions
|
@ -5,19 +5,23 @@
|
||||||
** Find a copy of GPL at https://sfconservancy.org/GPLv3
|
** Find a copy of GPL at https://sfconservancy.org/GPLv3
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
var NEW_AMOUNT_EVENT = 'conservancy:newamount';
|
||||||
|
|
||||||
var flipClass = function(elem, byeClass, hiClass) {
|
var flipClass = function(elem, byeClass, hiClass) {
|
||||||
var classList = elem.classList;
|
var classList = elem.classList;
|
||||||
classList.remove(byeClass);
|
classList.remove(byeClass);
|
||||||
classList.add(hiClass);
|
classList.add(hiClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
var checkAmountValid = function(amountInput) {
|
var buildAmountData = function(amountInput) {
|
||||||
var value = parseFloat(amountInput.value);
|
var amountData = {
|
||||||
var min = parseFloat(amountInput.min);
|
minAmount: parseFloat(amountInput.min),
|
||||||
/* Is the value is a valid float, it will stringify back to itself. */
|
newAmount: parseFloat(amountInput.value),
|
||||||
var isValid = (String(value) === amountInput.value) && (value >= min);
|
}
|
||||||
amountInput.dataset.valid = isValid ? '1' : '0';
|
if (amountInput.dataset.oldAmount !== undefined) {
|
||||||
return isValid;
|
amountData.oldAmount = parseFloat(amountInput.dataset.oldAmount);
|
||||||
|
}
|
||||||
|
return amountData;
|
||||||
}
|
}
|
||||||
|
|
||||||
var supportTypeSelector = function(supportTypeHash) {
|
var supportTypeSelector = function(supportTypeHash) {
|
||||||
|
@ -45,38 +49,47 @@ $(document).ready(function() {
|
||||||
var $formCorrectionNeeded = $('#form-correction-needed');
|
var $formCorrectionNeeded = $('#form-correction-needed');
|
||||||
$formCorrectionNeeded.addClass('hidden');
|
$formCorrectionNeeded.addClass('hidden');
|
||||||
|
|
||||||
$('form.supporter-form input[type=number]').on('input', function(event) {
|
$('form.supporter-form').each(function(index, form) {
|
||||||
event.target.classList.remove('invalid');
|
var $amountInput = $('input[type=number]', form).first();
|
||||||
}).on('focusout', function(event) {
|
var $amountError = $('.form-error', $amountInput[0].parentNode);
|
||||||
var amountInput = event.target;
|
|
||||||
var wasValid = amountInput.dataset.valid === '1';
|
|
||||||
var isValid = checkAmountValid(amountInput);
|
|
||||||
if (isValid) {
|
|
||||||
flipClass(amountInput, 'invalid', 'valid');
|
|
||||||
if (!wasValid) {
|
|
||||||
$('.form-error', amountInput.parentNode).fadeOut();
|
|
||||||
}
|
|
||||||
} else if (wasValid) {
|
|
||||||
flipClass(amountInput, 'valid', 'invalid');
|
|
||||||
$('.form-error', amountInput.parentNode).fadeIn();
|
|
||||||
}
|
|
||||||
}).each(function(index, elem) {
|
|
||||||
if (checkAmountValid(elem)) {
|
|
||||||
$('.form-error', elem.parentNode).addClass('hidden');
|
|
||||||
} else {
|
|
||||||
elem.classList.add('invalid');
|
|
||||||
$('.form-error', elem.parentNode).removeClass('hidden');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$('form.supporter-form').on('submit', function(event) {
|
$amountError.on(NEW_AMOUNT_EVENT, function(event, amountData) {
|
||||||
if (checkAmountValid($('input[name=amount]', event.target)[0])) {
|
var isValid = amountData.newAmount >= amountData.minAmount;
|
||||||
$formCorrectionNeeded.addClass('hidden');
|
if (amountData.oldAmount === undefined) {
|
||||||
} else {
|
if (isValid) {
|
||||||
$formCorrectionNeeded.removeClass('hidden')
|
$amountError.addClass('hidden');
|
||||||
.css("font-weight", "bold").css("font-size", "150%");
|
} else {
|
||||||
event.preventDefault();
|
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 selectSupportType = function(event) {
|
||||||
|
|
Loading…
Reference in a new issue