$.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(); } } });