2010-05-20 5 views
5

Возможно ли автоматизировать отображение/скрытие гигабайта загрузки ajax и одновременное отключение/включение кнопки отправки? (Когда кнопка отправки является стиль < а> не тип ввода = представить)JQuery автоматической загрузки gif и кнопки disable on submit click

В настоящее время при подаче я делаю это:

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

Я видел несколько мест, говорить о том, как использовать .ajaxStart(), чтобы автоматически показывать загрузочный gif, но можно ли также найти ссылку на кнопку (в стиле < a>), которая была нажата, и автоматически отключить/включить это?

Дело в том, что каждый раз не нужно вручную вводить Start/EndAjax и следить за тем, чтобы приложение было согласованным везде.

EDIT

Ни один из ответов до сих пор предлагают автоматизации - любое решение (как мой текущий выше), где вы должны вручную ввести начало/конец до и после каждого $ .ajax() не вызывает проблемы технического обслуживания : Легко забыть поставить начало/конец рядом с некоторыми вызовами $ .ajax(), и если вы хотите изменить, как это работает, вам нужно пройти через все, чтобы внести изменения.

EDIT 2 - уточнить точку повторно в .delegate() предложение

Вы сказали: «Вы можете прикрепить обработчик события любой элемент» - но я хочу, чтобы прикрепить ее к каждый кнопки элемента (DRY): так я модифицировал первую часть вашего предложения, чтобы быть:

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

Это решает первую задачу, которая, как показывает загрузку .gif для любой кнопки, без необходимости повторно вводить " $ ("# ajaxLoad"). show() "везде есть вызов $ .ajax().

Следующая часть - как отключить любую кнопку при нажатии (опять же без повторного кода) - вы предложили .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 
}); 

Проблема с этим состоит в том, что $ (это) не всегда кнопка сохранения (селектор возвращает все кнопки), это может быть кнопка или удалить кнопку отмены или т. д. Таким образом, вызов $ (this) .toggleClass прекрасен, но вызов Save() означает, что вы вызываете неправильную функцию. Все эти кнопки уже есть .click метод:

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

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

Так это исходная функция клик, который должен быть вызван, где он говорит, что $ (это) .something выше. На этом этапе он должен вызывать оригинальный клик - или, возможно, правильнее сказать, что он должен затем перейти к исходному .click. Файл .delegate должен быть более общим, а оригинальный .click будет обеспечивать конкретную реализацию.

+0

Как ответ на ваше редактирование: вам нужно будет определить эти вещи в какой-то момент; это не ускользает. Одним из возможных решений было бы создать функцию перекрытия ajax самостоятельно, например 'doAjax (..., ...)', включая jQuery '$ .ajax' и действия кнопки. Но это действительно зависит от того, что (что-то другое) вы пытаетесь сделать здесь, о том, может ли эта перекрывающаяся функция оставаться простой или невероятно сложной и потерять все свои преимущества. – Alec

ответ

7

Это на самом деле оказался очень прост: я включил это в моем файле helper.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)); 
     }); 
    }); 
}); 

Теперь, когда любой из АЯКС-й кнопки щелкают на на любой странице, кнопки отключены и отображается gj-файл загрузки ajax. Когда вызов ajax заканчивается, они возвращаются в нормальное состояние. И все это делается с повторным набором кода каждый раз, когда вызывается .ajax().

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: и вкладывать их в функции:


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

И затем вызвать на эту функцию:

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

Вы можете прикрепить обработчик событий к любому элементу; поэтому для вашей кнопки сохранить:

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

Теперь вы можете прослушивать событие щелчка для каждой кнопки на странице и вызовите функцию АЯКС из этого элемента:

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

$.delegate() функция прослушивает нажмите события для каждого элемента, который не имеет класса .ui-state-disabled. Когда событие запущено, он переключит класс этой кнопки на запрет, вызовет функцию сохранения, и будет запущено событие $ .ajaxStart(). Это событие покажет ваш анимированный gj.

Я предположил, что все ваши кнопки содержатся в div для этого примера. Вы хотите изменить код так, чтобы на самом деле указывает содержащий элемент ваших кнопок. Я также предполагаю, что вы используете jQuery 1.4.2.

Вы должны использовать функцию $.ajaxStop(), чтобы вернуть все обратно.

+0

Это выглядит хорошо. Можно ли вызвать функцию первоначального щелчка кнопок, вместо жесткого кодирования Save()? потому что, конечно, только 1 кнопка вызывает Save(), другие кнопки вызывают Delete(), DoSomethingElse() и т. д. (и это да, чтобы использовать 1.4.2) –

+0

Можете ли вы предоставить больше объяснений? Откуда вы хотите вызвать событие нажатия кнопки? –

+0

Я имею в виду, что, когда у вас есть «Сохранить()» в примере вашего делегата, можно заменить его вызовом текущей функции щелчка выбранного объекта. например $ (this) .call_original_click_function(); - Я не знаю, какой синтаксис может быть. (btw, как я понимаю) .delegate() заменит текущий .click новым - это правильно) –