Set of checkboxes to act like radio buttons - javascript

I am able to create set of checkboxes and toggle between them like radio button. But When I click on a different set, the previous set checked option gets disabled. Can anyone guide where I am going wrong. Thank you.
//set1
<li class="dropdown-item">
<input type="checkbox" id="InchMm" data-id=0>
<label for="unit1">Inch</label>
</li>
<li class="dropdown-item">
<input type="checkbox" id="InchMm" data-id=1 checked>
<label for="unit2">Mm/label>
</li>
<hr/>
//set2
<li class="dropdown-item">
<input type="checkbox" id="Temp" data-id=2>
<label for="unit3">Fh</label>
</li>
<li class="dropdown-item">
<input type="checkbox" id="Temp" data-id=3 checked>
<label for="unit4">Cl</label>
</li>

Changed id for class, ids are unique, you can't have multiple elements with the same id so you can use class instead if you want to target multiple elements
ID
The id global attribute defines an identifier (ID) which must be unique in the whole document. Its purpose is to identify the element when linking (using a fragment identifier), scripting, or styling (with CSS).
<li class="dropdown-item">
<input type="checkbox" class="InchMm" data-id=0>
<label for="unit1">Inch</label>
</li>
<li class="dropdown-item">
<input type="checkbox" class="InchMm" data-id=1 checked>
<label for="unit2">Mm</label>
</li>
<hr/>
<li class="dropdown-item">
<input type="checkbox" class="Temperature" data-id=2>
<label for="unit3">Farenhiet</label>
</li>
<li class="dropdown-item">
<input type="checkbox" class="Temperature" data-id=3 checked>
<label for="unit4">Celsuis</label>
</li>
Now you can use separate onchange for each set of checkboxes
// Inch to Mm
$(".InchMm").change(function(){
$(".InchMm").prop('checked',false);
$(this).prop('checked',true);
});
//Farenhiet to celsius
$(".Temperature").change(function(){
$(".Temperature").prop('checked',false);
$(this).prop('checked',true);
});

Related

Get selected radio button on selected in function in jQuery

I have the following markup:
<div class="secondary-filter" onclick="searchByFilter()">
<ul class="secondary-filter__list">
<li class="secondary-filter__list-item">
<input type="radio" id="secondaryFilter-all" name="secondaryFilter" value="All">
<label for="secondaryFilter-all">All</label>
</li>
<li class="secondary-filter__list-item">
<input type="radio" id="secondaryFilter-marked" name="secondaryFilter" value="Marked">
<label for="secondaryFilter-quoted">Marked</label>
</li>
<li class="secondary-filter__list-item">
<input type="radio" id="secondaryFilter-pending" name="secondaryFilter" value="Pending">
<label for="secondaryFilter-unquoted">Pending</label>
</li>
</ul>
</div>
How can I obtained the label of the checked radio button in the following function?
function searchByFilter() {
var x = $("input[name='secondaryFilter']").find('input:checked');
console.log(x.val());
}
I'm trying this.. but it's not working. Please help.
Your $("input[name='secondaryFilter']") creates a jQuery object if <input> elements, but .find only searches through descendants - the input elements don't have any descendants, rather you want to get the matching <input> in the current collection.
You should also attach the event listener using Javascript rather than in an HTML attribute. By listening for change events, you'll have events that only fire when one of the inputs change, rather than when anywhere in the container is clicked.
Also, probably best to have the label next to each input have its for attribute match the id of the input - that way, when clicking the label, the input will be checked - eg, change
<input type="radio" id="secondaryFilter-marked" name="secondaryFilter" value="Marked">
<label for="secondaryFilter-quoted">Marked</label>
to
<input type="radio" id="secondaryFilter-marked" name="secondaryFilter" value="Marked">
<label for="secondaryFilter-marked">Marked</label>
^^^^^^
While you could use .filter instead, to find the element in the current jQuery object matching the condition:
$("input[name='secondaryFilter']").on('change', function() {
var x = $("input[name='secondaryFilter']").filter('input:checked');
console.log(x.val());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="secondary-filter">
<ul class="secondary-filter__list">
<li class="secondary-filter__list-item">
<input type="radio" id="secondaryFilter-all" name="secondaryFilter" value="All">
<label for="secondaryFilter-all">All</label>
</li>
<li class="secondary-filter__list-item">
<input type="radio" id="secondaryFilter-marked" name="secondaryFilter" value="Marked">
<label for="secondaryFilter-marked">Marked</label>
</li>
<li class="secondary-filter__list-item">
<input type="radio" id="secondaryFilter-pending" name="secondaryFilter" value="Pending">
<label for="secondaryFilter-pending">Pending</label>
</li>
</ul>
</div>
It would be easier to just put the :checked into the first selector string:
const checkedInput = $("input[name='secondaryFilter']:checked");
$("input[name='secondaryFilter']").on('change', function() {
var x = $("input[name='secondaryFilter']:checked");
console.log(x.val());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="secondary-filter">
<ul class="secondary-filter__list">
<li class="secondary-filter__list-item">
<input type="radio" id="secondaryFilter-all" name="secondaryFilter" value="All">
<label for="secondaryFilter-all">All</label>
</li>
<li class="secondary-filter__list-item">
<input type="radio" id="secondaryFilter-marked" name="secondaryFilter" value="Marked">
<label for="secondaryFilter-marked">Marked</label>
</li>
<li class="secondary-filter__list-item">
<input type="radio" id="secondaryFilter-pending" name="secondaryFilter" value="Pending">
<label for="secondaryFilter-pending">Pending</label>
</li>
</ul>
</div>
To make this work attach a change event handler directly to the radio elements. Then you can get $(this).val() from it when the event occurs. You can also use next().text() to get the value shown in the label, although given that the radio value and innerText of the label are the same, this seems a little redundant.
Also note that the for attributes of the label elements need to match the id of the targeted radio, so I've fixed the HTML there too.
$('.secondary-filter :radio').on('change', function() {
var $radio = $(this);
var $label = $radio.next();
console.log(`value: ${$radio.val()}, label: ${$label.text()}`);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="secondary-filter">
<ul class="secondary-filter__list">
<li class="secondary-filter__list-item">
<input type="radio" id="secondaryFilter-all" name="secondaryFilter" value="All">
<label for="secondaryFilter-all">All</label>
</li>
<li class="secondary-filter__list-item">
<input type="radio" id="secondaryFilter-marked" name="secondaryFilter" value="Marked">
<label for="secondaryFilter-marked">Marked</label>
</li>
<li class="secondary-filter__list-item">
<input type="radio" id="secondaryFilter-pending" name="secondaryFilter" value="Pending">
<label for="secondaryFilter-pending">Pending</label>
</li>
</ul>
</div>
Use
input[name='secondaryFilter']:checked" ,'.secondary-filter'
It will check for checked radio button inside the class of the div
function searchByFilter() {
var x = $("input[name='secondaryFilter']:checked" ,'.secondary-filter')
console.log(x.val())
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="secondary-filter" onclick="searchByFilter()">
<ul class="secondary-filter__list">
<li class="secondary-filter__list-item">
<input type="radio" id="secondaryFilter-all" name="secondaryFilter" value="All">
<label for="secondaryFilter-all">All</label>
</li>
<li class="secondary-filter__list-item">
<input type="radio" id="secondaryFilter-marked" name="secondaryFilter" value="Marked">
<label for="secondaryFilter-quoted">Marked</label>
</li>
<li class="secondary-filter__list-item">
<input type="radio" id="secondaryFilter-pending" name="secondaryFilter" value="Pending">
<label for="secondaryFilter-unquoted">Pending</label>
</li>
</ul>
</div>
var x = $('input[name=secondaryFilter]:checked').val()

jQuery manipulate DOM

this is my default HTML-Markup from the Wordpress-Plugin:
<ul class="gfield_checkbox" id="input_2_21">
<li class="gchoice_2_21_1">
<input name="input_21.1" type="checkbox" value="Option One" id="choice_2_21_1">
<label for="choice_2_21_1" id="label_2_21_1">Option One</label>
</li>
<li class="gchoice_2_21_2">
<input name="input_21.2" type="checkbox" value="Option Two" id="choice_2_21_2">
<label for="choice_2_21_2" id="label_2_21_2">Option Two</label>
</li>
</ul>
After the document is ready I want to change the HTML-Markup to this:
<ul class="gfield_checkbox" id="input_2_21">
<li class="gchoice_2_21_1 checkbox checkbox-styled">
<label for="choice_2_21_1" id="label_2_21_1">
<input name="input_21.1" type="checkbox" value="Option One" id="choice_2_21_1">
<span>Option One</span>
</label>
</li>
<li class="gchoice_2_21_2 checkbox checkbox-styled">
<label for="choice_2_21_2" id="label_2_21_2">
<input name="input_21.2" type="checkbox" value="Option Two" id="choice_2_21_2">
<span>Option Two</span>
</label>
</li>
</ul>
Thats what I actually did:
$('.gfield_checkbox > li').addClass('checkbox checkbox-styled');
But how do I change the other parts of the code?
To change the html, there is a few ways to do it. One way is to wrap the text inside with the span, and than select the sibling and add it inside of the label.
$("li")
.addClass("checkbox checkbox-styled")
.find("label")
.wrapInner("<span/>")
.each(function(){
label = $(this)
label.prepend(label.prev())
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="gfield_checkbox" id="input_2_21">
<li class="gchoice_2_21_1">
<input name="input_21.1" type="checkbox" value="Option One" id="choice_2_21_1">
<label for="choice_2_21_1" id="label_2_21_1">Option One</label>
</li>
<li class="gchoice_2_21_2">
<input name="input_21.2" type="checkbox" value="Option Two" id="choice_2_21_2">
<label for="choice_2_21_2" id="label_2_21_2">Option Two</label>
</li>
</ul>
Details are commented in demo.
Demo
/*
On each <li>...
- ...add class .checkbox and .checkbox-styled
- Find each <label> and <input> nested in each <li>
- Remove the text from the <label>...
- ...append the <input> to <label>...
- ...append a <span> to <label>...
- ...insert the value of <input> as the text of the <span>
*/
$('li').each(function(i) {
$(this).addClass('checkbox checkbox-styled');
var label = $(this).find('label');
var input = $(this).find('input');
label.text('').append(input).append(`<span>${input.val()}</span>`);
});
<ul class="gfield_checkbox" id="input_2_21">
<li class="gchoice_2_21_1">
<input name="input_21.1" type="checkbox" value="Option One" id="choice_2_21_1">
<label for="choice_2_21_1" id="label_2_21_1">Option One</label>
</li>
<li class="gchoice_2_21_2">
<input name="input_21.2" type="checkbox" value="Option Two" id="choice_2_21_2">
<label for="choice_2_21_2" id="label_2_21_2">Option Two</label>
</li>
</ul>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Hide an pre-rendered li label

I've rendered an Django form field with CheckboxSelectMultiple widget in my page, now, on page load, I want to hide all unchecked checkbox option. I manage to hide the checkbox but I don't know how to hide the label associated with the checkbox. my question is, how can I hide this label as well? below is my code :
model.py
class model_A(models.Model):
user = models.ManyToManyField(User, blank=True)
form.py :
class EditForm(forms.ModelForm):
prefix = 'edit_form'
class Meta:
model = model_A
fields = '__all__'
widgets = {'user':forms.CheckboxSelectMultiple}
html :
<div class="field">
{{form.user}}
</div>
javascript :
$('input[type=checkbox]:not(:checked)').hide();
On view page source in browser :
<ul id="id_settings-user">
<li><label for="id_settings-user_1"><input type="checkbox" name="settings-user" value="1" id="id_settings-user_1" style="display: none;">
Person A</label>
</li>
<li><label for="id_settings-user_2"><input type="checkbox" name="settings-user" value="2" id="id_settings-user_2" style="display: none;">
Person B</label>
</li>
<li><label for="id_settings-user_3"><input type="checkbox" name="settings-user" value="3" id="id_settings-user_3" style="display: none;">
Person C</label>
</li>
</ul>
You can use .parent()/.closest() to target label then hide.
$('input[type=checkbox]:not(:checked)').parent().hide();
$('input[type=checkbox]:not(:checked)').closest('label').hide();
$('input[type=checkbox]:not(:checked)').parent().hide();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="id_settings-user">
<li><label for="id_settings-user_1"><input type="checkbox" name="settings-user" value="1" id="id_settings-user_1" checked >
Person A</label>
</li>
<li><label for="id_settings-user_2"><input type="checkbox" name="settings-user" value="2" id="id_settings-user_2" >
Person B</label>
</li>
<li><label for="id_settings-user_3"><input type="checkbox" name="settings-user" value="3" id="id_settings-user_3">
Person C</label>
</li>
</ul>

Select child element from parent data attributes value

I have this kind of html blocks:
<div data-target="TargeID" data-action="toggle" data-trigger="Yes">
...
<ul>
<li>
<label class="radio">
<input id="cpMainContent_ctl24_rptAnswers_rbAnswer_0" type="radio" name="cpMainContent_ctl24" value="ctl00$cpMainContent$ctl24$rptAnswers$ctl01$rbAnswer">
Yes
</label>
</li>
<li>
<label class="radio">
<input id="cpMainContent_ctl24_rptAnswers_rbAnswer_1" type="radio" name="cpMainContent_ctl24" value="ctl00$cpMainContent$ctl24$rptAnswers$ctl02$rbAnswer">
No
</label>
</li>
<li>
<label class="radio">
<input id="cpMainContent_ctl24_rptAnswers_rbAnswer_2" type="radio" name="cpMainContent_ctl24" value="ctl00$cpMainContent$ctl24$rptAnswers$ctl03$rbAnswer">
maybe
</label>
</li>
</ul>
</div>
I need to select every input inside elements with data-action="toggle"
and Im using this jQuery selector: $('[data-action="toggleQuestions"] :input');
but I need to select those input which text value is equal to the parent data-trigger value.
Is it possible directly with a selector?
The logic is too complex to put in to a single selector. Instead you can use filter() to find the :input elements, then match the text() of their parent label to the data-trigger value on the container. Try this:
var $container = $('[data-action="toggle"]');
var $input = $container.find(':input').filter(function() {
return $(this).closest('label').text().trim() == $container.data('trigger');
})
$input.prop('checked', true);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div data-target="TargeID" data-action="toggle" data-trigger="Yes">
<ul>
<li>
<label class="radio">
<input id="cpMainContent_ctl24_rptAnswers_rbAnswer_0" type="radio" name="cpMainContent_ctl24" value="ctl00$cpMainContent$ctl24$rptAnswers$ctl01$rbAnswer">
Yes
</label>
</li>
<li>
<label class="radio">
<input id="cpMainContent_ctl24_rptAnswers_rbAnswer_1" type="radio" name="cpMainContent_ctl24" value="ctl00$cpMainContent$ctl24$rptAnswers$ctl02$rbAnswer">
No
</label>
</li>
<li>
<label class="radio">
<input id="cpMainContent_ctl24_rptAnswers_rbAnswer_2" type="radio" name="cpMainContent_ctl24" value="ctl00$cpMainContent$ctl24$rptAnswers$ctl03$rbAnswer">
maybe
</label>
</li>
</ul>
</div>
Use the below code
$('[data-action="toggle"]').each(function() {
var triggerValue = $(this).attr("data-trigger");
$(this).find('input[type=radio]').each(function() {
if ($(this).parent().text().trim() === triggerValue) {
$(this).prop("checked", true);
}
});
});

jQuery set value of nth-child input field?

I have the following html and I want to set the value of the second radio button in the list to be checked. I know I can do this using the id attribute but how can I do the same
by using the class selector as below and chaining the input field to be checked?
<ul class="myOptionList">
<li>
<input id="1" type="radio" value="1" name="options">
<label >one</label>
</li>
<li>
<input id="2" type="radio" value="2" name="options">
<label >two</label>
</li>
...
</ul>
$(".myOptionList li:nth-child(2)"); // how do i chain input field and set it as checked
Below code may help you.
HTML
<ul class="myOptionList">
<li>
<input id="1" type="radio" value="1" name="options">
<label >one</label>
</li>
<li>
<input id="2" type="radio" value="2" name="options">
<label >two</label>
</li>
jQuery
$(".myOptionList li:nth-child(2)").find('input:radio').prop('checked',true);
For versions of jQuery prior to 1.6, use:
$(".myOptionList li:nth-child(2)").find('input:radio').attr('checked', 'checked');
$(document).ready(function(){
$(".radio1 li:nth-child(4)").find('input:radio').prop('checked',true);
$(".radio2 li:nth-child(2)").find('input:radio').prop('checked',true);
$(".radio li:nth-child(1)").find('input:radio').prop('checked',true);
});
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
</head>
<body>
Fourth child selected:
<ul class="radio1">
<li>
<input id="1" type="radio" value="1" name="option1">
<label >one</label>
</li>
<li>
<input id="2" type="radio" value="2" name="option1">
<label >two</label>
</li>
<li>
<input id="3" type="radio" value="3" name="option1">
<label >three</label>
</li>
<li>
<input id="4" type="radio" value="4" name="option1">
<label >four</label>
</li>
</ul>
Second child selected:
<ul class="radio2">
<li>
<input id="1" type="radio" value="1" name="option2">
<label >one</label>
</li>
<li>
<input id="2" type="radio" value="2" name="option2">
<label >two</label>
</li>
<li>
<input id="3" type="radio" value="3" name="option2">
<label >three</label>
</li>
<li>
<input id="4" type="radio" value="4" name="option2">
<label >four</label>
</li>
</ul>
First child selected:
<ul class="radio">
<li>
<input id="1" type="radio" value="1" name="option">
<label >one</label>
</li>
<li>
<input id="2" type="radio" value="2" name="option">
<label >two</label>
</li>
</ul>
First child selected:(same class name)
<ul class="radio">
<li>
<input id="1" type="radio" value="1" name="option4">
<label >one</label>
</li>
<li>
<input id="2" type="radio" value="2" name="option4">
<label >two</label>
</li>
</ul>
</body>
</html>
Even the use of:
$(".myOptionList li:nth-child(2)").find('input:radio').prop('checked',true);
Works apparently, it is just for a case.
It set the checked on all the radio until the last one, that it is set just because it is the last.
A more meaning solution would be to use the .last() to go directly on the radio option you want to set:
$(function(){
// Set the last checked radio
$('.myOptionList li > input[name="options"]').last().prop('checked', true)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="myOptionList">
<li>
<input id="1" type="radio" value="1" checked name="options">
<label >one</label>
</li>
<li>
<input id="2" type="radio" value="2" name="options">
<label >two</label>
</li>
...
</ul>
To ensure it's working properly I set the first radio checked.
But I suggest to change your code in a way that you select the radio on the value attribute.
The benefit of this is that your code will be more clear and easy to understand and change, and more if the order of radios change it will still works.

Categories

Resources