How to test for onchange value? - javascript

This gives an error and breaks the function.
The error says "Cannot read property 'onchange' of undefined" even though I'm trying to test for onchange to prevent an error.
Here's my function:
function ClearAndRun(element) {
$el = $("select, input");
$next = $el.eq($el.index(element) + 1);
for(i=$el.index($next);i<$el.length;i++) {
if($next.get(0).onchange != null) {
$next.val("");
$next.change;
}
$next = $el.eq($el.index(element) + i);
}
}
<input onchange="ClearAndRun(this)">
I've tried a few different was of testing for an onchange value and they all seem to give that error. Thanks for your help!

Use $.each and .change doesn't call change, you need parentheses
$.each($element, function(){
if(this.onchange){
$(this).val("");
$(this).change();
}
});

I want to set the values to nothing
This will reset the value to nothing for each select/input
$element.each(function() {
if ($(this).val() != null) {
$(this).val("");
$(this).change();
}
});
...and run their onchange functions which are prepared for a nothing answer
this will be invoked because you have called .change() on one of those elements
$element.on('change', function() {
$('the_form').reset()
});
It sounds like when that .change() method is invoked for any element, you want to reset the form...
If these answers are reset and there onchange functions are run, it essentially resets the form...
(Example taken from here)
This is as far as I understand your question, I am unsure when you started talking of other child elements...
...this may hide or show spans based on their answers
But, this code will reset all values of input/select and call their .change() method. The problem with this, what I can see, is that for every element, you are resetting the form which will put additional strain on the DOM and is not ideal.
N.B: If you are not setting the value of these elements, you can use text() instead which will check the text inside the element
The HTML onchangeattribute only seems to be possible for select elements. From references I cannot see if this is possible with input's as well...
Execute a JavaScript when a user changes the selected option of a element:
(Credit w3schools)

So here's what I ended up needing:
function ClearAndRunFuncs(element) {
$el = $("input[name!=''][onchange!=''], select[name!=''][onchange!='']");
for(i=$el.index(element)+1;i<$el.length;i++) {
$el.eq(i).val("");
$el.eq(i).change();
}
}
I didn't realize you could put conditions based on attributes on the selector. So this prevents any errors because no fields that are missing onchanges, or even name values are being processed by this function.

Related

Chaining jquery functions - Beginner

I am trying to set the name and ID of an element when a radio button is clicked on. To avoid duplicating the selector, I attempted to set it up like this:
$( "#selectOther" ).click(function() {
$( "[field=primaryInput]" ).attr('id', "modifiedId", function() {
$(this).attr('name', "modifiedName");
if ($(this).attr('visible') == "False") {
$(this).slideDown('fast');
$(this).attr("visible", "True");
}
});
});
However, it isn't working. It seems that the ID is changed, but the Name is not, nor is the rest of the function executed. Could someone help me understand how to express this correctly?
Here's a JFiddle.
EDIT: In my final case I will have a couple of buttons that reveal the field if it is hidden, and others that will hide it if it is visible. That is why I am not using .slideToggle()
See this fiddle:
$('input[type="radio"]').click(function() {
$('input[data="primaryInput"]')
.prop('id', this.id)
.prop('name', this.name)
.val(this.value)
.css('display', 'inline-block');
});
Number of points:
You didn't set an external resource (namely jQuery) in your fiddle - so you wouldn't ever get jQuery functions to execute
Use the data attribute for custom attributes. You can access them the way I have done or by selecting the $(element).data('field')
This example might help you understand how chaining works. One other piece of advise is that chaining only works if the method invoked next receives the same element the previous method returns. If it ever changes, you can use end() to get the previous state.

Dynamically changing a checkbox doesn't trigger onChange?

Note: jQuery is not an option.
I want to detect a change in the state of a checkbox, but the onChange event doesn't seem to fire when I do this:
document.getElementById('myCheckBox').addEventListener('change',function() {
console.log('Changed!');
});
document.getElementById('someLink').onClick = function() {
// toggle checkbox
document.getElementById('myCheckBox').checked = !document.getElementById('myCheckBox').checked;
};
When I click #someLink the change event is not fired. I could add another listener to #myLink, but then if I add other links that check the same box I have to add more listeners. I want one listener for a checkbox change event. Again, jQuery is not an option, I need vanilla JS.
EDIT: Sorry if I did not make this more clear, but I want to avoid adding complexity to each link that will check this box. So ideally (and maybe the answer is that this is impossible) I don't want to have to alter the link/click logic at all. I want to be able to change the .checked property anywhere in the code and have it be detected without additional logic at each change (if possible).
UPDATE:
Okay so there is apparently no way to do this nicely without altering the onClick logic, so (like some kind of animal) I ended up brute forcing the problem as follows:
function mySentinel() {
if(document.getElementById('myCheckBox').checked) {
console.log("I've been checked!");
return;
}
setTimeout("mySentinel()",100);
}
// then call this somewhere in the on document load section...
mySentinel();
You can add some sort of timeout if you want also:
function mySentinel(var i) {
if(document.getElementById('myCheckBox').checked) {
console.log("I've been checked!");
return;
}
if(i <= 0) {
console.log("Time out. Still not checked");
}
i--;
setTimeout("mySentinel("+i+")",100);
}
// then call this somewhere in the on document load section...
// 60 second timeout (some math can make the argument look nicer)
mySentinel(600);
That is correct, changing the value or checked state of an input programatically does not fire the event handlers.
You'll have to trigger the event as well with javascript
document.getElementById('myCheckBox').addEventListener('change',function() {
console.log('Changed!');
});
document.getElementById('someLink').onclick = function() {
var box = document.getElementById('myCheckBox')
box.checked = !box.checked;
if ("createEvent" in document) {
var evt = document.createEvent("HTMLEvents");
evt.initEvent("change", false, true);
box.dispatchEvent(evt);
} else {
box.fireEvent("onchange");
}
};
and note that's it's onclick (all lowercase)
FIDDLE
EDIT
I want to avoid adding complexity to each link that will check this box.
So ideally ... I don't want to have to alter the link/click logic at all.
I want to be able to change the .checked property anywhere in the code and have it be detected without additional logic at each change (if possible).
And that's not really possible, without using horrible hacks with intervals etc.
When the checked state is changed programatically the event handler isn't triggered at all, because that would really be a huge issue in most cases, and much harder to work around the opposite scenario, where you just trigger the event handler manually instead, and that is really the only way to do it.
Of course, you can make it a lot more convenient using classes and external function and such
document.getElementById('myCheckBox').addEventListener('change',function() {
console.log('Changed!');
});
var links = document.querySelectorAll('.someLinkClass');
for (var i = links.length; i--;) {
links[i].addEventListener('click', triggerChange, false);
}
function triggerChange() {
var box = document.getElementById('myCheckBox')
box.checked = !box.checked;
if ("createEvent" in document) {
var evt = document.createEvent("HTMLEvents");
evt.initEvent("change", false, true);
box.dispatchEvent(evt);
} else {
box.fireEvent("onchange");
}
};
and anytime you add a link, you just add that class
Change the checkbox
Change the checkbox again
Change the checkbox even more
etc.
If you want to add more links that will trigger the checkbox, create a class name for them and use getElementByClass('classname')
Use onclick in your html, not js. Example: <div onclick="doSomething()"></div>
Just use an if/else statement for the check/uncheck:
if(document.getElementById('myCheck').checked){document.getElementById("myCheck").checked = false;} else{document.getElementById("myCheck").checked = true;}
I think jQuery have a change event. And you don't use it in the good way.
Read this page: http://api.jquery.com/change/
and this: jQuery checkbox change and click event
When any change occurs in the checkbox, jQuery event function is called. And then you can write anything in this event function
You can invoke/trigger an event but its not as easy as it seems, especially when you have to deal with internet explorer.
The cleanest solution is to put your event into its own function, then call it where you need it.
function handleEvent(){
console.log('Changed!');
}
documentent.getElementById('myCheckBox').addEventListener('change',function() {
handleEvent()
});
document.getElementById('someLink').onClick = function() {
// toggle checkbox
document.getElementById('myCheckBox').checked = !document.getElementById('myCheckBox').checked;
handleEvent();
};

checkbox running script onclick before actually setting the checked flag

I have a combobox with checkboxes. I am using jQuery to add a Click event to all of the checkboxes. When the checkbox is checked, a script is supposed to run and check an attribute of the checked box to determine it's type and then perform functions accordingly:
function () {
$('.RcbTag').find('input[type="checkbox"]').click(function () {
var evtCB = $(this);
var id = $(this).closest(".rcbSlide").siblings(".RcbTag").attr("id");
var rcbObject = $find(id);
rcbObject.get_items().forEach(
function (item, index) {
if (item.get_attributes().getAttribute('GUIDType') == 'group' &&
item.get_checked()) {
alert("Checked");
}
});
});
The problem right now is that it appears that the script is running before the checkbox is actually flipped to "checked". So in this example, it looks to see if the item attribute is 'group' and if it's checked. This always returns false, but will return true when I uncheck it. So I'm missing some order of events here. How do I fix this?
I think you're mixing jQuery click handlers and the Telerik code. Let's try and just stick with the Telerik-sanctioned events and I think everything will work like you're expecting.
On your RadComboBox, add an event handler declaritively like this:
OnClientItemChecked = "ComboBoxRowClick"
Then declare the JS function as you have it now (except we want to name it and not keep it anonymous):
function ComboBoxRowClick(sender, args) {
if (args.get_item().get_attributes().getAttribute('GUIDType') == 'group' &&
args.get_item().get_checked()) {
alert("Checked");
}
}
For more info on the client side functions from Telerik, you can check this link: http://www.telerik.com/help/aspnet-ajax/listboxitem-client-api.html
Also, you might run into this small annoyance where you have to click in the little checkbox itself, and not anywhere on the row (as one might expect). You can find a workaround for that one here: http://www.msigman.com/2010/07/telerik-radlistbox-fix/
try using change instead of click? that way you will catch changes made via keybord as well. and it will solve ypur problem.

Sequence of Events, alert is faster then removeAttr

i got following problem, i need to build a two checkboxes; where only one can be selected at a time, but onchange there will be a live calculation.
$('#calculator input, #calculator select').change(function() {
$('#calc_keller_true').click(function() {
$('#calc_keller_false').removeAttr('checked');
});
$('#calc_keller_false').click(function() {
$('#calc_keller_true').removeAttr('checked');
});
liveCalculate();
});
This is how it looks like, which is working but it seems to slow cause in my function liveCalculate i do this.
function liveCalculate() {
// Getting the value of the checked checkbox
var calc_keller = $('input[name=calc_keller]:checked').val();
alert(calc_keller);
}
So when i click on the false button the alert will trigger before my removeAttr and both Checkboxes will be 'checked' at the moment of the alert.
Anyone got a plan why exactly the liveCalculate function triggers faster then the removeAttr ?
Do i miss some basic knowledge in how the order works in javascript ?
Best Regards,
jay7
You only need to add click-handlers once. In your above example, you are adding them again and again, for every 'change' event you have on the select box.
Furthermore, you are not actually removing the attr on the change event, that happens during the click events. However, you fire liveCalculate after the change event.
Consider the following:
$('#calc_keller_true').click(function() {
$('#calc_keller_false').removeAttr('checked');
});
$('#calc_keller_false').click(function() {
$('#calc_keller_true').removeAttr('checked');
});
$('#calculator input, #calculator select').change(function() {
$('#calc_keller_false').removeAttr('checked');
$('#calc_keller_true').removeAttr('checked');
liveCalculate();
});
I'm not entirely sure if that accomplishes what you're expecting (simply because it isn't 100% clear to me what you do expect to happen).

W3.org validation stuck on one inline javascript attribute, how to fix it?

I have a website with the following code for a specific element:
<textarea id="textToTranslate" onfinishinput="dothis()" rows="5"></textarea>
onfinishinput waits for the user input and check if he is stopped. If he stop typing, the function dothis is called throught $('#waitUserInput').live() function.
The tricky part of my question is, how to change the above line to be completely jQuery.
The jQuery dat correspont to the dothis() function is the following:
// Detect if user input stops
$('#waitUserInput').live("keyup", function(e)
{
startTypingTimer($(e.target));
});
var typingTimeout;
function startTypingTimer(input_field)
{
if (typingTimeout != undefined)
clearTimeout(typingTimeout);
typingTimeout = setTimeout( function()
{
eval(input_field.attr("onfinishinput"));
}
, 250);
}
Javascript dothis() function:
function dothis(){
// Ajax call when called
{
Now, when I go to http://validator.w3.org, I have one error, and yes it is about the above code:
Attribute onfinishinput not allowed on element textarea at this point.
<textarea id="textToTranslate" onfinishinput="dothis()" rows="5"></textarea>
The question is, is it possible to turn the onfinishinput javascript attribute out of the textarea, but so that is is functioning the same?
I know it is a little complex, but I hope someone can help.
Why not just change:
eval(input_field.attr("onfinishinput"));
To:
dothis();
And then remove the 'onfinishinput' attribute from your textarea?
There is no such attribute called 'onfinishinput' for the TEXTAREA so the validator is correct. Including it does in fact violate the standard.
It appears that what you are trying to do is to be able to have a different handler for each TEXTAREA on a page so that you can take different actions. If that is the case, why not just have your jQuery call dothis() unconditionally and pass the control that fired the event as a parameter?
You could then put control-specific handling in your dothis() function based on the ID of the passed control.
How about binding the event differently and removing the attribute:
$('#textToTranslate').bind('onfinishinput', dothis');
You'd then need to trigger the event using jQuery's trigger (see http://api.jquery.com/bind/)

Categories

Resources