Example on JS FIddle.
The question is:
If the first click is on the radio button, it behaves normally; But if the first click is on span text (i.e. aaaa), it can not get the checked radio.
Please tell me why and how I can make it the same.
This code, which happens when the radio button is clicked:
var obj = $(e.target||e.srcElement).parent();
score = obj.find('input:checked').val();
Puts the parent in the obj variable, which is the containing DIV. This contains both of the radio buttons. It then finds the FIRST checked input element in that DIV, which is always the one with the 'first' value after it is checked.
You should just get the value of the item which was clicked:
score = $(e.target||e.srcElement).val();
This can be rewritten as
score = $(this).val();
Here's a working example: http://jsfiddle.net/RPSwD/10/
See new fiddle.
The problem is this line:
score = obj.find('input:checked').val();
Change it to:
score = $(this).val();
The reason for this is that you're looking for the selected item in the div but on the first click, the item has yet to become selected. Given that the event is targeted at the radio button, you can assume that radio is the selected one.
Note also that you don't need to use e.target||e.srcElement. jQuery takes care of this for you. Use $(this) instead.
Additionally, you need to set a name on the radio buttons to stop both from becoming selected. Alternatively, if having both selected is desired behaviour, use check boxes instead.
You don't need to use any of the event properties:
var score = $(this).val(); // in your '.x' click handler
$('.y').click(function(e) {
$(this).prev('.x').click();
});
just wrap your radio button inside label tag like this
<label for="radio1">
<input type=radio class="x" id="radio1" value="First"/>
<span class="y">aaaa</span>
</label>
No need for extra jquery or javascript
check the demo here
Related
Basically if I click on a checkbox, I want the name of the checkbox to be displayed on the console.
Here is the relevant javascript function and HTML.
javascript:
var list = [];
function test(){
var checkBoxes = document.querySelectorAll('input[type=checkbox]')
for(var i = 0; i < checkBoxes.length; i++) {
checkBoxes[i].addEventListener('change',function(){
if(this.checked){
console.log(this.value)
}
});
}
}
HTML:
<label><input type = "checkbox" onclick= "test()" name ="one" value ="one">test<br></label>
<label><input type = "checkbox" onclick= "test()" name ="two" value ="two" > test 1<br></label>
<label><input type = "checkbox" onclick= "test()" name ="three" value ="three" >test 2<br></label>
<label><input type = "checkbox" onclick= "test()" name ="four" value ="four" >test 3<br></label>
<label><input type = "checkbox" onclick= "test()" name ="five" value ="five" >test 4<br></label>
<label><input type = "checkbox" onclick= "test()" name ="six" value ="six" >Test 5<br></label>
If I click on the checkbox it is supposed to show in the console the name of the checked box.
However, something really strange happens and I don’t understand why it is. I have a vague inkling as to why it's happening but it's not quite clear.
When I click on the first check box for example. I click on the checkbox named "one".
The console displays: one (as required)
But if I click on the next check box (for example I clicked on the checkbox named "four").
In the console it displays:
four
four
And the next checkbox clicked (if it's the one named "five")
The console shows:
five
five
five
and so on....(incrementally repeating the checkbox name displayed on the console each time I click on another checkbox)
Why is it repeating ? When I click on the checkbox there should be technically one onclick event. How come it's counting all the other ones and repeating the console.log(this.value) bit?
Thanks in advance for any who may be able to give some idea as to why this is happening.
The problem is that you have inline click event handlers already set up and then when you click a checkbox, you programmatically set up a second one for the change event with .addEventListener(). So EVERY time you click a checkbox, you add yet another change event handler - - if a checkbox value gets changed, EACH AND EVERY handler associated with the change event will run. The more you click a checkbox, the more change events you set up.
Now, in order to change a checkbox, you need to click it. So, a future click will cause both the click and the change events to fire. Because of this way that change works with checkboxes and radio buttons, it's not usually used and instead click handlers typically do the job.
Inline event handlers should not be used, they are a 20+ year old technique that has many faults.
Also, you don't need to loop through the checkboxes in the handler. You'd use a loop to set up the handlers.
// Get all the checkboxes into an Array
var checkBoxes = Array.prototype.slice.call(document.querySelectorAll('input[type=checkbox]'));
// Loop over the array only to set up event handlers on them
checkBoxes.forEach(function(cb) {
// Set up an event handler
cb.addEventListener('change',function(){
// You don't need to loop again, just use the value of "this"
if(this.checked){
console.log(this.value);
}
});
});
<label><input type = "checkbox" name ="one" value ="one">test<br></label>
<label><input type = "checkbox" name ="two" value ="two" > test 1<br></label>
<label><input type = "checkbox" name ="three" value ="three" >test 2<br></label>
<label><input type = "checkbox" name ="four" value ="four" >test 3<br></label>
<label><input type = "checkbox" name ="five" value ="five" >test 4<br></label>
<label><input type = "checkbox" name ="six" value ="six" >Test 5<br></label>
The problem is that you keep adding event listeners to every checkbox whenever you click on one. This means that every time you click on a checkbox, more handlers are present that log to the console.
The sequence of events decoded:
Your page is loaded, nothing has been done so far.
Click on a check box => onclick is fired.
test() is invoked, an event listener for change is attached to each checkbox.
The onchange event fires and reaches the installed handler.
The event is logged to the console.
Click on another checkbox => onclick is fired.
test() is invoked, another event listener for changeis attached to each checkbox.
The onchange event fires and reaches the first instance of the installed handler.
The event is logged to the console.
The onchange event reaches the second instance of the handler.
The event is logged to the console again.
and so on...
If you want to keep track of everything, I'd suggest the following JS to eliminate this problem (this doesn't need the onclick attribute at all):
document.addEventListener('DOMContentLoaded', function (p_event) {
var l_checkboxes = document.querySelectorAll('input[type="checkbox"]');
var l_item;
for(l_item of l_checkboxes)
{
l_item.addEventListener('change', function (p_event) {
if(p_event.target.checked)
console.log(p_event.target.value);
}, false);
}
}, false);
You are getting all the checkboxes on the page with document.querySelectorAll. Then you are looping through the list of all checkboxes in a for loop.
You can get the ID of the element clicked with
var checkBox = event.target.id;
then just display the name with console.log(document.getElementById(checkBox).value)
I have this html part code :
<p><label>Taxe </label>
<select id="id_taxe" name="id_taxe" style="width: 100px;" onchange="taxselection(this);"></select>
<input id="taxe" name="taxe" class="fiche" width="150px" readonly="readonly" />%
</p>
Javascript method :
function taxselection(cat)
{
var tax = cat.value;
alert(tax);
$("#taxe").val(tax);
}
I'd like to set the value of taxe input to the selected value from the dropdownlist.It works fine only where the dropdownlist contains more than one element.
I try onselect instead of onchange but I get the same problem.
So How can I fix this issue when the list contains only one element?
This works:
$('#id_taxe').change(function(){
var thisVal = $(this).val();
var curVal = $('#taxe').val();
if(thisVal != curVal)
$('#taxe').val(thisVal);
$('#select option:selected').removeAttr('selected');
$(this).attr('selected','selected');
});
Use the change method which is very efficient for select boxes. Simply check the item selected isn't currently selected then if not, set the value of the input to the selected value. Lastly you want to remove any option's attr's that are "selected=selected" and set the current one to selected.
Just include this inside a $(document).ready() wrapper at the end of your HTML and the change event will be anchored to the select field.
Hope this helps.
http://jsbin.com/populo
Either always give an empty option, or in your code that outputs the select, check the amount of options, and set the input value straight away if there's only 1 option.
A select with just 1 option has no events, since the option will be selected by default, so there's no changes, and no events.
As DrunkWolf mentioned add an empty option always or you can try onblur or onclick event instead, depending on what you are actually trying to do.
Ok, just to stay close to your code, do it like this: http://jsfiddle.net/z2uao1un/1/
function taxselection(cat) {
var tax = cat.value;
alert(tax);
$("#taxe").val(tax);
}
taxselection(document.getElementById('id_taxe'));
This will call the function onload and get value of the element. You can additionally add an onchange eventhandler to the element. I highly recommend not doing that in the HTML! Good luck.
So basically what I'm trying to do as a measure of security (and a learning process) is to my own "Capthca" system. What happens is I have twenty "label's" (only one shown below for brevity), each with an ID between 1 and 20. My javascript randomly picks one of these ID's and makes that picture show up as the security code. Each label has its own value which corresponds to the text of the captcha image.
Also, I have the submit button initially disabled.
What I need help with is figuring out how to enable the submit button once someone types in the proper value that matches the value listed in the HTML label element.
I've posted the user input value and the ID's value and even when they match the javascript won't enable the submit button.
I feel like this is a really really simple addition/fix. Help would be much much appreciated!!!
HTML code
<div class="security">
<label class="captcha enabled" id="1" value="324n48nv"><img src="images/security/1.png"></label>
</div>
<div id="contact-div-captcha-input" class="contact-div" >
<input class="field" name="human" placeholder="Decrypt the image text here">
</div>
<input id="submit" type="submit" name="submit" value="Send the form" disabled>
Javascript code
//Picks random image
function pictureSelector() {
var number = (Math.round(Math.random() * 20));
//Prevents zero from being randomly selected which would return an error
if (number === 0) {
number = 1;
};
console.log(number);
//Set the ID variable to select which image gets enabled
pictureID = ("#" + number);
//If the siblings have a class of enabled, remove it
$(pictureID).siblings().removeClass("enabled");
//Add the disabled class to all of the sibling elements so that just the selected ID image is showing
$(pictureID).siblings().addClass("disabled");
//Remove the disabled class from the selected ID
$(pictureID).removeClass("disabled");
//Add the enabled class to the selected ID
$(pictureID).addClass("enabled");
};
//Calls the pictureSelector function
pictureSelector();
//Gets the value of the picture value
var pictureValue = $(pictureID).attr("value");
console.log(pictureValue);
//Gets the value of the security input box as the user presses the keys and stores it as the variable inputValue
$("#contact-div-captcha-input input").keyup(function(){
var inputValue = $("#contact-div-captcha-input input").val();
console.log(inputValue);
});
console.log($("#contact-div-captcha-input input").val());
//Checks to see if the two values match
function equalCheck() {
//If they match, remove the disabled attribute from the submit button
if ($(pictureValue) == $("#contact-div-captcha-input input").val()) {
$("#submit").removeAttr("disabled");
}
};
equalCheck();
UPDATE
Fiddle here
UPDATE #2
$("#contact-div-captcha-input input").keyup(function(){
var inputValue = $("#contact-div-captcha-input input").val();
console.log(inputValue);
if (pictureValue === inputValue) {
$("#inputsubmit").removeAttr("disabled");
}
});
So I got it working 99.9%, now the only problem is that if someone were to backspace or delete the correct value they have inputted, the submit button does not then change back to disabled. Any pointers?
Known issue.
Give your button a name OTHER THAN submit. That name interferes with the form's submit.
EDIT
A link was requested for this -- I don't have a link for pure JavaScript, but the jQuery docs do mention this issue:
http://api.jquery.com/submit/
Forms and their child elements should not use input names or ids that
conflict with properties of a form, such as submit, length, or method.
Name conflicts can cause confusing failures. For a complete list of
rules and to check your markup for these problems, see DOMLint.
EDIT 2
http://jsfiddle.net/m55asd0v/
You had the CSS and JavaScript sections reversed. That code never ran in JSFiddle.
You never re-called equalCheck. I added a call to your keyUp handler.
For some reason you wrapped pictureValue inside a jQuery object as $(pictureValue) which couldn't have possibly done what you wanted.
Basic debugging 101:
A console.log inside of your equalCheck would have shown you that function was only called once.
A console log checking the values you were comparing would have shown
that you had the wrong value.
Basic attention to the weird highlighting inside of JSFiddle would have shown you had the code sections in the wrong categories.
Following code is generated by a for loop.
<form action="saveresponse.php" method="POST" name="mainForm">
<input class="cbox_yes" type="checkbox" name="yes[]" value="01.jpg"
onclick="spenable()" /> OK
<input class="cbox_sp" type="checkbox" name="sp[]" value="01.jpg" disabled />Special<br />
<input class="cbox_yes" type="checkbox" name="yes[]" value="02.jpg"
onclick="spenable()" /> OK
<input class="cbox_sp" type="checkbox" name="sp[]" value="02.jpg" disabled />Special<br />
etc etc upto n times...
Now, what I want is that on page load, all the sp[] checkboxes should be disabled and enabled only if their corrosponding yes[] checkbox is checked by user.
Javascript code I am using: (Just to check if JS is capturing the states of yes[] checkbox?
function spenable(){
var yes = document.mainForm.yes[].value;
if (yes == true)
//alert("true");
document.mainForm.yes[].value = checked;
else
//alert("false");
document.mainForm.yes[].value = checked;
};
};
But I am not getting any alert (Neither Yes, Nor No).
So, is yes[] (Square brackets) in second line is incorrect? Or my if/else condition is wrong in JS?
P.S. All the questions here at SO or on Google deal with only one case/pair.
P.S. If required, I can change yes[] to yes1, yes2, yes3 etc and corresponding sp1, sp2, sp3 where 1,2,3 is $i of For loop, but then how will I capture/refer to it in JS?
_UPDATE:_
The flow/conditions are(Clarification):
Initially Special checkbox will be disabled and OK checkbox will be unchecked.
Then if user checks Ok, Special gets enabled.
If user want, he can tick Special.
If, later, user changes mind and untick the OK, Special should be unticked as well as disabled again.
I used jQuery here for the sake of simplicity.
$("input[name='yes[]']").change(function() { //When checkbox changes
var checked = $(this).attr("checked");
$(this).next().attr("disabled", !checked); //The next checkbox will enable
}); // or disable based on the
// checkbox before it
Demo: http://jsfiddle.net/DerekL/Zdf9d/
Pure JavaScript: http://jsfiddle.net/DerekL/Zdf9d/1/
Update
It will uncheck the first checkboxes when the Special checkbox is checked.
Pure JavaScript: http://jsfiddle.net/DerekL/Zdf9d/2/
More Updates
Here's the demo:
Pure JavaScript: http://jsfiddle.net/DerekL/Zdf9d/3/
jQuery: http://jsfiddle.net/DerekL/Zdf9d/4/
Little note: document.querySelectorAll works on all modern browsers and IE8+ including IE8. It is always better to use jQuery if you want to support IE6.
You can't use yes[] as an identifier in the Javascript, so you have to access the field using the name as a string:
document.mainForm["yes[]"]
This will not return a single element, it will return an array of elements. Use an index to access a specific element:
document.mainForm["yes[]"][0]
The value of the checkbox will always be the value property, regardless of whether the checkbox is selected or not. Use the checked property to find out if it's selected:
function spenable() {
var yes = document.mainForm["yes[]"][0].checked;
if (yes) {
alert("true");
} else {
alert("false");
};
}
To access the specific checkbox that was clicked, send the index of the checkbox in the event call:
<input class="cbox_yes" type="checkbox" name="yes[]" value="01.jpg" onclick="spenable(0);" /> OK
Use the index in the function:
function spenable(idx) {
var yes = document.mainForm["yes[]"][idx].checked;
var sp = document.mainForm["sp[]"][idx];
sp.disabled = !yes;
}
If you are open to using jQuery:
$('input[type="checkbox"]').click(function(){
var obj = $(this);
obj.next('.cbox_sp').attr({'disabled':(obj.is(':checked') ? false : 'disabled')});
});
This solution will assign an onclick event handler to all checkboxes and then check to see if the corresponding "special" checkbox should be disabled or not. It also sets the default checked state to true.
Working Example: http://jsfiddle.net/6YTqC/
UPDATE
If you try the form on this link http://jsfiddle.net/Matt_KP/BwmzQ/ the fiddle and select the top right £40 radio button then see the order total at the bottom it says £40. Then if you select the £75 the order total changes to £75 but then if you go back and check the £40 again the order total is £75 + £40 when it should just be £40 for the radio button that is checked.
UPDATE END
I have a section with Radio buttons where only certain radio buttons can be checked if others are selected. So say if a user selected one Radio Button but then selected another the first Radio Button would become unselected as they cannot have both selected.
Also I am using a custom attribute in the radio buttons called data-price which holds the value of each radio button that needs to be added toghther.
The problem is when a user selects a Radio Button the total shows fine but then if the user selects another radio button that can't have the previous one selected it adds the total onto the previous one where it should only add the Radio Buttons that are checked. It is kind of like caching the totals I think.
This is what I am using to total the checked Radio Buttons:
<script type="text/javascript">
jQuery(document).ready(function($){
$('input:radio').change(function(){
var total = 0.0;
$('input:radio:checked').each(function(){
total += parseFloat($(this).data('price'));
});
$('#total').val(total.toFixed(2));
});
})
</script>
I think the majority of your issues can be circumvented with some new HTML....
Your crazy jQuery code to limit the input is ridiculous.. you have name, value, and your data-price attributes... splitting each radio set up by item seems a little overkill to me..
Here is a limited example (as per our discussion in the chat).
http://jsfiddle.net/CZpnD/ <- here is the example you can work from..
the main things to look at are how I used the same radio name for each "block" of options, and how I loop through all options when a single option is changed to get the new total (not the most efficient but it works).
and for the love of pete use labels!
HTML is build to do this.
<form name="myform">
<input type="radio" name="foo" value="10" /> foo
<input type="radio" name="foo" value="30" /> bar
</form>
If you give radio buttons the same name then only one can be selected.
Further more when you get the radio element the .value property represents the value of the currently checked radio button
var myform = document.forms.myform;
var radio = myform.elements.foo;
var price = radio.value;
Note that radio is a RadioNodeList which is only returned by elements[name]
Example
However it turns out that browser support for RadioNodeList is appaling so you have to do it manually. Or use the RadioNodeList polyfill
for (var i = 0, len = radio.length; i < len; i++) {
var el = radio[i];
if (el.checked) {
var price = el.value;
break;
}
}