From 7aa203150fc1a2ec79c681c13f0d486d531746eb Mon Sep 17 00:00:00 2001 From: George Halkiadakis Date: Sun, 12 Mar 2023 23:57:48 +0200 Subject: error pages; js system to support back/front-end --- html/assets/js/forms/ajaxForm.js | 188 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100644 html/assets/js/forms/ajaxForm.js (limited to 'html/assets/js/forms/ajaxForm.js') diff --git a/html/assets/js/forms/ajaxForm.js b/html/assets/js/forms/ajaxForm.js new file mode 100644 index 0000000..6ade446 --- /dev/null +++ b/html/assets/js/forms/ajaxForm.js @@ -0,0 +1,188 @@ +$.defineAttributePlugin('ajaxform', ['serialize', 'debounce'], function ($element, options, serialize, debounce) { + options = options || {}; + options.Url = options.Url || $element.attr('action'); + + var loader = ''; + var submit; + var onError = debounce(scrollToFirstError, 100); + + onError(); + + function getElementToReplace() { + var $toReplace; + if (options.ElementID) { + $toReplace = $("#" + options.ElementID); + } + else { + $toReplace = $element.closest('.ajax-replace-container'); + if ($toReplace.length === 0) { + $toReplace = $element.closest('div.form'); + } + if ($toReplace.length === 0) { + $toReplace = $element; + } + } + return $toReplace; + } + + function ajaxComplete(response, $element) { + var flow = response.getResponseHeader("X-FlowComplete"); + + if (flow) { + + $element.trigger('flowcomplete', flow); + } + } + + function createReplacement(content) { + return $(content); // $('
' + content + '
'); //.find('> *'); + } + var submitting = false; + submit = function () { + if (!options.Url || submitting) { + return; + } + submitting = true; + mask(); + var headers = { + "X-NoRedirect": "true" + }; + var $toReplace = getElementToReplace(); + if ($toReplace.is('.ajax-modal')) { + headers["X-Modal"] = "true"; + } + var result = { + redirected: false + }; + + var ajaxOptions = { + url: options.Url, + headers: headers, + beforeSend: function () { + $('body').trigger('TopLoader:Show'); + $element.find('[type="submit"]').attr('disabled', 'disabled'); + }, + type: 'post', + success: function (content, status, response) { + if (content.RedirectUrl) { + result.redirected = true; + window.location.href = content.RedirectUrl; + return; + } + if (content) { + var $replacement = createReplacement(content); + $toReplace.replaceWith($replacement); + $replacement.parseAttributePlugins(); + ajaxComplete(response, $replacement); + $replacement.trigger('ajaxForm.submitted'); + } + else { + ajaxComplete(response, $element); + } + + + }, + complete: function () { + $('body').trigger('TopLoader:Hide'); + if (!result.redirected) { + unmask(); + $element.find('[clicked]').removeAttr('clicked'); + $element.find('[type="submit"]').removeAttr('disabled'); + submitting = false; + } + }, + error: function (r) { + if (r.status === 401) { + location.reload(); + return; + } + } + }; + + if ($element.is("form") && $element.prop("enctype") === "multipart/form-data") { + ajaxOptions.data = new FormData($element.get(0)); + ajaxOptions.contentType = false; + ajaxOptions.processData = false; + } else { + var $elements = $element.find('input[name], textarea[name], select[name], :submit[name][clicked=true]') + ajaxOptions.data = serialize($elements); + } + + $.ajax(ajaxOptions); + }; + + function mask() { + $element.find('[clicked]').addClass('in-progress').append(loader); + $element.trigger('ajaxform.submitting'); + } + function unmask() { + $element.find('[clicked]').removeClass('in-progress').find('.ajax-loader').remove(); + $element.trigger('ajaxform.complete'); + } + + if (options.LazyVerification) { + var s = submit; + submit = function () { + $.ajax({ + url: options.LazyVerification, + beforeSend: function () { + $element.find('[type="submit"]').attr('disabled', 'disabled'); + }, + type: 'post', + success: function (content, status, response) { + $element.append(content); + s(); + }, + complete: function () { + $element.find('[type="submit"]').removeAttr('disabled'); + } + }); + }; + } + $element.find("[type=submit]").click(function () { + $element.find("[type=submit]").removeAttr("clicked"); + $(this).attr("clicked", "true"); + }); + if ($element.is('form')) { + $element.on('submit', function (e) { + + if (options.Url) { + e.preventDefault(); + } + var clickedButton = $element.find('[clicked]'); + if (!clickedButton.is('.cancel')) { + if (!$element.valid()) { + console.warn('validation error'); + onError(); + return; + } + } + submit(); + }); + } + else { + $element.find('[type="submit"]').click(function (e) { + e.preventDefault(); + e.stopPropagation(); + submit(); + }); + } + $element.data('ajaxform.submit', submit); + + function scrollToFirstError() { + var $erroneousElement = $element.find(".field-validation-error").eq(0).parents(".field"); + + if ($erroneousElement.length === 1) { + var top = $erroneousElement.offset().top; + var $header = $('.headerWrp'); + if ($header.length) { + top -= $header.height() + 80; + } + $('html,body').animate({ + scrollTop: top + }, 500); + $erroneousElement.find("input").focus(); + } + } + +}); -- cgit v1.2.3