Extend a specific jQuery method in ASP.NET MVC jquery.unobtrusive-ajax.js

Asked

Viewed 500 times

3

I’m using the Extensions methods @Ajax.BeginForm() to save the data via AJAX. To avoid running more than one click on the Submit button, which could cause a double Insert in my database, I decided to include a small chunk of code within the jquery.unobtrusive-ajax.js file, which disables the Submit button.

I included the code snippet right after the calls of the method that displays a Download, respectively loading.show(duration); and loading.hide(duration);.

Follow the complete method where I added my code:

function asyncRequest(element, options) {
    var confirm, loading, method, duration;

    confirm = element.getAttribute("data-ajax-confirm");
    if (confirm && !window.confirm(confirm)) {
        return;
    }

    loading = $(element.getAttribute("data-ajax-loading"));
    duration = parseInt(element.getAttribute("data-ajax-loading-duration"), 10) || 0;

    $.extend(options, {
        context: element,
        type: element.getAttribute("data-ajax-method") || undefined,
        url: element.getAttribute("data-ajax-url") || undefined,
        beforeSend: function (xhr) {
            var result;
            asyncOnBeforeSend(xhr, method);
            result = getFunction(element.getAttribute("data-ajax-begin"), ["xhr"]).apply(this, arguments);
            if (result !== false) {
                loading.show(duration);
                $("form[data-ajax=true] :submit").attr('disabled', 'disabled').addClass('disabled'); //adicionado para evitar novo clique após submit
            }
            return result;
        },
        complete: function () {
            loading.hide(duration);
            $("form[data-ajax=true] :submit").removeAttr('disabled').removeClass('disabled'); //adicionado para evitar clique após submit
            getFunction(element.getAttribute("data-ajax-complete"), ["xhr", "status"]).apply(this, arguments);
        },
        success: function (data, status, xhr) {
            asyncOnSuccess(element, data, xhr.getResponseHeader("Content-Type") || "text/html");
            getFunction(element.getAttribute("data-ajax-success"), ["data", "status", "xhr"]).apply(this, arguments);
        },
        error: getFunction(element.getAttribute("data-ajax-failure"), ["xhr", "status", "error"])
    });

    options.data.push({ name: "X-Requested-With", value: "XMLHttpRequest" });

    method = options.type.toUpperCase();
    if (!isMethodProxySafe(method)) {
        options.type = "POST";
        options.data.push({ name: "X-HTTP-Method-Override", value: method });
    }

    $.ajax(options);
}

The parts I included:

loading.show(duration);
$("form[data-ajax=true] :submit").attr('disabled', 'disabled').addClass('disabled');

and:

loading.hide(duration);
$("form[data-ajax=true] :submit").removeAttr('disabled').removeClass('disabled');

That adds and removes an attribute disabled="disabled" and a class as well disabled to the Ubmit button right after the loading element is displayed and hidden.

This works perfectly, the only problem is that as I am editing a code that microsoft keeps, if a new version of the file is published, I will lose my code. So my question is whether it is possible to create a similar effect, with some extension of that file, that could be written in a separate script in a separate file.

2 answers

1

Analyzing the code of jquery.unobstrusive-ajax.js, I was able to verify that there are some points that can be extended by placing attributes in the form generated by Ajax.BeginForm:

  • data-ajax-begin: this attribute can point to a global function, present in the window, or contain the javascript code directly, which will be executed before making the ajax request.

  • data-ajax-complete: this attribute can point to a global function, present in the window, or contain javascript code directly, which will be executed when ajax is completed.

That being said, you can create functions to be included in a javascript file like this:

function ajaxBegin()
{
    //adicionado para evitar novo clique após submit
    $("form[data-ajax=true] :submit").attr('disabled', 'disabled').addClass('disabled');
}

function ajaxComplete()
{
    //adicionado para evitar novo clique após submit
    $("form[data-ajax=true] :submit").attr('disabled', 'disabled').addClass('disabled');
}

And in this same javascript file, already use a method to change the forms generated by the method Ajax.BeginForm, which have the appropriate attribute data-ajax="true":

$(function () {
    $("form[data-ajax=true]")
        .attr("data-ajax-begin", "ajaxBegin")
        .attr("data-ajax-complete", "ajaxComplete");
}

Once this is done, you will need to include this javascript file in all pages that you want this behavior:

  • you could put this script at the top of the file jquery.unobtrusive-ajax.js from Microsoft (putting code on top is easier than editing something in the middle of the file)

  • you can put in the file _Layout.cshtml, if you have a layout file

Ai is at your discretion, the best way to include in all pages.

0

I would refer you to create a . js file for your website. No $(Document). ready(Function(){ ... }).

You can use this:

$(document).ajaxStart(function () {
       //Seu código quando a requisição inicia
    });
    $(document).ajaxStop(function () {
        //Seu código quando a requisição é finalizada
    });
  • This I would need to do on all my Forms, the file change I made works on all without changing any specific files. That’s the idea of unobtrusive.

  • You can carry this. js in your MVC Layout file, with that all pages that have this layout will have access to the functions of Document.ready(); See the edition I did in the reply, if you put your loading display code there, it can work.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.