diff --git a/opentech/apply/funds/templates/funds/application_base.html b/opentech/apply/funds/templates/funds/application_base.html index f3c0e80f6e04a9d4272d80f2e35f86361913803f..0b0bb40687c985cba1857a9dcc9d31c5b1be2114 100644 --- a/opentech/apply/funds/templates/funds/application_base.html +++ b/opentech/apply/funds/templates/funds/application_base.html @@ -42,3 +42,7 @@ {% endif %} </div> {% endblock %} + +{% block extra_js %} + <script src="{% static 'js/apply/mailgun-validator.js' %}"></script> +{% endblock %} diff --git a/opentech/static_src/src/javascript/apply/mailgun-validator.js b/opentech/static_src/src/javascript/apply/mailgun-validator.js new file mode 100644 index 0000000000000000000000000000000000000000..238c12909abd82fe846159f83b10c51161f89397 --- /dev/null +++ b/opentech/static_src/src/javascript/apply/mailgun-validator.js @@ -0,0 +1,122 @@ +(function ($) { + + 'use strict'; + + $.fn.mailgunValidator = function (options) { + return this.each(function () { + var thisElement = $(this); + thisElement.focusout(function (e) { + // Trim string and autocorrect whitespace issues + var elementValue = thisElement.val(); + elementValue = $.trim(elementValue); + thisElement.val(elementValue); + + // Attach event to options + options.e = e; + + run_validator(elementValue, options, thisElement); + }); + }); + }; + + function run_validator(address_text, options, element) { + // Abort existing AJAX Request to prevent flooding + if (element.mailgunRequest) { + element.mailgunRequest.abort(); + element.mailgunRequest = null; + } + + // don't run validator without input + if (!address_text) { + return; + } + + // validator is in progress + if (options && options.in_progress) { + options.in_progress(options.e); + } + + // don't run dupicate calls + if (element.mailgunLastSuccessReturn) { + if (address_text === element.mailgunLastSuccessReturn.address) { + if (options && options.success) { + options.success(element.mailgunLastSuccessReturn, options.e); + } + return; + } + } + + // length and @ syntax check + var success = false; + var error_message = false; + if (address_text.length > 512) { + error_message = 'Email address exceeds maxiumum allowable length of 512.'; + } + else if (address_text.split('@').length - 1 !== 1) { + error_message = 'Email address must contain only one @.'; + } + + if (error_message) { + if (options && options.error) { + options.error(error_message, options.e); + } + return; + } + + // timeout incase of some kind of internal server error + var timeoutID = setTimeout(function () { + error_message = 'Error occurred, unable to validate address.'; + if (!success) { + // Abort existing AJAX Request for a true timeout + if (element.mailgunRequest) { + element.mailgunRequest.abort(); + element.mailgunRequest = null; + } + + if (options && options.error) { + options.error(error_message, options.e); + } + } + }, 30000); // 30 seconds + + // make ajax call to get validation results + element.mailgunRequest = $.ajax({ + type: 'GET', + url: 'https://api.mailgun.net/v3/address/validate', + data: { + address: address_text, + api_key: options.api_key + }, + dataType: 'jsonp', + crossDomain: true, + success: function (data, status_text) { + clearTimeout(timeoutID); + + element.mailgunLastSuccessReturn = data; + if (options && options.success) { + options.success(data, options.e); + } + }, + error: function (request, status_text, error) { + clearTimeout(timeoutID); + error_message = 'Error occurred, unable to validate address.'; + + if (options && options.error) { + options.error(error_message, options.e); + } + } + }); + } + + $('input[type=email]').each(function () { + $(this).after('<div class="status"></div>').mailgunValidator({ + api_key: 'pubkey-b3ea454f53bcd621d767e64f0b4ef0ac', + error: validation_error + }); + }); + + function validation_error(error_message) { + $('.status').html(error_message); + } + +})(jQuery);