I have this little function :
$('.chrnumberpickerDiv select').change(function(){
var sel = $(this),
value = sel.closest('.chrnumberpickerDiv').find('.chrnumberpickerDivText');
value.text(sel.find(':selected').text());
}).one('change');
My problem is that I also need to trigger it on DOM load. I have tried .trigger('change') instead of .one('change') but it seems like it goes in a loop and never stops refreshing my page. So what could I be doing to trigger the event on DOM but without causing any damages to other events or whatever makes the function go in a loop ?
If I understood your question, you need to trigger a function when the select changes, as well as programmatically trigger it when the page loads to populate an initial value:
// define the handler
var changeHandler = function() {
var sel = $(this),
value = sel.closest('.chrnumberpickerDiv').find('.chrnumberpickerDivText');
value.text(sel.find(':selected').text());
};
// bind the handler
$('.chrnumberpickerDiv select').change(changeHandler);
$(document).ready(function () {
// execute the handler on page load
// use proxy to change what "this" means in the handler
// (jQuery does this for you when you bind a handler through jQuery)
$.proxy(changeHandler, $('.chrnumberpickerDiv select')[0]));
});
Documentation for proxy
Try this, instead of your code
$(document).ready(function() {
$('.chrnumberpickerDiv select').change(function(){
var sel = $(this),
value = sel.closest('.chrnumberpickerDiv').find('.chrnumberpickerDivText');
value.text(sel.find(':selected').text());
}).one('change');
});
you have be careful not to assign multiple change functions. Otherwise all of them are called when the change event happens.
Related
How do I programmatically force an onchange event on an input?
I've tried something like this:
var code = ele.getAttribute('onchange');
eval(code);
But my end goal is to fire any listener functions, and that doesn't seem to work. Neither does just updating the 'value' attribute.
Create an Event object and pass it to the dispatchEvent method of the element:
var element = document.getElementById('just_an_example');
var event = new Event('change');
element.dispatchEvent(event);
This will trigger event listeners regardless of whether they were registered by calling the addEventListener method or by setting the onchange property of the element.
By default, events created and dispatched like this don't propagate (bubble) up the DOM tree like events normally do.
If you want the event to bubble, you need to pass a second argument to the Event constructor:
var event = new Event('change', { bubbles: true });
Information about browser compability:
dispatchEvent()
Event()
In jQuery I mostly use:
$("#element").trigger("change");
ugh don't use eval for anything. Well, there are certain things, but they're extremely rare.
Rather, you would do this:
document.getElementById("test").onchange()
Look here for more options:
http://jehiah.cz/archive/firing-javascript-events-properly
For some reason ele.onchange() is throwing a "method not found" expception for me in IE on my page, so I ended up using this function from the link Kolten provided and calling fireEvent(ele, 'change'), which worked:
function fireEvent(element,event){
if (document.createEventObject){
// dispatch for IE
var evt = document.createEventObject();
return element.fireEvent('on'+event,evt)
}
else{
// dispatch for firefox + others
var evt = document.createEvent("HTMLEvents");
evt.initEvent(event, true, true ); // event type,bubbling,cancelable
return !element.dispatchEvent(evt);
}
}
I did however, create a test page that confirmed calling should onchange() work:
<input id="test1" name="test1" value="Hello" onchange="alert(this.value);"/>
<input type="button" onclick="document.getElementById('test1').onchange();" value="Say Hello"/>
Edit: The reason ele.onchange() didn't work was because I hadn't actually declared anything for the onchange event. But the fireEvent still works.
Taken from the bottom of QUnit
function triggerEvent( elem, type, event ) {
if ( $.browser.mozilla || $.browser.opera ) {
event = document.createEvent("MouseEvents");
event.initMouseEvent(type, true, true, elem.ownerDocument.defaultView,
0, 0, 0, 0, 0, false, false, false, false, 0, null);
elem.dispatchEvent( event );
} else if ( $.browser.msie ) {
elem.fireEvent("on"+type);
}
}
You can, of course, replace the $.browser stuff to your own browser detection methods to make it jQuery independent.
To use this function:
var event;
triggerEvent(ele, "change", event);
This will basically fire the real DOM event as if something had actually changed.
This is the most correct answer for IE and Chrome::
var element = document.getElementById('xxxx');
var evt = document.createEvent('HTMLEvents');
evt.initEvent('change', false, true);
element.dispatchEvent(evt);
If you add all your events with this snippet of code:
//put this somewhere in your JavaScript:
HTMLElement.prototype.addEvent = function(event, callback){
if(!this.events)this.events = {};
if(!this.events[event]){
this.events[event] = [];
var element = this;
this['on'+event] = function(e){
var events = element.events[event];
for(var i=0;i<events.length;i++){
events[i](e||event);
}
}
}
this.events[event].push(callback);
}
//use like this:
element.addEvent('change', function(e){...});
then you can just use element.on<EVENTNAME>() where <EVENTNAME> is the name of your event, and that will call all events with <EVENTNAME>
The change event in an input element is triggered directly only by the user. To trigger the change event programmatically we need to dispatch the change event.
The question is Where and How?
"Where" we want the change event to be triggered exactly at the moment after a bunch of codes is executed, and "How" is in the form of the following syntax:
const myInput = document.getElementById("myInputId");
function myFunc() {
//some codes
myInput.dispatchEvent(new Event("change"));
}
In this way, we created the change event programmatically by using the Event constructor and dispatched it by the dispatchEvent() method. So whenever myFunc() method is invoked, after the //some codes are executed, our synthetic change event is immediately triggered on the desired input element.
Important result: Here, the change event is triggered by executing the //some codes in myFunc() instead of changing the input value by the user (default mode).
if you're using jQuery you would have:
$('#elementId').change(function() { alert('Do Stuff'); });
or MS AJAX:
$addHandler($get('elementId'), 'change', function(){ alert('Do Stuff'); });
Or in the raw HTML of the element:
<input type="text" onchange="alert('Do Stuff');" id="myElement" />
After re-reading the question I think I miss-read what was to be done. I've never found a way to update a DOM element in a manner which will force a change event, what you're best doing is having a separate event handler method, like this:
$addHandler($get('elementId'), 'change', elementChanged);
function elementChanged(){
alert('Do Stuff!');
}
function editElement(){
var el = $get('elementId');
el.value = 'something new';
elementChanged();
}
Since you're already writing a JavaScript method which will do the changing it's only 1 additional line to call.
Or, if you are using the Microsoft AJAX framework you can access all the event handlers via:
$get('elementId')._events
It'd allow you to do some reflection-style workings to find the right event handler(s) to fire.
Using JQuery you can do the following:
// for the element which uses ID
$("#id").trigger("change");
// for the element which uses class name
$(".class_name").trigger("change");
For triggering any event in Javascript.
document.getElementById("yourid").addEventListener("change", function({
//your code here
})
Can anyone suggest where I'm going wrong here? news_active is a static div, everything else is loaded in via ajax calls, nothing is being triggered for the alert, pretty stumped?!
$('#news_active').load('ajax.php', function() {
// Delete news active
$('#news_delete').on('click', function() {
var vNid = $('#news_delete').attr('data-nid').val();
alert(vNid);
//$('#news_active').load('ajax.php?nid='+vNid);
});
});
The button looks like this, there are multiple buttons loaded in with different data-nid values:
<button id="news_delete" data-nid="1">Delete</button>
Since the news_delete is loaded dynamically, you need to use event delegation to register the event handler like:
// New way (jQuery 1.7+) - .on(events, selector, handler)
$('#news_active').on('click', '#news_delete', function(event) {
var vNid = $('#news_delete').data('nid');
alert(vNid);
});
Also, the way of getting the data-nid attribute value in your code is not correct.
Either use this:
var vNid = $('#news_delete').attr('data-nid'); // No need of .val() here
alert(vNid);
or just this using .data()
var vNid = $('#news_delete').data('nid');
alert(vNid);
You should use data() method instead:
var vNid = $('#news_delete').data('nid');
or just attr('data-nid') without val().
val() is trying to get Element.value property and you don't have it in button.
var vNid = $('#news_delete').attr('data-nid').val(); //remove the value it
// will return the value of button
change it to
var vNid = $('#news_delete').attr('data-nid');
I have an script that uses jquery, but i have a problem in the next part:
$("#botonAgregar").click(function() {
$.ajax({
type: "GET",
url: $(this).attr('href'),
success: function(html) {
$("#dialogDiv").html(html);
$("#dialogDiv").dialog('open');
}
});
alert();
$("a[type='submit']").click(function() {
var formName = $(this).attr("nombreform");
var formSelector = "form#" + formName;
$(formSelector).submit();
});
return false;
});
It works as it is, but if i remove the "alert();" line it doesnt add the click event to $("a[type='submit']") objects. What could be wrong?
it doesnt add the click event to $("a[type='submit']") objects
Yes it does. However, if more of those elements are being added during the AJAX call then you'll need to re-add the handler to those new elements after those are added to the DOM. Currently you're not doing that because the code after your call to .ajax() is happening before the AJAX call completes. This is because AJAX is, by definition, asynchronous. It's possible for the AJAX call to complete before later code is executed, but it is not guaranteed. (And in the case of code that's immediately after it, it's highly unlikely.)
Your success handler is called when the AJAX call completes, so that would be an opportune time to do this:
$("#dialogDiv").html(html);
$("#dialogDiv").dialog('open');
$("a[type='submit']").click(function() {
var formName = $(this).attr("nombreform");
var formSelector = "form#" + formName;
$(formSelector).submit();
});
However, there is a much better way to do this.
One of the problems with the approach you have is that you're going to re-add the handler to the same elements over and over. You're also adding the same handler to many elements, when you really only need one. Take a look at the jQuery .on() function. Essentially what it does is add a single handler to a common parent element of the target elements, and then filter the events based on the target element selector. So you only need to add the handler once:
$(function () {
$(document).on('click', 'a[type=submit]', function () {
var formName = $(this).attr('nombreform');
var formSelector = 'form#' + formName;
$(formSelector).submit();
});
});
In this case I'm using document as the common parent, though any other parent will work. (The body tag, a div which contains all of the target elements, etc. It just needs to be a common parent element which doesn't change throughout the life of the DOM.)
Basically I have a button Delete Selected, which is disabled as long as no checkboxes are selected. As soon as the user checks a checkbox, I'd like to bind a click event-handler to this button.
As it can happen that the user deselects the checkboxes and none is selected, I wanted to store the complete event-handler function in a variable and only bind it as soon as checkboxes are checked.
The question is: how can I store this event-handler function in a variable to most easily bind it to an object?
Till now I only used this to unbind an event-handler (that already existed on this object) and then bind it again, like this:
$(my-selector).unbind('click', eventHandler);
$(my-selector).bind('click', eventHandler);
...but never the other way round.
My suggestion is to go a different route: Bind the events and leave them bound for the complete lifecycle of the page. In the event handler, check for the state of the relevant objects and decide what to do with the event - this might include simply ignoring it.
There are two rationales behind that:
Keep it simple and debugable
I have seen delivery of an event delayed so long, that the state at the initiation of the event was no longer the same as on event delivery: i.e.: Your event is delivered, after you have unbound it (as it was initiated while still bound)
I'm not sure if I understand, but do you mean something like this?
// eventHandler function
var eventHandler = function(event) {
... // do something
}
// bind eventHandler function to jQuery collection
$(my-selector).bind('click', eventHandler);
$(my-selector).unbind('click', eventHandler);
var handlerFunc = function () {...}
$(my-selector).unbind('click', handlerFunc);
$(my-selector).bind('click', handlerFunc);
you can use a variable to store what checkboxes are selected, something like this:
var checkboxHandler = {}
checkboxHandler.activateButton = function(){...};
checkboxHandler.deactivateButton = function(){...};
checkboxHandler.checkboxes_checked = {};
checkboxHandler.number_of_checked_checkboxes = 0;
checkboxHandler.checkboxClicked = function(event){
if($(this).attr('checked')){
var id = $(this).attr('id');
if(checkboxHandler.checkboxes_checked[id]){
// uncheck
checkboxHandler.checkboxes_checked[id] = false;
checkboxHandler.number_of_checked_checkboxes--;
}else{
// checked
checkboxHandler.checkboxes_checked[id] = true;
checkboxHandler.number_of_checked_checkboxes++;
}
if(checkboxHandler.number_of_checked_checkboxes>0){
checkboxHandler.activateButton();
}else{
checkboxHandler.deactivateButton();
}
}
}
$('checkboxes').bind('click',checkboxHandler.checkboxClicked)
this way you only bind the checkboxes once and you don't have to bind/unbind them
I need my script to do something on the first time an element is clicked and continue to do something different on click 2,3,4 and so on
$('selector').click(function() {
//I would realy like this variable to be updated
var click = 0;
if (click === 0) {
do this
var click = 1;
} else {
do this
}
});//end click
really I think it should rely on the variables but I can't think of how to update the variable from here on out any help would be awesome.
Have a look at jQuery's .data() method. Consider your example:
$('selector').click(function() {
var $this = $(this),
clickNum = $this.data('clickNum');
if (!clickNum) clickNum = 1;
alert(clickNum);
$this.data('clickNum', ++clickNum);
});
See a working example here: http://jsfiddle.net/uaaft/
Use data to persist your state with the element.
In your click handler,
use
$(this).data('number_of_clicks')
to retrieve the value and
$(this).data('number_of_clicks',some_value)
to set it.
Note: $(this).data('number_of_clicks') will return false if it hasn't been set yet
Edit: fixed link
Another alternative might be to have two functions, and bind one using the one function in $(document).ready() (or wherever you are binding your handlers), and in that function, bind the second function to be run for all subsequent clicks using bind or click.
e.g.
function FirstTime(element) {
// do stuff the first time round here
$(element.target).click(AllOtherTimes);
}
function AllOtherTimes(element) {
// do stuff all subsequent times here
}
$(function() {
$('selector').one('click', FirstTime);
});
This is super easy in vanilla Js. This is using proper, different click handlers
const onNextTimes = function(e) {
// Do this after all but first click
};
node.addEventListener("click", function onFirstTime(e) {
node.addEventListener("click", onNextTimes);
}, {once : true});
Documentation, CanIUse
If you just need sequences of fixed behaviors, you can do this:
$('selector').toggle(function(){...}, function(){...}, function(){...},...);
Event handlers in the toggle method will be called orderly.
$('#foo').one('click', function() {
alert('This will be displayed only once.');
});
this would bind click event to Corresponding Html element once and unbind it automatically after first event rendering.
Or alternatively u could the following:
$("#foo").bind('click',function(){
// Some activity
$("#foo").unbind("click");
// bind it to some other event handler.
});