Jquery自动加载gif和按钮禁用提交点击。

时间:2021-06-28 20:31:52

Is it possible to automate the showing/hiding of a ajax loading gif, and the disabling/enabling of the submit button at the same time? (when the submit button is a styled < a > not a input type=submit)

是否有可能实现ajax加载gif的显示/隐藏,同时禁用/启用提交按钮?(当提交按钮是样式< a >而不是输入类型=submit)

Currently when submitting I do this:

现在提交我的时候:

$("#save_button_id").click(function () {
        if ($('#save_button_id').hasClass('ui-state-disabled')) return false;
        Save();
});

function Save() {
StartAjax($("#save_button_id"));
$.ajax({
        success: function (data) {
            EndAjax($("#save_button_id"));
            // etc...
        },
        error: function (xhr, status, error) {
            EndAjax($("#save_button_id"));
            // etc ...
        }
});
}

function StartAjax(button) {
    DisableButtonClick(button);
    $("#ajaxLoad").show();
}

function EndAjax(button) {
    EnableButtonClick(button);
    $("#ajaxLoad").hide();
}

I've seen a few places talk about how to use .ajaxStart() to automatically show the loading gif, but is it possible to also find a reference to the button (a styled < a > tag) that was clicked, and automatically disable/enable that as well?

我已经看到一些地方讨论了如何使用.ajaxStart()来自动显示加载的gif,但是是否也可以找到对所单击的按钮的引用(样式为< a >标记),并自动禁用/启用它?

The point of this is to not have to manually type in Start/EndAjax every time, and to make sure the app is consistent everywhere.

这样做的目的是,不必每次都手动输入Start/EndAjax,并确保应用程序在任何地方都是一致的。

EDIT

编辑

None of the answers so far offer automation - any solution (like my current one above) where you have to manually type start/end before and after every single $.ajax() causes a maintenance problem: Its easy to forget to place the start/end next to some $.ajax() calls, and if you want to change how it works later you need to go through every single one to make the change.

迄今为止没有一个答案提供自动化——任何解决方案(就像我现在的上面),您必须手动类型开始/结束之前和之后的每一个美元. ajax()会导致维护问题:容易忘记的地方旁边的开始/结束美元. ajax()调用,如果你想要改变它是如何工作的之后,你需要穿过每一个变化。

EDIT 2 - to clarify point re the .delegate() suggestion

编辑2 -澄清点re .delegate()建议

You said "You can attach your event handler to any element" - but I want to attach it to every button element (DRY!): so I've modified the 1st part of your suggestion to be:

您说过“您可以将事件处理程序附加到任何元素”——但我想将它附加到每个按钮元素(DRY!):所以我将您的建议的第一部分修改为:

$('div#buttons a.ui-icon').each(function(index) {
    $(this).ajaxStart(function() {
        $("#ajaxLoad").show();
    });
});

This solves the first problem, which is how to show the loading .gif for any button, without having to repetitively type "$("#ajaxLoad").show()" everywhere there is an $.ajax() call.

这解决了第一个问题,即如何为任何按钮显示load .gif,而不必重复输入“$("#ajaxLoad").show()”.“在任何地方都有$.ajax()调用。

The next part is how to disable any button when it is clicked (again with no repetitive code) - you suggested .delegate(). But in your example every button click will call the Save() method. (I changed the selector to match my html)

下一部分是如何在单击时禁用任何按钮(同样没有重复的代码)——您建议使用.delegate()。但是在您的示例中,每个按钮单击都会调用Save()方法。(我更改了选择器以匹配我的html)

$('div#buttons a.ui-icon').delegate('button:not(.ui-state-disabled)', 'click', function() {
   $(this).toggleClass('ui-state-disabled');
   Save();  // this line needs replacing with a call to $(this).something
});

The problem with this is that $(this) is not always the save button (the selector returns ALL the buttons), it might be the delete button or the cancel button or etc. So calling $(this).toggleClass is fine, but calling Save() means you are calling the wrong function. All these buttons already have a .click method:

这里的问题是$(this)并不总是save按钮(选择器返回所有的按钮),它可能是delete按钮或cancel按钮等等。切换类没问题,但是调用Save()意味着调用了错误的函数。所有这些按钮都有.click方法:

$("#SaveButton").click(function () {
    Save();
});

$("#DeleteButton").click(function () {
    Delete();
});

So this is the original click function that needs to be called where it says $(this).something above. At this point it should be calling the original click - or perhaps it is more correct to say it should then bubble up to the original .click. The .delegate must be more generic, and the original .click will provide the specific implementation.

这是原始的click函数,需要在它说$(this)的地方调用。上面的东西。此时,它应该调用原始的click——或者更正确的说法是,它应该冒泡到原来的。点击。委托必须更加通用,原始的.click将提供特定的实现。

3 个解决方案

#1


7  

It actually turned out to be very straightforward: I've included this in my helper.js file that is run for every page:

它实际上是非常简单的:我把它包含在我的助手中。每个页面运行的js文件:

$(document).ready(function () {
    $('div#buttons a.fm-button').each(function (index) {
        $(this).ajaxStart(function () {
            $("#ajaxLoad").show();
            DisableButtonClick($(this));
        });
        $(this).ajaxStop(function () {
            $("#ajaxLoad").hide();
            EnableButtonClick($(this));
        });
    });
});

Now whenever any of the ajax-y buttons are clicked on any page, the buttons are disabled and the ajax loading gif is shown. When the ajax call ends they are returned to their normal state. And all done with out repetitively typing code every time .ajax() is called.

现在每当在任何页面上单击任何ajax-y按钮时,就会禁用按钮,并显示ajax加载gif。当ajax调用结束时,它们将返回到正常状态。并且每次都使用重复的输入代码。

#2


2  

You can attach your event handler to any element; so for your save button:

可以将事件处理程序附加到任何元素;保存按钮:

$(this).ajaxStart(function() {
  $("#ajaxLoad").show();
});

Now, you can listen for the click event for each button on your page and call the ajax function from that element:

现在,您可以监听页面上每个按钮的单击事件,并从该元素调用ajax函数:

$('div').delegate('button:not(.ui-state-disabled)', 'click', function() {
   $(this).toggleClass('ui-state-disabled');
   Save();
});

The $.delegate() function listens to click events for each element that does not have the .ui-state-disabled class. When an event is fired, it will toggle the class of that button to disabled, call your Save function and the $.ajaxStart() event will fire. That event will show your animated ajax gif.

$.delegate()函数监听每个元素的单击事件,这些元素没有。ui-状态-禁用类。当触发事件时,它将切换该按钮的类以禁用,并调用Save函数,然后将触发$. ajaxstart()事件。该事件将显示您的动画ajax gif。

I have assumed that your buttons are all contained in a div for this example. You many want to modify the code so that $('div').delegate... actually specifies the containing element of your buttons. I am also assuming you're using jQuery 1.4.2.

我假设您的按钮都包含在这个示例的div中。您可能希望修改代码,以便$('div').delegate…实际上指定了按钮的包含元素。我还假设您使用的是jQuery 1.4.2。

You should be able to use the $.ajaxStop() function to revert everything back again.

您应该能够使用$. ajaxstop()函数再次还原所有内容。

#3


0  

$("#save_button_id").click(function () {
  if ($('#save_button_id').hasClass('ui-state-disabled')) {
    return false;
  } else {
    // add disabled class
    $('#save_button_id').addClass('ui-state-disabled');

    // optionally disable the button if it's an input button
    $('#save_button_id').attr('disabled','disabled');

    // show ajax loader
    $("#ajaxLoad").show();

    $.ajax({
      url: 'ajax/stuff.html',
      success: function(data) {
        // do stuff

        // re-enable button
        $('#save_button_id').removeClass('ui-state-disabled');

        // optionally re-enable the button if it's an input button
        $('#save_button_id').attr('disabled','');

        // hide ajax loader
        $("#ajaxLoad").hide();
      },
      error: function (xhr, status, error) {
        // do stuff

        // re-enable button
        $('#save_button_id').removeClass('ui-state-disabled');

        // optionally re-enable the button if it's an input button
        $('#save_button_id').attr('disabled','');

        // hide ajax loader
        $("#ajaxLoad").hide();
      });
  }

  // prevent default action, if any
  return false;
});

Edit: and to put those in a function:

编辑:并把它们放在一个函数中:


function processing(status) {
  if (status == 1) {
    // add disabled class
    $('#save_button_id').addClass('ui-state-disabled');

    // optionally disable the button if it's an input button
    $('#save_button_id').attr('disabled','disabled');

    // show ajax loader
    $("#ajaxLoad").show();
  } else {
    // re-enable button
    $('#save_button_id').removeClass('ui-state-disabled');

    // optionally re-enable the button if it's an input button
    $('#save_button_id').attr('disabled','');

    // hide ajax loader
    $("#ajaxLoad").hide();
  }
}

And then call on that function:

然后调用这个函数:

$("#save_button_id").click(function () {
  if ($('#save_button_id').hasClass('ui-state-disabled')) {
    return false;
  } else {
    processing(1);

    $.ajax({
      url: 'ajax/stuff.html',
      success: function(data) {
        // do stuff

        processing(0);
      },
      error: function (xhr, status, error) {
        // do stuff

        processing(0);
      });
  }

  // prevent default action, if any
  return false;
});

#1


7  

It actually turned out to be very straightforward: I've included this in my helper.js file that is run for every page:

它实际上是非常简单的:我把它包含在我的助手中。每个页面运行的js文件:

$(document).ready(function () {
    $('div#buttons a.fm-button').each(function (index) {
        $(this).ajaxStart(function () {
            $("#ajaxLoad").show();
            DisableButtonClick($(this));
        });
        $(this).ajaxStop(function () {
            $("#ajaxLoad").hide();
            EnableButtonClick($(this));
        });
    });
});

Now whenever any of the ajax-y buttons are clicked on any page, the buttons are disabled and the ajax loading gif is shown. When the ajax call ends they are returned to their normal state. And all done with out repetitively typing code every time .ajax() is called.

现在每当在任何页面上单击任何ajax-y按钮时,就会禁用按钮,并显示ajax加载gif。当ajax调用结束时,它们将返回到正常状态。并且每次都使用重复的输入代码。

#2


2  

You can attach your event handler to any element; so for your save button:

可以将事件处理程序附加到任何元素;保存按钮:

$(this).ajaxStart(function() {
  $("#ajaxLoad").show();
});

Now, you can listen for the click event for each button on your page and call the ajax function from that element:

现在,您可以监听页面上每个按钮的单击事件,并从该元素调用ajax函数:

$('div').delegate('button:not(.ui-state-disabled)', 'click', function() {
   $(this).toggleClass('ui-state-disabled');
   Save();
});

The $.delegate() function listens to click events for each element that does not have the .ui-state-disabled class. When an event is fired, it will toggle the class of that button to disabled, call your Save function and the $.ajaxStart() event will fire. That event will show your animated ajax gif.

$.delegate()函数监听每个元素的单击事件,这些元素没有。ui-状态-禁用类。当触发事件时,它将切换该按钮的类以禁用,并调用Save函数,然后将触发$. ajaxstart()事件。该事件将显示您的动画ajax gif。

I have assumed that your buttons are all contained in a div for this example. You many want to modify the code so that $('div').delegate... actually specifies the containing element of your buttons. I am also assuming you're using jQuery 1.4.2.

我假设您的按钮都包含在这个示例的div中。您可能希望修改代码,以便$('div').delegate…实际上指定了按钮的包含元素。我还假设您使用的是jQuery 1.4.2。

You should be able to use the $.ajaxStop() function to revert everything back again.

您应该能够使用$. ajaxstop()函数再次还原所有内容。

#3


0  

$("#save_button_id").click(function () {
  if ($('#save_button_id').hasClass('ui-state-disabled')) {
    return false;
  } else {
    // add disabled class
    $('#save_button_id').addClass('ui-state-disabled');

    // optionally disable the button if it's an input button
    $('#save_button_id').attr('disabled','disabled');

    // show ajax loader
    $("#ajaxLoad").show();

    $.ajax({
      url: 'ajax/stuff.html',
      success: function(data) {
        // do stuff

        // re-enable button
        $('#save_button_id').removeClass('ui-state-disabled');

        // optionally re-enable the button if it's an input button
        $('#save_button_id').attr('disabled','');

        // hide ajax loader
        $("#ajaxLoad").hide();
      },
      error: function (xhr, status, error) {
        // do stuff

        // re-enable button
        $('#save_button_id').removeClass('ui-state-disabled');

        // optionally re-enable the button if it's an input button
        $('#save_button_id').attr('disabled','');

        // hide ajax loader
        $("#ajaxLoad").hide();
      });
  }

  // prevent default action, if any
  return false;
});

Edit: and to put those in a function:

编辑:并把它们放在一个函数中:


function processing(status) {
  if (status == 1) {
    // add disabled class
    $('#save_button_id').addClass('ui-state-disabled');

    // optionally disable the button if it's an input button
    $('#save_button_id').attr('disabled','disabled');

    // show ajax loader
    $("#ajaxLoad").show();
  } else {
    // re-enable button
    $('#save_button_id').removeClass('ui-state-disabled');

    // optionally re-enable the button if it's an input button
    $('#save_button_id').attr('disabled','');

    // hide ajax loader
    $("#ajaxLoad").hide();
  }
}

And then call on that function:

然后调用这个函数:

$("#save_button_id").click(function () {
  if ($('#save_button_id').hasClass('ui-state-disabled')) {
    return false;
  } else {
    processing(1);

    $.ajax({
      url: 'ajax/stuff.html',
      success: function(data) {
        // do stuff

        processing(0);
      },
      error: function (xhr, status, error) {
        // do stuff

        processing(0);
      });
  }

  // prevent default action, if any
  return false;
});