okno jQuery UI zamiast alert () dla atrybutu rails 3 Data-confirm
W Rails 3, podanie parametru: confirm do link_to wypełni atrybut data-confirm odnośnika. Spowoduje to wywołanie alertu JS () po kliknięciu łącza.
Używam adaptera rails jQuery UJS ( https://github.com/rails/jquery-ujs ). odpowiedni kod z rails.js to:
$('body').delegate('a[data-confirm], button[data-confirm], input[data-confirm]', 'click.rails', function () {
var el = $(this);
if (el.triggerAndReturn('confirm')) {
if (!confirm(el.attr('data-confirm'))) {
return false;
}
}
});
I
triggerAndReturn: function (name, data) {
var event = new $.Event(name);
this.trigger(event, data);
return event.result !== false;
}
Chciałbym wiedzieć, jak można to zmodyfikować, aby zamiast tego uzyskać okno dialogowe jQuery (np. okno dialogowe jQuery UI ) umożliwiające użytkownikowi potwierdzenie albo odwołaj.
Moja znajomość JavaScript nie jest wystarczająca, aby osiągnąć to elegancko. Moim obecnym podejściem byłoby po prostu przepisanie $('body').funkcja delegate () zamiast tego tworzy instancję lightbox. Wyobrażam sobie jednak, że istnieje bardziej skuteczne podejście niż to.
5 answers
Właśnie dodałem zewnętrzne API do Rails jquery-ujs dla dokładnie tego rodzaju personalizacji. Możesz teraz tworzyć szyny.js używa niestandardowego okna dialogowego potwierdzenia poprzez podłączenie (i ponowne zapisanie 1 linii) funkcji $.rails.allowAction
.
Zobacz mój artykuł, Rails jQuery UJS: Now Interactive , aby uzyskać pełne wyjaśnienie z przykładami.
EDIT: począwszy od tego zatwierdzenia , przeniosłem confirm
funkcję dialogową do obiektu $.rails
, aby można było go teraz jeszcze łatwiej modyfikować lub zamieniać. Np.
$.rails.confirm = function(message) { return myConfirmDialog(message); };
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-08 17:27:45
Jak wspomnieli inni, nie możesz użyć okna dialogowego jQuery, ponieważ $.rails.confirm
musi zostać zablokowane, dopóki nie zwróci odpowiedzi użytkowników.
Możesz jednak nadpisać $.rails.allowAction
w swoim pliku application.js
w następujący sposób:
$.rails.allowAction = function(element) {
var message = element.data('confirm'),
answer = false, callback;
if (!message) { return true; }
if ($.rails.fire(element, 'confirm')) {
myCustomConfirmBox(message, function() {
callback = $.rails.fire(element,
'confirm:complete', [answer]);
if(callback) {
var oldAllowAction = $.rails.allowAction;
$.rails.allowAction = function() { return true; };
element.trigger('click');
$.rails.allowAction = oldAllowAction;
}
});
}
return false;
}
function myCustomConfirmBox(message, callback) {
// implement your own confirm box here
// call callback() if the user says yes
}
Działa poprzez natychmiastowe zwrócenie false
, dzięki czemu skutecznie anuluje Zdarzenie kliknięcia. Jednak twoja niestandardowa funkcja może następnie wywołać oddzwanianie, aby faktycznie podążać za linkiem / przesłać formularz.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-24 12:04:50
Nie rozumiem, dlaczego musisz używać okna dialogowego jQuery, gdy funkcja JavaScript confirm() nadal będzie działać poprawnie. Zrobiłbym coś takiego:
$('a[data-confirm]').click(funciton() {
confirm($(this).data("confirm"));
});
Jeśli zamiast tego chcesz użyć okna dialogowego, jest to trochę inne. Możesz jednorazowo każde okno dialogowe, które chcesz, lub prawdopodobnie możesz przyjąć jednolitą aplikację podejścia, tak aby Twoje rails.js lub Twoje podanie.js może obsłużyć każdą instancję okna dialogowego. Na przykład, potrzebujesz czegoś takiego na swoim Strona:
<a class="dialogLauncher">The link that creates your dialog</a>
<div class="dialog" title="My confirmation title" style="display:none">
<p>My confirmation message</p>
</div>
Wtedy w Twoim js:
$('.dialogLauncher').click(function() {
var dialog = $(this).next('.dialog');
dialog.dialog();
})
Jeśli chcesz jeszcze bardziej dostosować swoje okno dialogowe, sprawdź ten przykład.
Edit
Teraz, gdy o tym myślę, byłaby to dobra okazja dla niestandardowego konstruktora formularzy. Możesz nadpisać jeden ze swoich tagów linków Rails do wyjściowego html, podobnego do tego, co jest wymienione powyżej, gdy występuje określony atrybut, np. :dialog => true
. Na pewno w ten sposób Railsy to zrobi. Możesz dodać inne opcje do Twój tag, jak tytuł okna dialogowego itp.
Edit
Jeszcze lepiej, zamiast :dialog => true
Użyj :confirm => "my confirm message"
tak jak normalnie, ale w nadpisaniu link_to użyjesz opcji :confirm
, aby utworzyć okno dialogowe html, którego potrzebuje jQuery, usunąć tę opcję, a następnie wywołać super
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-15 20:51:13
Tak to działa. Proszę sugerować wszelkie poprawki / ulepszenia
#W szynach.js
#// Added new variable
var deleteConfirmed = false;
// Changed function to use jquery dialog instead of confirm
$('body').delegate('a[data-confirm], button[data-confirm], input[data-confirm]', 'click.rails', function () {
var el = $(this);
/*
if (el.triggerAndReturn('confirm')) {
if (!confirm(el.attr('data-confirm'))) {
return false;
}
}
*/
if (el.triggerAndReturn('confirm')) {
if(deleteConfirmed) {
deleteConfirmed = false;
return true;
}
$( "#dialog-confirm" ).dialog("option", "buttons",
{
"Delete": function() {
$( this ).dialog( "close" );
deleteConfirmed = true;
el.trigger('click');
return true;
},
Cancel: function() {
$( this ).dialog( "close" );
return false;
}
}
);
$( "#dialog-confirm" ).dialog("open");
return false;
}
});
#
W aplikacji.js
#//Ensure confirm Dialog is pre-created
jQuery(function () {
$( "#dialog-confirm" ).dialog({
autoOpen: false,
resizable: false,
height:140,
modal: true
});
});
#
W układzie.html Alt możesz umieścić ten div w dowolnym miejscu w wygenerowanym html
# <div id='dialog-confirm' title='Confirm Delete'>
<p>
<span class='ui-icon-alert' style='float:left; margin:0 7px 20px 0;'>
This item will be permanently deleted. Are you sure?
</span>
</p>
</div>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-17 19:02:18
Najbardziej podobała mi się odpowiedź od @ Marc Schütz na temat nadpisywania $.rails.allowAction
wszystkiego, co znalazłem w Internecie - ale nie jestem wielkim fanem nadpisywania funkcji w allowAction
, ponieważ jest ona używana w całej bazie kodowej jQuery-ujs (co jeśli są skutki uboczne? Lub jeśli źródło tej metody ulegnie zmianie w przyszłej aktualizacji?).
Więc... Zwijałem własną metodę, o której myślę, że warto wspomnieć, ponieważ jest ona lżejsza od metody opisanej powyżej. Nie porywa allowAction
. Tutaj jest:
# Nuke the default confirmation dialog. Always return true
# since we don't want it blocking our custom modal.
$.rails.confirm = (message) -> true
# Hook into any data-confirm elements and pop a custom modal
$(document).on 'confirm', '[data-confirm]', ->
if !$(this).data('confirmed')
myCustomModal 'Are you sure?', $(this).data('confirm'), =>
$(this).data('confirmed', true)
$(this).trigger('click.rails')
false
else
true
# myCustomModal is a function that takes (title, message, confirmCallback)
Jak to działa? Cóż, jeśli spojrzysz na źródło , zauważysz, że metoda allowAction
zatrzyma się, jeśli confirm event
zwróci fałszywą wartość. Więc przepływ wynosi:
- użytkownik kliknie link lub przycisk z atrybutem
data-confirm
. Na linku lub przycisku nie madata-confirmed
, więc wpadamy w najpierw jeśli block, wyzwalamy nasz Niestandardowy modal i zwracamy false, zatrzymując w ten sposób kontynuację akcji w programie obsługi kliknięć ujs. - Użytkownik potwierdza w modalu niestandardowym, a callback jest wyzwalany. Zapisujemy stan elementu poprzez
data('confirmed', true)
i ponownie wywołujemy to samo zdarzenie, które zostało wywołane wcześniej (click.rails
). - tym razem
confirm event
spadnie doelse
bloku (ponieważdata('confirmed')
jest prawdziwe) i zwróci true, powodując, żeallowAction
blok zostanie oceniony na true.
I ' m oczywiście brakuje mi nawet innych sposobów, które mogą to jeszcze uprościć, ale myślę, że jest to naprawdę elastyczne podejście do uzyskania niestandardowego modalu potwierdzenia bez łamania rdzenia {15]} funkcjonalności.
(również, ponieważ używamy .on()
będzie to wiązać się z dowolnymi data-confirm
elementami na stronie w czasie ładowania lub w przyszłości, podobnie jak działa .delegate()
, w przypadku, gdy się zastanawiasz.)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-29 06:53:18