5 Stimmen

Jquery automatisch laden gif und Schaltfläche deaktivieren auf Submit-Klick

Ist es möglich, das Ein-/Ausblenden eines Ajax-Lade-Gifs und das Deaktivieren/Aktivieren der Schaltfläche "Submit" gleichzeitig zu automatisieren? (wenn die Schaltfläche "Senden" ein gestyltes <a> ist und nicht ein input type=submit)

Derzeit mache ich beim Einreichen Folgendes:

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

Ich habe gesehen, ein paar Orte darüber reden, wie .ajaxStart() zu verwenden, um automatisch das Laden gif zeigen, aber ist es möglich, auch einen Verweis auf die Schaltfläche (ein gestyltes < a > Tag), die angeklickt wurde, und automatisch deaktivieren/aktivieren, dass als gut zu finden?

Damit soll vermieden werden, dass Start/EndAjax jedes Mal manuell eingegeben werden muss, und es soll sichergestellt werden, dass die App überall konsistent ist.

EDIT

Keine der bisherigen Antworten bietet eine Automatisierung - jede Lösung (wie meine derzeitige oben), bei der man manuell Start/Ende vor und nach jedem einzelnen $.ajax() eingeben muss, verursacht ein Wartungsproblem: Man vergisst leicht, den Start/Ende neben einigen $.ajax()-Aufrufen zu platzieren, und wenn man später ändern möchte, wie es funktioniert, muss man durch jeden einzelnen gehen, um die Änderung vorzunehmen.

EDIT 2 - um den Punkt bezüglich des .delegate()-Vorschlags zu klären

Sie sagten: "Sie können Ihren Event-Handler an cualquier Element" - aber ich möchte es an chaque Schaltflächenelement (DRY!): also habe ich den 1. Teil deines Vorschlags so geändert, dass er lautet

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

Dies löst das erste Problem, nämlich wie man das ladende .gif für jede beliebige Schaltfläche anzeigen kann, ohne immer wieder "$("#ajaxLoad").show()" eingeben zu müssen, wenn es einen $.ajax()-Aufruf gibt.

Der nächste Teil ist, wie jede Schaltfläche zu deaktivieren, wenn sie angeklickt wird (wieder ohne sich wiederholenden Code) - Sie vorgeschlagen .delegate(). Aber in Ihrem Beispiel wird bei jedem Klick auf eine Schaltfläche die Methode Save() aufgerufen. (Ich änderte den Selektor, um meine html anzupassen)

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

Das Problem dabei ist, dass $(this) nicht immer die Schaltfläche "Speichern" ist (der Selektor gibt ALLE Schaltflächen zurück), es könnte auch die Schaltfläche "Löschen" oder "Abbrechen" sein. Der Aufruf von $(this).toggleClass ist also in Ordnung, aber der Aufruf von Save() bedeutet, dass Sie die falsche Funktion aufrufen. Alle diese Schaltflächen haben bereits eine .click-Methode:

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

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

Dies ist also die ursprüngliche Klick-Funktion, die aufgerufen werden muss, wo es heißt $(this).something oben. An dieser Stelle sollte es den ursprünglichen Klick aufrufen - oder vielleicht ist es richtiger zu sagen, es sollte dann Blase bis zu den ursprünglichen .click. Die .delegate muss mehr generisch sein, und die ursprüngliche .click wird die spezifische Implementierung bereitstellen.

8voto

JK. Punkte 20597

Es stellte sich heraus, dass es eigentlich sehr einfach war: Ich habe dies in meine helper.js-Datei aufgenommen, die für jede Seite ausgeführt wird:

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

Wenn nun eine der Ajax-Schaltflächen auf einer beliebigen Seite angeklickt wird, werden die Schaltflächen deaktiviert und das Ajax-Lade-Gif wird angezeigt. Wenn der Ajax-Aufruf endet, werden sie in ihren normalen Zustand zurückversetzt. Und das alles ohne wiederholtes Eingeben von Code bei jedem Aufruf von .ajax().

2voto

Phil.Wheeler Punkte 16548

Sie können Ihren Event-Handler an jedes beliebige Element anhängen, also auch an Ihre Speicherschaltfläche:

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

Jetzt können Sie auf das Klick-Ereignis für jede Schaltfläche auf Ihrer Seite warten und die Ajax-Funktion von diesem Element aus aufrufen:

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

El $.delegate() lauscht auf Klick-Ereignisse für jedes Element, das nicht die .ui-state-disabled Klasse. Wenn ein Ereignis ausgelöst wird, wird die Klasse der Schaltfläche auf deaktiviert umgeschaltet, die Funktion Speichern aufgerufen und das Ereignis $.ajaxStart() ausgelöst. Dieses Ereignis zeigt Ihr animiertes Ajax-Gif an.

Ich bin davon ausgegangen, dass Ihre Schaltflächen für dieses Beispiel alle in einem div enthalten sind. Vielleicht möchten Sie den Code so ändern, dass $('div').delegate... gibt das enthaltende Element der Schaltflächen an. Ich bin auch davon ausgehen, dass Sie jQuery 1.4.2 verwenden.

Sie sollten in der Lage sein, die $.ajaxStop() Funktion, um alles wieder rückgängig zu machen.

0voto

Alec Punkte 8804
$("#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;
});

Bearbeiten: und diese in eine Funktion zu setzen:

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

Und dann rufen Sie diese Funktion auf:

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X