How can I override Rails 3 unobtrusive javascript functions without modifying the supplied rails.js?
My Javascript isn't quite up to scratch and I'm struggling to override a function in the supplied rails.js
.
I want to modify the way that a[data-confirm]
are handled, usin开发者_Go百科g a jQuery UI modal dialogue rather than the vanilla javascript confirm()
.
The relevant function in rails.js
is allowAction(element)
. If I define this in another file, I can call it from the firebug console successfully, but the rails.js
version is still called from anchors with a data-confirm
attribute.
I think it's because the whole rails.js
file is wrapped in:
(function($) {
...
})( jQuery );
Is there a sensible way to override this function, without modifying the supplied rails.js
?
Edit:
The call in rails.js
to allowAction
is wrapped in a .live
call:
$('a[data-confirm], a[data-method], a[data-remote]').live('click.rails', function(e) {
var link = $(this);
if (!allowAction(link)) return false;
if (link.attr('data-remote')) {
handleRemote(link);
return false;
} else if (link.attr('data-method')) {
handleMethod(link);
return false;
}
});
I also tried including my javascript before and after the rails.js
, to no avail.
Edit:
So, if I call .die('click.rails')
I can then redefine the entire click.rails
event, but the original handleRemote()
and handleMethod()
functions are not called.
FYI, I just added an external API to the Rails jquery-ujs for exactly this sort of thing. You can now make rails.js use a custom confirm method by plugging into (and re-writing 1 line of) the $.rails.allowAction
function.
See my article, Rails jQuery UJS: Now Interactive, for a full explanation with examples.
EDIT: And now, as of this commit the confirm
dialog function can be overridden in the same way. E.g.
$.rails.confirm = function(message) { return myConfirmDialog(message); };
Like this?
//Backup our original function just in case
var backupFunc = allowAction;
//Your replacement function
var myFunc = function(element){
//Have it your way, badabababa :)
};
//Override default 'allowAction' function
allowAction = myFunc;
/*
Restore it the way it was before: allowAction = backupFunc;
*/
EDIT: The scope on the functions are in a closed scope. So you will be unable to act on them as you wish.
I just checked the rails.js
code (I'm using Rails 3.0.3 and jquery-rails 0.2.7), and the point where it calls the confirm()
method is different than yours. Mine look a lot easier to replace:
function allowAction(element) {
var message = element.data('confirm');
return !message || (fire(element, 'confirm') && confirm(message));
}
Maybe you can upgrade your jquery-rails
gem (and re-run rails generate jquery:install
)?
精彩评论