2010-05-20 17 views
5

Ist es möglich, das Anzeigen/Verbergen eines Ajax-Lade-GIFs zu automatisieren, und gleichzeitig das Senden/Aktivieren des Senden-Buttons zu aktivieren? (Wenn die Submit-Button ist ein Stil < a> keine input type = abschicken)Jquery automatisches Laden Gif und Button deaktivieren beim Senden klicken

Zeit bei der Einreichung ich dies tun:

$("#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 ein paar Plätze gesehen habe darüber sprechen, wie .ajaxStart zu verwenden() um das Lade-GIF automatisch anzuzeigen, aber ist es auch möglich, einen Verweis auf die Schaltfläche (ein gestyltes <a> -Tag), auf das geklickt wurde, zu finden und diese auch automatisch zu aktivieren/deaktivieren?

Der Punkt ist, dass nicht jedes Mal Start/EndAjax manuell eingegeben werden muss, und um sicherzustellen, dass die App überall konsistent ist.

EDIT

Keine der Antworten bisher bieten Automatisierung - jede Lösung (wie mein aktuellen oben), wo Sie müssen manuell Start/Ende vor und nach jedem einzelnen $ Schnipsel() verursacht ein Wartungsproblem geben : Es ist leicht zu vergessen, den Start/das Ende neben einigen $ .ajax() -Aufrufen zu platzieren, und wenn Sie später ändern möchten, wie Sie es später machen, müssen Sie jeden einzelnen durchlaufen, um die Änderung vorzunehmen.

EDIT 2 - Punkt re der .delegate() Vorschlag zur Klärung

Sie sagten, „Sie können Ihre Ereignishandler jede Element anhängen“ - aber ich will es jeder Taste Element befestigen (DRY): so habe ich den ersten Teil Ihres Vorschlag geändert werden:

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

Dies löst das erste Problem, das ist, wie der Laden .gif für jede Taste zeigen, ohne wiederholt mit "eingeben $ ("# ajaxLoad"). show() "überall dort ist ein $ .ajax() Aufruf.

Der nächste Teil ist, wie man eine Schaltfläche deaktiviert, wenn es geklickt wird (wieder ohne sich wiederholenden Code) - Sie vorgeschlagen .delegate(). Aber in Ihrem Beispiel ruft jeder Knopfklick die Save() Methode auf. (Änderte ich die Wähler meine html übereinstimmen)

$('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 Taste save (der Wähler gibt alle Tasten), könnte es die Löschtaste oder die sein Cancel-Taste oder usw. Das Aufrufen von $ (this) .toggleClass ist in Ordnung, aber das Aufrufen von Save() bedeutet, dass Sie die falsche Funktion aufrufen. Alle diese Tasten haben bereits eine .click Methode:

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

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

Das 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 korrekter zu sagen, dass es dann zum ursprünglichen .click sprudeln sollte. Das .delegate muss generischer sein, und das ursprüngliche .click wird die spezifische Implementierung bereitstellen.

+0

Als Antwort auf Ihre Bearbeitung: Sie müssen diese Dinge an einem oder anderen Punkt definieren; da gibt es kein Entkommen. Eine mögliche Lösung wäre, eine überlappende Ajax-Funktion selbst zu erstellen, sagen wir 'doAjax (..., ...)', einschließlich jQuerys '$ .ajax' und den Tastenaktionen. Aber es hängt wirklich davon ab, was (verschiedene Dinge) du hier machen willst, ob diese überlappende Funktion einfach bleibt oder unglaublich komplex wird und alle ihre Vorteile verliert. – Alec

Antwort

7

Es stellte sich tatsächlich sehr einfach sein aus: Ich habe in meinem helper.js-Datei enthalten, 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)); 
     }); 
    }); 
}); 

Nun, wenn eine der Ajax-y-Tasten auf geklickt auf jeder Seite sind die Schaltflächen deaktiviert und das Ajax-Lade-GIF wird angezeigt. Wenn der Ajax-Ruf endet, kehren sie in ihren normalen Zustand zurück. Und das alles ohne wiederholtes Eingeben von Code jedes Mal, wenn .ajax() aufgerufen wird.

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: und diejenigen, die in 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 diese Funktion:

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

Sie können Ihre Event-Handler auf ein beliebiges Element befestigen; so für den Button speichern:

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

Jetzt können Sie für das Click-Ereignis für jede Taste auf Ihrer Seite hören und die Ajax-Funktion von diesem Element nennen:

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

Die $.delegate() Funktion hört klicken Ereignisse für jedes Element, das nicht die Klasse .ui-state-disabled aufweist. Wenn ein Ereignis ausgelöst wird, wird die Klasse dieser Schaltfläche deaktiviert, rufen Sie Ihre Save-Funktion auf und das Ereignis $ .ajaxStart() wird ausgelöst. Dieses Ereignis zeigt Ihr animiertes Ajax-GIF.

Ich habe angenommen, dass alle Ihre Tasten in einem div für dieses Beispiel enthalten sind. Sie möchten den Code so ändern, dass tatsächlich das enthaltende Element Ihrer Schaltflächen angibt. Ich nehme auch an, dass Sie jQuery 1.4.2 verwenden.

Sie sollten die Funktion $.ajaxStop() verwenden können, um alles wieder zurückzusetzen.

+0

Das sieht gut aus. Ist es möglich, die Tasten Original-Klick-Funktion anstelle von Hard-Codierung Save() zu nennen? weil natürlich nur 1 Taste ruft Save(), andere Tasten rufen Delete(), DoSomethingElse() usw. (und das ist ein Ja zur Verwendung von 1.4.2) –

+0

Können Sie mehr Erklärung zur Verfügung stellen? Von wo möchten Sie das Button Click Event aufrufen? –

+0

Ich meine, dass, wo Sie "Save()" in Ihrem Delegatbeispiel haben, es ist möglich, es durch einen Aufruf der aktuellen Klickfunktion des ausgewählten Objekts zu ersetzen. zB $ (this) .call_original_click_function(); - Ich weiß nicht, wie die Syntax sein könnte. (so wie ich es verstehe. .delegate() wird den aktuellen .click durch einen neuen ersetzen - ist das korrekt) –

Verwandte Themen