This question already has answers here:
jQuery click function only works on first element
(8 answers)
Closed 3 years ago.
I am writing an application where the user selects by toggling the switch button but the click event affects only the first element.
<label class="switch">
<input type="checkbox" id="block-instructors" class="block-instructors" value="FMmRXgApuo5AZe4zGqUl">
<span class="slider round"></span>
</label>
<label class="switch">
<input type="checkbox" id="block-instructors" class="block-instructors" value="J0jcK7eUvadzSNaaoG2h">
<span class="slider round"></span>
</label>
$("#block-instructors").on('change', function(e){
if ($(this).is(':checked')) {
$(this).attr('value');
alert($(this).val());
}
else {
$(this).attr('value', 'false');
alert($(this).val());
}
});
You can't have the same id for two elements on one page. Use this instead
$(".block-instructors").on('change', function(e) {
if ($(this).is(':checked')) {
$(this).attr('value');
alert($(this).val());
} else {
$(this).attr('value', 'false');
alert($(this).val());
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label class="switch">
<input type="checkbox" id="block-instructors" class="block-instructors" value="FMmRXgApuo5AZe4zGqUl">
<span class="slider round"></span>
</label>
<label class="switch">
<input type="checkbox" id="block-instructors" class="block-instructors" value="J0jcK7eUvadzSNaaoG2h">
<span class="slider round"></span>
</label>
Use class instead of id:
$(".block-instructors").on('change', function(e){
You should have the unique id for individual element or tag. When you are clicking it is referring to last one since the code executes line by line. Try this code instead.
$("#block-instructors1").on('change', function(e,value){
if ($(this).is(':checked')) {
$(this).attr('value');
alert($(this).val());
}
else {
$(this).attr('value', 'false');
alert($(this).val());
}
});
$("#block-instructors2").on('change', function(e,value){
if ($(this).is(':checked')) {
$(this).attr('value');
alert($(this).val());
}
else {
$(this).attr('value', 'false');
alert($(this).val());
}
});
To select the first element or any of the first nth element in jquery can be done easily by :nth-child() selector in jquery
For example for 2nd li in ul:
$("ul li:nth-child(2)")
Reference can be found here
Here you have defined multiple tags with same Id. Your jQuery function starts searching for the Id 'block-instructors' and returns you where it finds first in DOM. You must convert block-instructors from Id to class and then access it
Related
I search to open the modal #LoginModalStart, with a checkbox, but the page open this modal with every checkbox.
Can you help me ?
$('input[type="checkbox"]').on('change', function(e) {
if (e.target.checked) {
$("#LoginModalScreenplay").modal();
}
});
$('input[type="checkbox"]') targets every checkbox on your page. You probably want to target the specific checkbox. Something like this
<input type="checkbox" id="my-special-checkbox">
$('#my-special-checkbox').on('change', function(e) {
if (e.target.checked) {
$("#LoginModalScreenplay").modal();
}
});
You have to pass show to modal method:
$('#LoginModalScreenplay').modal('show')
You use this,
<input name="checkbox" type="checkbox" id="my-special-checkbox" value=1>
<input name="checkbox" type="checkbox" id="my-special-checkbox" value=2>
<input name="checkbox" type="checkbox" id="my-special-checkbox" value=3>
<script>
$(document).ready(function(){
$('input[name="checkbox"]').on('change', function(e) {
var x = $(this).val();
$("input:checkbox").prop('checked', false);
if(x==1){
$("input[value="+x+"]").prop('checked', true);
$("#LoginModalScreenplay").modal(); //or $("#LoginModalScreenplay").show();
}
});
});
</script>
So here is what I have for a toggle switch I'm using off of https://metroui.org.ua/inputs.html
What Im trying to do is change the label thats before the switch/checkbox to say checked or not checked. If I click on the label it changes the switch but the text does not change.
JavaScript:
$(document).ready(function() {
$('#front_set').click(function() {
if ($(this).is(':checked')) {
$(this).siblings('label').html('checked');
} else {
$(this).siblings('label').html(' not checked');
}
});
});
<label for="front_set">checked</label>
<label class="switch-original right">
<input type="checkbox" id="front_set">
<span class="check"></span>
</label>
The issue: The label is not a sibling of the clicked checkbox, so you won't find it using siblings. The label is actually a sibling of the label that is the parent of the checkbox.
The solution: Use a different selector to find the label, so their relative positions don't matter much anymore. Using label[for="xyz"] you can find exactly that label that is bound to checkbox xyz, regardless of its position in the document. This makes your code more flexible too, because it won't break immediately if you reorganize your DOM.
var $myLabel = $('label[for="' + this.id + '"]');
$myLabel.html( $(this).is(':checked') ? 'checked' : ' not checked');
$(document).ready(function() {
$('#front_set').click(function() {
var $myLabel = $('label[for="' + this.id + '"]');
$myLabel.html( $(this).is(':checked') ? 'checked' : ' not checked');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label for="front_set">checked</label>
<label class="switch-original right">
<input type="checkbox" id="front_set">
<span class="check"></span>
</label>
You need to change the parent().siblings('label'), not .siblings('label') because $(this) is the element you bind the click event to, which is $('#front_set') ( = your input) and that's a child of <label>, not a sibling of it. So you need to go up a level, using .parent():
$(document).ready(function() {
$('#front_set').click(function() {
if ($(this).is(':checked')) {
$(this).parent().siblings('label').html('checked');
} else {
$(this).parent().siblings('label').html(' not checked');
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label for="front_set">checked</label>
<label class="switch-original right">
<input type="checkbox" id="front_set">
<span class="check"></span>
</label>
What I don't understand is what is that <span class="check"></span> doing in your code? It does nothing and your code would do well without it.
Improved version:
You shouldn't bind events on click to checkboxes, but on change, as checkboxes can change their value without being clicked. So here is a better version of it, most likely to work on any device, in any browser:
$(document).on('ready', function() {
$.fn.extend({
setLabel: function() {
var label = $('[for="'+$(this).attr('id')+'"]').eq(0);
$(label).text(($(this).is(':checked') ? '' : 'not ') + 'checked');
}
});
$('#front_set').on('change', function(){
$(this).setLabel();
})
$('#front_set').setLabel();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label for="front_set">checked</label>
<label class="switch-original right">
<input type="checkbox" id="front_set">
</label>
This also registers the checking of the label as a jQuery function, enabling you to call it on any element using .setLabel(). In this version I used GolezTrol's solution for selecting the label, since it adds flexibility (the parent/child relation between input and label is no longer relevant).
I have the following code snippet. Why might the .is() not be working on wrapping only the checked checkboxes?
$("input:checkbox").on("change", function() {
$("input:checkbox").is(":checked").wrap("<span class='check-wrap-sapn'></div>");
});
.red {
background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="checkbox">
<input type="checkbox">
<input type="checkbox">
.is() returns a boolean so it is not chainable. You want .has()
Now the issue you have is if the user unchecks it, it still will be wrapped and if they check it again, you will have multiple wrapped elements. You probably should just wrap the element to start and toggle the class on the parent element.
$("input:checkbox").on("change", function() {
$(this).closest("label").toggleClass("checked", this.checked);
}).trigger("change");
label.checked {
background: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label>
<input type="checkbox">
</label>
<label>
<input type="checkbox">
</label>
<label>
<input type="checkbox">
</label>
Read the documentation of .is:
Check the current matched set of elements against a selector, element, or jQuery object and return true if at least one of these elements matches the given arguments.
So the return value of .is is a boolean. But you're trying to call a jQuery method on it.
Additionally, you're repeating your DOM query within the event handler, and so will act on all matching elements, not just the one that relates to the event.
And your wrapper starts out as a div but ends as a span. Might want to be consistent about that.
And I suspect check-wrap-sapn was meant to be check-wrap-span.
If I'm guessing correctly at your goal, then:
$("input:checkbox").on("change", function() {
var $this = $(this);
if ($this.is(":checked")) {
$this.wrap("<span class='check-wrap-span'></span>");
} else {
$this.unwrap();
}
});
Or:
$("input:checkbox").on("change", function() {
if (this.checked) {
$(this).wrap("<span class='check-wrap-span'></span>");
} else {
$(this).unwrap();
}
});
Live Example:
$("input:checkbox").on("change", function() {
if (this.checked) {
$(this).wrap("<span class='check-wrap-span'></span>");
} else {
$(this).unwrap();
}
});
.check-wrap-span {
border: 1px solid green;
}
<input type="checkbox">
<input type="checkbox">
<input type="checkbox">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
But this is something that would be much better handled with styling the CSS, via the :checked pseudo-class, provided the styling in question can be applied to checkboxes. If it can't, I'd advocate always having the wrapper span, but toggling a class on it:
Live Example:
$("input:checkbox").on("change", function() {
$(this.parentNode).toggleClass("check-wrap-span", this.checked);
});
.check-wrap-span {
border: 1px solid green;
}
<span><input type="checkbox"></span>
<span><input type="checkbox"></span>
<span><input type="checkbox"></span>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
Use $(this) inside the event handler to check if the checkbox is checked
is returns boolean result, use is() in if and if the checkbox is checked, then wrap it.
$("input:checkbox").on("change", function() {
var $this = $(this);
if ($this.is(":checked"))
$this.wrap("<span class='red'></div>");
});
.red {
background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="checkbox">
<input type="checkbox">
<input type="checkbox">
Basically, I want 8 radio buttons. And if one radio button is selected then a div is shown below. If another button is selected another div is shown. Only one div shown at a time and if no button selected (initially) then no divs shown.
This is my HTML which is fairly standard, I'm not trying to improve this for what I need.
<form id='group'>
<label><input type="radio" name="group1" class="sim-micro-btn"/></label>
<label><input type="radio" name="group1" class="sim-mini-btn"/></label>
<label><input type="radio" name="group1" class="sim-maxi-btn"/></label>
<label><input type="radio" name="group1" class="sim-mega-btn"/></label>
<label><input type="radio" name="group1" class="phone-smart-micro-btn"/></label>
<label><input type="radio" name="group1" class="phone-smart-mini-btn"/></label>
<label><input type="radio" name="group1" class="phone-smart-btn"/></label>
<label><input type="radio" name="group1" class="phone-smart-maxi-btn"/></label>
</form>
<div class="billpay-internet-add-ons">
<div class="sim-micro-desktop">sim-micro</div>
<div class="sim-mini-desktop">sim-mini</div>
<div class="sim-maxi-desktop">sim-maxi</div>
<div class="sim-mega-desktop">sim-mega</div>
<div class="phone-smart-micro-desktop">phone-smart-micro</div>
<div class="phone-smart-mini-desktop">phone-smart-mini</div>
<div class="phone-smart-desktop">phone-smart</div>
<div class="phone-smart-maxi-desktop">phone-smart-maxi</div>
</div>
However this is my script and it seems fairly hectic and I'm wondering before I move on is there a way to do this a bit more simple?
$(document).ready(function(){
$('.sim-micro-desktop').hide();
$('.sim-mini-desktop').hide();
$('.sim-maxi-desktop').hide();
$('.sim-mega-desktop').hide();
$('.phone-smart-micro-desktop').hide();
$('.phone-smart-mini-desktop').hide();
$('.phone-smart-desktop').hide();
$('.phone-smart-maxi-desktop').hide();
$('form#group').click(function(){
if($('.sim-micro-btn').is(":checked")){
$('.sim-micro-desktop').show();
} else {
$('.sim-micro-desktop').hide();
}
if($('.sim-mini-btn').is(":checked")){
$('.sim-mini-desktop').show();
} else {
$('.sim-mini-desktop').hide();
}
if($('.sim-maxi-btn').is(":checked")){
$('.sim-maxi-desktop').show();
} else {
$('.sim-maxi-desktop').hide();
}
if($('.sim-mega-btn').is(":checked")){
$('.sim-mega-desktop').show();
} else {
$('.sim-mega-desktop').hide();
}
if($('.phone-smart-micro-btn').is(":checked")){
$('.phone-smart-micro-desktop').show();
} else {
$('.phone-smart-micro-desktop').hide();
}
if($('.phone-smart-mini-btn').is(":checked")){
$('.phone-smart-mini-desktop').show();
} else {
$('.phone-smart-mini-desktop').hide();
}
if($('.phone-smart-btn').is(":checked")){
$('.phone-smart-desktop').show();
} else {
$('.phone-smart-desktop').hide();
}
if($('.phone-smart-maxi-btn').is(":checked")){
$('.phone-smart-maxi-desktop').show();
} else {
$('.phone-smart-maxi-desktop').hide();
}
});
});
Firstly put shared classes on both the radio buttons and the div elements which show the content. In my example I've used trigger and content respectively. Then add a data attribute to the radio to identify which div should be shown on click.
Shortened example:
<form id='group'>
<label>
<input type="radio" name="group1" class="sim-micro-btn trigger" data-rel="sim-micro-desktop" />
</label>
</form>
<div class="billpay-internet-add-ons">
<div class="sim-micro-desktop content">sim-micro</div>
</div>
Then you only need 1 click handler like this:
$(document).ready(function(){
$('.trigger').click(function() {
$('.content').hide();
$('.' + $(this).data('rel')).show();
});
});
You can also then use CSS to hide the div elements without jQuery - styling should always be done in CSS anyway as it's a much better separation of concerns.
.content {
display: none;
}
Example fiddle
You can hide the div elements using CSS:
.billpay-internet-add-ons div {
display: none;
}
Then you can use the className of the target to determine which div to show, hiding all sibling elements:
$('form#group').click(function(e) {
var className = e.target.className.replace('btn', 'desktop');
$('.' + className).show().siblings().hide();
});
Here's a fiddle
use html5 data attribute)(i.e data-mappingclass ) pointing to corresponding div you need to show. add same class to all radio button(ie radioClass).
HTML
<label><input type="radio" name="group1" class="radioClass sim-micro-btn" data-mappingclass="sim-micro-desktop"/></label>
<label><input type="radio" name="group1" class="radioClass sim-mini-btn" data-mappingclass="sim-mini-desktop"/></label>
... //same for others
JS
$('.radioClass').click(function() {
$('.billpay-internet-add-ons div').hide();
if(this.checked){
$('.' + $(this).data('mappingclass').show();
}
});
You could use selectors to reduce the number of lines of code here.
$('.sim-micro-desktop').hide();
$('.sim-mini-desktop').hide();
$('.sim-maxi-desktop').hide();
$('.sim-mega-desktop').hide();
$('.phone-smart-micro-desktop').hide();
$('.phone-smart-mini-desktop').hide();
$('.phone-smart-desktop').hide();
$('.phone-smart-maxi-desktop').hide();
Could be shortened to:
$('.billpay-internet-add-ons div').hide();
This uses the parent element to group those elements you want to hide, rather than repeating the request for each one.
Similarly, you can use your naming convention to map the items to the elements to show and hide - here is the full working example:
$(document).ready(function(){
$('.billpay-internet-add-ons div').hide();
$('form#group').click(function(){
$('#group input').each(function() {
var item = $(this);
var isChecked = item.is(':checked');
var name = item.attr('class').replace("-btn", "-desktop");
if (isChecked) {
$('.' + name).show();
} else {
$('.' + name).hide();
}
});
});
});
This example is purely based on your HTML without any changes. See it working here.
You could simplify this further if you didn't need to transform the names. You could use a data-attribute instead of changing the class names to do this.
var $billpay= $('.billpay-internet-add-ons');
$billpay.find("div").hide();
$("#group input:radio").click(function(){
$billpay.find("div").hide();
$billpay.find("div:eq("+$(this).parent().index()+")").show();
});
http://jsfiddle.net/KaF77/2/
I simplified it some four you. Basically you look which index the radio clicked has and then show a div with the same index. So the position of the divs has to match the radios.
Your HTML is the same as before.
Your CSS:
.billpay-internet-add-ons > div {
display:none;
}
All your Javascript:
$(document).ready(function(){
$('form#group').click(function(e)
{
$('.billpay-internet-add-ons > div').hide();
$('form#group input[type="radio"]').each(function(index)
{
if($(this).is(':checked'))
{
$('.billpay-internet-add-ons > div:eq(' + index + ')').show();
}
});
});
});
jsFiddle Demo: http://jsfiddle.net/cfSXY/
You can firstly have everything hidden by default (except one form maybe) using CSS, which gets rid of this:
$('.sim-micro-desktop').hide();
$('.sim-mini-desktop').hide();
$('.sim-maxi-desktop').hide();
$('.sim-mega-desktop').hide();
$('.phone-smart-micro-desktop').hide();
$('.phone-smart-mini-desktop').hide();
$('.phone-smart-desktop').hide();
$('.phone-smart-maxi-desktop').hide();
This has a negative implication for users without javascript, if you're worried - they'll never be able to see the other forms.
Next, only one radio can be checked, so just find out which one it is using:
$('input[name=group1]:checked);
But why would you do that, so you have the radios have a click handler more like:
$('#group input[type="radio"').click(function(){
//code to show/hide form
});
Now you have a choice as to how you link your radio buttons to the different forms one way could be to use the data attribute, so you define your radios like so:
<label><input type="radio" name="group1" class="phone-smart-maxi-btn" data-form="phone-smart-maxi-desktop"/></label>
Which you can access like so:
$('input[name=group1]:checked).data("form");
Now all you need to do is hide the div that was already showing, but that can be achieved with a similar use of the data attribute or by using the :visible selector.
I have made a check-box checkall/uncheckall.
HTML
<div> Using Check all function </div>
<div id="selectCheckBox">
<input type="checkbox" class="all" onchange="checkAll('selectCheckBox','all','check','true');" />Select All
<input type="checkbox" class="check" onchange="checkAll('selectCheckBox','all','check','false');" />Check Box 1
<input type="checkbox" class="check" onchange="checkAll('selectCheckBox','all','check','false');" />Check Box 2
<input type="checkbox" class="check" onchange="checkAll('selectCheckBox','all','check','false');" />Check Box 3
<input type="checkbox" class="check" onchange="checkAll('selectCheckBox','all','check','false');" />Check Box 4
</div>
main.js
function checkAll(parentId,allClass,checkboxClass,allChecked){
checkboxAll = $('#'+parentId+' .'+allClass);
otherCheckBox = $('#'+parentId+' .'+checkboxClass);
checkedCheckBox = otherCheckBox.filter($('input[type=checkbox]:checked'));
if(allChecked=='false'){
if(otherCheckBox.size()==checkedCheckBox.size()){
checkboxAll.attr('checked',true);
}else{
checkboxAll.attr('checked',false);
}
}else{
if(checkboxAll.attr('checked')){
otherCheckBox.attr('checked',true);
}else{
otherCheckBox.attr('checked',false);
}
}
}
It works fine. But get bulky when I have whole lot of checkboxes. I want to do same work by using jQuery rather than putting onchange on each checkbox. I tried different sort of things but couldnot work. I tried following one:
$('.check input[type="checkbox"]').change(function(e){
checkAll('selectCheckBox','all','check','true');
});
to do same work as onchange event but didnot work. Where do I went wrong.
I think you just need this: You do not need to pass all the arguments and have the inline onchange event attached to it. You can simplify your code.
$(function () {
$('input[type="checkbox"]').change(function (e) {
if(this.className == 'all')
{
$('.check').prop('checked', this.checked); //Toggle all checkboxes based on `.all` check box check status
}
else
{
$('.all').prop('checked', $('.check:checked').length == $('.check').length); // toggle all check box based on whether all others are checked or not.
}
});
});
Demo
Your selector is wrong:
.check input[type="checkbox"]
Above selects any input of type checkbox that has the ancestor with class .check. It'll match this:
<div class="check">
<input type="checkbox".../>
</div>
it should be:
input.check[type="checkbox"]
You closed the string here $('.check input[type='checkbox']') instead, you should use double quotes $('.check input[type="checkbox"]')