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

3

I'm using the extensions methods @Ajax.BeginForm() to save the data via AJAX. To prevent more than one click on the submit button, which could cause a double insert in my database, I decided to include a small snippet of code inside the jquery.unobtrusive-ajax.js file, which disables the submit button.

I include the code snippet just after the calls of the method that displays a loader, respectively loading.show(duration); and loading.hide(duration); .

Here is 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 excerpts that include:

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

e:

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

That adds and removes a disabled="disabled" attribute and a class also disabled to the submit button just after the loading element is displayed and hidden.

This works perfectly, the only problem is that since I am editing a code that Microsoft maintains, if a new version of the file is published, I will lose my code. So my question is about 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.

    
asked by anonymous 10.03.2014 / 20:19

2 answers

1

By analyzing the code of jquery.unobstrusive-ajax.js , I could check that there are some points that can be extended by putting attributes in the form generated by Ajax.BeginForm :

  • data-ajax-begin : This attribute can point to a global function, presents in 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, presents in window , or contain the javascript code directly, which will be executed when ajax completes.

That 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');
}

In this same javascript file, already use a method to change the form s generated by the Ajax.BeginForm method, which conveniently have the data-ajax="true" attribute:

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

Once you've done this, you'll need to include this javascript file on every page that you want this behavior to be:

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

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

There, it's up to you, the best way to include it on every page.

    
10.04.2014 / 01:29
0

I would direct you to create an .js file for your site. No $ (document) .ready (function () {...}); put your code snippet where you will have no problems if Microsoft updates its native file.

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
    });
    
10.03.2014 / 20:43