So this is slightly different than all the posts I have found on the subject. I have a button that gets loaded dynamically via Jquery, I save the selector of this button and later on in my code I need to send a click event (Emulate someone clicking on the button) Now normally I would just use $('#myID').click();
and this casts a click. But Since my button is loaded dynamically this does not work. Now I do NOT need to handle the onclick event. I could use
$(document).on('click', '#myId',function(e){});
for that. I need to actually send the click event. I have tried
.click();
.on('click);
.onClick();
.trigger('click');
Any ideas?
You could also breakout the code that you want to happen when you click on the button into a function if it's simple enough and instead of trying to fire a click event just fire the function the button normally fires.
By using setTimeout() to call the function again and again you are essentially polling the element, untill it actually exists, which is when you fire the click event.
// Wait for everything in the document to be loaded
jQuery(document).ready(function() {
// Make the initial call to the function
fire_click('#myID');
// This function tries to find the button, and if it can't
// find it, it calls itself again in 50 ms.
function fire_click(selector) {
elem = jQuery(selector);
if (elem.length == 0)
setTimeout(fire_click, 50);
else
elem.click();
}
});
A better solution would be to have a callback function that is fired when the button is loaded. This callback function can then fire the click event on the button, since the callback function is only called when the button is actually there. Generally it's a good idea to avoid polling for information when you can, so therefore this would be considered a better solution.
Related
I have a button.when click button, show a dialog to select data.
If click the button so fast,multi dialog will be show.
At present,I have two way to solve this problem
1.use disabled
2.use setTimeout and clearTimeout
have any other better way to solve this problem?
thank you very much
explain:
if use disabled,after dialog close,need to set the button available.
at present,I use this code
Util.prototype.lazyTriggerEvent = function(buttonId,event,callback){
var searchTrigger=null;
$("#"+buttonId).bind(event,function(){
var text = $.trim($(this).val());
clearTimeout(searchTrigger);
searchTrigger = setTimeout(function(){
callback(text);
},500);
})
};
//Util.lazyTriggerEvent("showDialgBtnId","click",function(){})
if click button trigger a ajax,and have much more button like this,is a best common way to solve this problem.
You can use jquery's .one() handler which limits a function to running once:
JQuery's .one() handler
Description: Attach a handler to an event for the elements. The
handler is executed at most once per element per event type.
$('button').one('click', function() {
// Do stuff
});
Or you can also disable the button on click:
$('button').click(function() {
$(this).prop('disabled', true);
// Do stuff
});
To re-enable the button, you can simply add the following to your close modal function:
$('button').prop('disabled', false);
I suppose when you want to show a dialogue, you execute a function called showDialogue() .
In your showDialogue(), you'll be able to check whether your dialogue was initiated.
Keep your mind off the button. Focus on the showDialogue().
If your dialogue was initiated, then do not execute the rest of your code in showDialogue(), as if showDialogue() isn't executed twice. It gives an illusion that the multi click isn't working. Is it the solution you desire, without disable and setTimeout?
Use disabled at first, and then when the dialog displays, enable the button.
I am trying to simulate an onclick event on a drop down.
I have an IE object that is going to a page and I need to change a dropdown which has an onchange event:
$('select[name="blah"]').val(3).trigger('change');
$('select[name="blah"]').change(function(){
alert('changed');
});
When I try this, I would expect the alert to fire as it's technically an onchange.
http://jsfiddle.net/3y5hmyf0/
Is there a way to acomplish this?
More Details
My tool is controlling another IE page through an object. It navigates to the page and finds the select drop down on the page. From there, if you did it manually it has an onchange event when making a selection.
I am trying to get jQuery to simulate as if it was being clicked by a person to it triggers that on change event.
I have tried .trigger and .change and couldnt get either of them to work.
The only reason your code does not work is the order you are executing it. You need to connect the handler before triggering it:
JSFiddle: http://jsfiddle.net/3y5hmyf0/1/
// Wire up event handler
$('select[name="blah"]').change(function(){
alert('changed');
});
// Now generate the event
$('select[name="blah"]').val(3).trigger('change');
Note: Your manual change trigger is still required as a change event must normally be triggered by user interaction. Setting the value is not enough.
$('select[name="blah"]').change(function(){
NotifyChanged();
});
function NotifyChanged() {
alert('changed');
}
If you want to test the logic in the changed function, just call it.
There are a couple of things that really trouble me with regards to how jQuery handles nested functions (not to the point that I can't sleep but it's getting there) and I wish a jQuery expert could explain how things work to bring me piece of mind.
Let's say you have the below HTML code:
<button id="first">click me first</button>
<button id="second">click me next</button>
And the following jQuery code:
$(document).ready(function() {
$('#first').click(function() {
$('#second').click(function() {
alert('test');
});
});
});
A dialog box will popup if you click the first button and then the second button.
I understand jQuery instantiates the $('#first').click() function when the DOM is ready and calls it when someone clicks on the first button.
However what I am puzzled with is the following:
[Q1] is the $('#second').click() function also instantiated on DOM ready or only when $('#one').click() is called?
Now, when you look at the jQuery code, there is nothing that "keeps us" in the $('#first').click() function, that is once the user clicks on the first button, the $('#second').click() function should be instantiated and we should exit the $('#one').click() function straight away. However after clicking the first button, jquery must somehow keep $('#second').click() indefinitely in memory in case the user clicks on the second button.
[Q2] how does jquery know to keep the $('#second').click() function in memory until the user clicks on the second button after clicking the first button?
Finally let's say you wanted to modify your code so that the user had to click the second button within 10 seconds of clicking the first button for the dialog box to appear:
[Q3] how would you implement this so that jQuery would know to stop listening for click events on the second button after 10 seconds?
Q1 - JS will simply load function definitions. It won't run it unless they are explicitly triggered/called. In this case, it will simply attach the event handler to #first and wait until someone clicks the button to fire the event. This will make the second function attach itself to the second button.
Q2 Again, it's not jQuery, it's JavaScript doing all the work. The method is simply attached to the DOM element and is triggered on the event it is attached to. JS is like any programming language and will keep all methods and variables in its memory.
The second click function isn't actually attached to the second button until after someone clicks on the first button. This is because, when the first button is clicked, JS knows to trigger the first method which does all the work of attaching the second method to the second button.
Q3 You could use setTimeout to unbind that method from the DOM element.
$(document).ready(function() {
$('#first').click(function() {
$('#second').click(function() {
alert('test');
setTimeout(function(){$('#second').unbind('click');}, 10000);
});
});
});
Note This unbinds all click event handlers from this DOM element. You can also unbind that particular method by passing it as a parameter. Check out the API docs for usage.
setTimeout : https://developer.mozilla.org/en/DOM/window.setTimeout
unbind : http://api.jquery.com/unbind/
[A1] The second function is only instantiated when #first is clicked as it is part of the execution of the first method. This also means that if you click #first n times you should get n alerts for every click on #second.
[A2] The function is rooted by the #second element. So long as that element is alive javascript knows to keep the function around.
[A3] You would need to save off the function pointer and do a setTimeout to clear it.
$(document).ready(function() {
$('#first').click(function() {
var secondFunction = function() {
alert('test');
};
$('#second').click(secondFunction);
setTimeout(function(){ $('#second').unbind('click', secondFunction); }, 10000);
});
});
A better implementation is probably something like:
$(document).ready(function() {
var enabled = false;
$('#first').click(function() {
enabled = true;
setTimeout(function(){ enabled = false; }, 10000);
});
$('#second').click(function() {
if(enabled) {
alert('test');
};
});
});
The answer to your first question: Yes, the second button will bind to click event only when a user clicks on the first button.
The second question: I'm not sure what you're asking.
The third one: Assuming the button one has nothing to do except bind the event to second button once clicked, you can set a timeout on document ready for 10 seconds. Now when the timer expires it must unbind the button one's click event hence blocking second button's event. I guess you understand now. e.g.
$(document).ready(function(){
setTimeout(removeEvent, 10000);
$('#first').click(function() {
$('#second').click(function() {
alert('test');
});
});
});
function removeEvent(){
$('#first').unbind('click');
}
I'm making an edit button which pops up a modal box with a form to edit it. jQuery then sends this form to my server and I get a JSON response back. However, due to my bubbling issue, if I click on, for example, all of the edit buttons and then click on the last one and change a field, it does it across all of them.
$('.edit').click(function(event){
//more code...
modal_submit(the_id);
event.stopPropagation();
});
and then the submit event:
function modal_submit(the_id){
$('#modal form').submit(function(){
//This will alert every time I have EVER clicked on an edit button
alert(the_id);
return false;
});
}
finally all of this is inside of a getScript:
$.getScript('js/edit.js',function(){
create_edit_btn();
});
I've only used this 1 other time, and it worked, but I also had to do this.event.stopPropagation, but if I do "this" now it says this.event is undefined, but like I said, this exact code worked before for another script I did.
Does anyone have any ideas? :\
EDIT:
the html is:
<li>
<input id="item1" type="checkbox" value="webhosting|15" title="Web Hosting">
<p>Hosting for your web site</p>
</li>
An event can have multiple event listeners. Each time you use $(element).submit(whateverFunction) you are adding another whateverFunction to the submit event. If you only want only the last listener to be the action that is taken upon envoking the event, try doing this:
function modal_submit(the_id){
$('#modal form').unbind(); // this will remove all other event listeners from this element
$('#modal form').submit(function(){
//This will alert every time I have EVER clicked on an edit button
alert(the_id);
return false;
});
I think you event.stoppropagation does its job already. It stopped all the bubbling on the click event of the button (ie, if you try checking the document body, it won't have mouse click event anymore). The reason why codes within submit of the form is still executed, is because this is called by the button's default action.
Together with event.stoppropagation(), I suggest you include this:
event.preventDefault();
So that the default action will not used and only the codes within your handler is executed.
Is this in the function that creates edit buttons?
$('.edit').click(function(event){
//more code...
modal_submit(the_id);
event.stopPropagation();
});
If it this, then it will add this handler multiple times to the same elements, causing a flurry of alerts. Use live, which will place the handler on every matched element, even if is is added later in execution.
So, you have a page:
<html><head>
<script type="text/javascript" src="jquery.1.3.2.js"></script>
<script type="text/javascript">
$(function() {
var onajax = function(e) { alert($(e.target).text()); };
var onclick = function(e) { $(e.target).load('foobar'); };
$('#a,#b').ajaxStart(onajax).click(onclick);
});
</script></head><body>
<div id="a">foo</div>
<div id="b">bar</div>
</body></html>
Would you expect one alert or two when you clicked on 'foo'? I would expect just one, but i get two. Why does one event have multiple targets? This sure seems to violate the principle of least surprise. Am i missing something? Is there a way to distinguish, via the event object which div the load() call was made upon? That would sure be helpful...
EDIT: to clarify, the click stuff is just for the demo. having a non-generic ajaxStart handler is my goal. i want div#a to do one thing when it is the subject of an ajax event and div#b to do something different. so, fundamentally, i want to be able to tell which div the load() was called upon when i catch an ajax event. i'm beginning to think it's not possible. perhaps i should take this up with jquery-dev...
Ok, i went ahead and looked at the jQuery ajax and event code. jQuery only ever triggers ajax events globally (without a target element):
jQuery.event.trigger("ajaxStart");
No other information goes along. :(
So, when the trigger method gets such call, it looks through jQuery.cache and finds all elements that have a handler bound for that event type and jQuery.event.trigger again, but this time with that element as the target.
So, it's exactly as it appears in the demo. When one actual ajax event occurs, jQuery triggers a non-bubbling event for every element to which a handler for that event is bound.
So, i suppose i have to lobby them to send more info along with that "ajaxStart" trigger when a load() call happens.
Update: Ariel committed support for this recently. It should be in jQuery 1.4 (or whatever they decide to call the next version).
when you set ajaxStart, it's going to go off for both divs. so when you set each div to react to the ajaxStart event, every time ajax starts, they will both go off...
you should do something separate for each click handler and something generic for your ajaxStart event...
Because you have a selector with two elements, you're creating two ajaxStart handlers. ajaxStart is a global event, so as soon as you fire any ajax event, the onajax function is going to be called twice. So yes, you'd get two popups.