I have html content like:
<button class="submit">Save</button>
and view like:
var MyView = Backbone.View.extend({
events: {
'click .submit': 'save'
},
save: function() {}
}
When i'm clicking on this button, i see that backbone doens't handle this event, but instead standard browser actions are made (at least on Chrome). Same for <a> tag. I mean Backbone haven't bound to this tags.
Currently I've to use <span> for buttons, it works fine, but i'm wondering why I can't use standard tags for buttons? How I can remove standard browser events, and use backbone for <a> or <button>
The events are just 'listeners' - they are informed that the event happened. If you want to stop the event you must do
save: function(event) {
event.preventDefault();
event.stopPropagation();
}
To check that Backbone handles the event, check that your listener (save) is invoked when you click. Backbone does not stop the default behavior, you have to do it yourself in you event handling function.
Another advice: put your buttons inside a form and add an event listener for submit form. This will work also if the user submits the form using the keyboard (the click event is only for the mouse).
Related
What happens to the dom when you re-render a partial with js.erb? I can no longer get click events.
Based on this tutorial, I have followed it to re-render a js.erb partial which works fine. When I click the "cat.name" button (on linked page), and on that page is another button that I'm listening for click events but not working.
The run down:
On index page, click event works. When I make the request for from_category, no more click event. So what really happen?
Html:
<button id="test" value="ok">click</button>
JS:
$( "#test" ).on("click", function(e) {
console.log(e.target.value)
});
You click events don't bind to the new dom elements you should use event delegation to bubble the events to the newly created dom elements
$('body').on('click input keypress','.the_dynamic_element',function(){
});
No need to bind the event on body you can use this format to bind the event to the selector
$(document).on('click', '#test', function(e) {
console.log(e.target.value)
});
I want to translate this into backbone event model, avoiding using directly jquery.
$(".class").is(":hover")
What I have tried in my view is register an event (mouseenter, mouseleave), but seems that the events are being intercepted before by another component probably because it have stopPropagation or for an uncertain reason I don't receive it. I need to have something like this.
if($(".class").is(":hover")){
//execute this code.
}
What I tried to do is using event handlers to intercept the hover on a specific element change a flag, and change the condition to use that flag.
if(flag){
//execute this code.
}
You're looking for the mouseover javascript event.
If the event bubbling is stopped by stopPropagation, rethink using stopPropagation as it causes all sort of problems.
Here's a simple backbone view using the event.
var View = Backbone.View.extend({
events: {
"mouseover .specific-element": "onMouseOver"
},
onMouseOver: function(e) {
// do stuff
}
});
I have an <input> element that can either have the focus set via code, or as the result of a mouse click.
If the user clicks on the input, then the click event handler will fire - all well and good. If the element receives the focus via some other way (e.g. via code) then I want to manually trigger the click event so that the handler will also fire.
I could do this:
$elem = $('input');
$elem
.on('focus', function() { $(this).trigger('click') })
.on('click', function() { alert('Clicked!') });
However, this will result in click handler being fired twice; once for the click event and once for the focus event.
Is there any way to selectively trigger the click handler only if the focus was not received as the result of a click event?
UPDATE
This is a very simplified version of my problem, so I can't do things like bind both handlers to the focus event etc. I'm trying to merge two third-party pieces of code.
The .trigger() function adds a property isTrigger in the event object to identify that the event was triggered by its usage. Although, it is not documented the property is still present in jQuery 1.8.3 but it seems to only be used internally.
Anyways, you can make use of the extraParameters parameter to add a custom property to the event object. For instance,
$(this).trigger('click', {
isTrigger: true
});
It will keep the compatibility with isTrigger even if it is gone in a future release.
After doing some more research it appears that there is no way of guaranteeing which event will fire first: click or focus. (There doesn't seem to be a standard that dictates the order of events.)
This means that when the focus event fires there's no way to determine if a click event will or will not be triggered by the browser shortly afterwards.
I managed to solve the issue by using setTimeout() to run a test about 100ms after the focus event fired to check if the click event had fired. The third-party code that I was using (bound to the click event) added an extra class to the <input>, so I was able to check for that.
You can tap into the mousedown event which fires before the focus event. When you click a focusable object the order of events is as follows... mousedown, focus, mouseup, click.
You could set a flag in the mousedown event and then check for it in the focus event to see if the focus came from a mouse click. Obviously make sure to clear the flag in the focus event handler. Every application is different, but tapping into the mousedown event allows you to figure out a solution.
Here is a JSFiddle demonstrating the order of events... http://jsfiddle.net/ek7v7/
$elem = $('input');
$elem
.on('focus', function() { alert("Focused!") })
Focus can be fired by focusing the input by using tab, clicking it, or by using .focus()
Is there a reason for on('click', ...)?
I am using Rapheael to draw a control Dashboard. Right now I am adding a hyperlink object into the Dashboard editor. It is a text with the HREF attribute.
When I add the element and click on it, it opens the link. Is there some way to temporarly disable the link?
When I click the other elements, it opens the property dialog. I would like that also with the Hyperlink object.
I've tried adding return:false, but didn't help:
obj.dblclick(function (event) {
jQuery('##divProperties').dialog('open');
return false;
});
Returning false is a way to cancel events with more traditional event binding, e.g.
obj.onclick = function() { return false }
or
<a onclick="return false;"></a>
But it doesn't work with jQuery event bindings.
To do that, you need to call the .preventDefault() method on the event object, which is passed to the event handler:
obj.dblclick(function (event) {
jQuery('##divProperties').dialog('open');
event.preventDefault();
});
You may want to prevent default on the click event also if you're capturing double click so it doesn't get fired either.
I have an HTML button that needs to check several conditions, and if they pass allow the default action to occur.
The following works in Firefox, but it fails in IE. I setup a click handler on the button:
Ext.get('send').on('click', handleSend, this, {
preventDefault: true
});
which pops up one of several message boxes if one of the conditions isn't met. If all conditions are met, I remove the click listener from the button and click the button again:
Ext.get('send').un('click', handleSend, this);
Ext.getDom('send').click();
As far as I can tell, it fails in IE (and possibly other browsers) because click() isn't a standard function for a DOM element.
If the default action were a simple form submit, I could just do that after the checks pass, but we're using Tapestry 4 with a listener, which doesn't get executed on a normal form submit.
I've tried submitting the form with
tapestry.form.submit('composeForm', 'doSend');
but the doSend listener isn't getting called.
Conditionally allowing the default event is the best solution I've come up with, but there are a couple of options that may be possible:
Is there some other way to cause a Tapestry 4 listener to be fired from within Javascript?
Is there any way to recognize the normal form submit in my Tapestry Page and thereby trigger the listener?
JSFiddle added
In this jsfiddle, the default action is to submit the form; this is prevented when the checkbox is unchecked. When checked it removes the handler, but the call to click() doesn't work in IE.
Is there a way to simulate a click in IE?
Update
Another snag in the problem is that I have to display an 'are you sure' dialog, so in order to give them time to answer, the event has to be stopped. If they click OK, the default action needs to occur. JSFiddle doesn't seem to have ExtJS widgets like MessageBox, so I'm not sure how to demo this behavior.
At #Ivan's suggestion I tried
Ext.getDom('send').fireEvent('onclick');
but it returns false, meaning the event is being cancelled somewhere. I then tried
var evt = document.createEvent("Event");
evt.initEvent('click', false, false);
var cancelled = Ext.getDom('send').fireEvent('onclick', evt);
but IE9 says that document.createEvent doesn't exist, even though this is how MSDN says to do it.
If all conditions are met, I remove the click listener from the button
and click the button again:
Don't.
You should rather check the conditions in the click handler and call stopEvent there like so:
Ext.get('send').on('click', handleClick);
function handleClick(e) {
if (condition) {
e.stopEvent();
}
}
Internet explorer does not support click. You should use fireEvent method instead e.g.
Ext.getDom('send').fireEvent('onclick');
That should work for IE. For other browsers I guess click is ok. Anyway If I should do similar task I'll try to write an adapter for tapestry and use tapestry javascript library.
There's a listener parameter on Form components; from the Tapestry 4 doc:
Default listener to be invoked when the form is submitted. Invoked
only if another listener (success, cancel or refresh) is not invoked.
Setting this parameter to my listener method like so:
<binding name="listener" value="listener:doSend" />
causes a Tapestry form submit
tapestry.form.submit('myFormId');
to trigger the listener.