More efficient way to use document.getElementById for checkboxes? - javascript

This section of code uses jQuery to hide/show form fields. When they are hidden the values of those fields are set to empty. This is easy for an input field with its unique ID. I run into trouble with checkboxes. The code below works for three checkboxes. But I have to use this same technique for a set of 26 checkboxes. How can I do this more efficiently?
$(".transfer").click(function(){
if ($('input[name=transfer_position]:checked').val() == "yes" ) {
//Slide Down Effect
$(".transfer_details").slideDown("slow");
document.getElementById('transfer_interest').focus();
} else {
//Slide Up Effect
$(".transfer_details").slideUp("slow");
document.getElementById('transfer_interest').value = "";
document.getElementById('select_positions_0').checked = false;
document.getElementById('select_positions_1').checked = false;
document.getElementById('select_positions_2').checked = false;
}
});
<li>
<label>
<input type="radio" name="transfer_position" class="transfer" value="yes" id="transfer_position_0" />
Yes</label>
<label>
<input type="radio" name="transfer_position" class="transfer" value="no" id="transfer_position_1" />
No</label>
</li>
<li class="transfer_details">
<label for="transfer_interest">Why are you interested in transferring to your selected SL positions and what would you bring to that position(s) and team(s)?</label>
<textarea name="transfer_interest" id="transfer_interest" cols="80" rows="6"> </textarea>
</li>
<li class="transfer_details">
<label>
<input type="checkbox" name="select_positions[]" class="select_positons" value="Resident Advisor" id="select_positions_0" />
Resident Advisor</label>
<label>
<input type="checkbox" name="select_positions[]" class="select_positons" value="Programming Assistant" id="select_positions_1" />
Programming Assistant</label>
<label>
<input type="checkbox" name="select_positions[]" class="select_positons" value="Social Justice Advocate " id="select_positions_2" />
Social Justice Advocate </label>
</li>

Use classes, since many elements can share a class. So you simply uncheck all checkboxes with a certain class:
$('.select_positions').attr('checked', false);

Use the amazing power of jquery's selectors, of course!
$('li.transfer_details input[type=checkbox]').prop("checked", false);
descendant selector - http://api.jquery.com/descendant-selector/
setting the checked attribute -
http://api.jquery.com/prop/

One approach would be to use the child selector in conjunction with the checkbox selector, and iterating using the each function in jQuery to accomplish what you're looking for.
Keep in mind this is untested, so its probably going to raise errors and I trust you to fix that.
Beneath your slide up effect, you'd want something like the following:
$('.transfer_details > input:checkbox').each(function() {
(this).checked = false;
});
Hope this helps and happy coding!

Related

Jquery select from a collection of jquery objects which is checked

I haven't been able to find this answer. I don't know if I'm searching wrong or my lexicon is incorrect but I am trying to get the selected elements of a group of jquery radio buttons. Here is my JS code:
var hideFieldsBasedOnRadioButtonValue = function () {
var $employmentStatusRadioButtons = $(".edit-profile-employment-information input[name='user[profile_attributes][employment_status]']");
var displayOrHideRequiredFields = function ($radioButton) {
if ($radioButton.val() === "Full Time" || $radioButton.val() === "Part Time") {
$radioButton.closest("div.form-row").next(".required-input-when-yes").removeClass("d-none");
} else {
$radioButton.closest("div.form-row").next(".required-input-when-yes").addClass("d-none");
}
}
displayOrHideRequiredFields($(".edit-profile-employment-information input[name='user[profile_attributes][employment_status]']:checked"));
$employmentStatusRadioButtons.on("change", function () {
displayOrHideRequiredFields($(this));
});
}
This is a stripped down version of this function. I have a few more radio buttons that need to either hide or display additional fields depending on the radio button's value. What I'm having trouble with specifically is I want to trim this line down:
displayOrHideRequiredFields($(".edit-profile-employment-information input[name='user[profile_attributes][employment_status]']:checked"));
the $employmentStatusRadioButtons are a collection of jquery objects and I'm unable to figure out how to grab the selected one. Any help would be amazing.
Instead of using the same ".edit-profile-employment-information input[name='user[profile_attributes][employment_status]']" selector on this line and on line 2 of the code I want to do something like
displayOrHideRequiredFields($employmentStatusRadioButtons:checked);
Now that won't work. The closest I've been able to get this to work is by doing the following;
displayOrHideRequiredFields($employmentStatusRadioButtons.selector + ":checked")
But I don't really like how that looks. We aren't using ES6 or else it would be awesome.
I haven't been able to find anything to help me in this regard. Does anyone know any methods specifically where I can do something like this?
You can use the jquery filter() function for filtering a variable with jQuery objects.
var $radios = $('[name=test],[name=test2]');
var $radiosFiltered = $radios.filter(':checked');
$radiosFiltered.each(function(){
console.log($(this).val());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="radio" name="test" value="1" checked>
<input type="radio" name="test" value="2">
<input type="radio" name="test" value="3">
<input type="radio" name="test2" value="4">
<input type="radio" name="test2" value="5" checked>
<input type="radio" name="test2" value="6">
You was so close, you need to use filter to get the checked elements from your collection :
$employmentStatusRadioButtons.filter(':checked');

How to use buttons to allow user to add/subtract input elements and maintain element value sequence?

I am trying to use "+" and "-" buttons to allow the user to add or subtract the number of possible choices for each question in a multiple choice quiz creation app.
The max number of choices per question is 4, and the minimum is 2.
The issue I am coming up against is that after adding a choice, the subtract button cannot read the value of the last radio button.
Also, the values of the radio buttons are there because they are used in other parts of the application, not just for this functionality. Therefore it is important that the radio button choices are consecutive, starting with 0.
Thank you in advance for any tips.
Here is a Codepen, but the code I am using is also below: http://codepen.io/anon/pen/zKdzZv?editors=1010
HTML:
<div id="q-container">
<div class="qelem">
<h4>Question 1.)</h4>
<input type="text" class="question" style="width:400px"
placeholder=" Who was the 2nd president of the United States?">
<br>
<br>
<ul style="list-style:none;" class="choices">
<li><input type="radio" name="rad" value="0"><input type="text" class="choice" placeholder=" John Hancock"></li>
<li><input type="radio" name="rad" value="1"><input type="text" class="choice" placeholder=" Adam Smith"></li>
<li><input type="radio" name="rad" value="2"><input type="text" class="choice" placeholder=" John Adams"></li>
</ul>
<br>
<div class="btn-group btn-group-xs choiceAmt" role="group">
<button type="button" class="btn" id="add"><small><span class="glyphicon glyphicon-plus"></span></small></button>
<button type="button" class="btn" id="sub"><small><span class="glyphicon glyphicon-minus"></span></small></button>
</div>
</div>
</div>
JavaScript:
$("#add").click(function(){
var num;
var lastRadioVal = $(this).parents(".qelem").find("input:radio").last().val();
console.log("lastRadioVal = " +lastRadioVal);
num = lastRadioVal+1;
$(this).parents(".qelem").children(".choices").append(
'<li><input type="radio" name="rad" value="'+num+'">
<input type="text" class="choice"></li>'
);
if(lastRadioVal = 3){
$(this).prop('disabled',true);
}
if(lastRadioVal > 1){
$("#sub").prop('disabled',false);
}
console.log("lastRadioVal = " +lastRadioVal);
});
$("#sub").click(function(){
var lastRadioVal = $(this).parents(".qelem").find("input:radio").last().val();
console.log("lastRadioVal = " +lastRadioVal);
$(this).parents(".qelem").find("li").last().remove();
lastRadioVal--;
if(lastRadioVal = 1){
$(this).prop('disabled', true);
}
$("#add").prop('disabled', false);
console.log("lastRadioVal = " +lastRadioVal);
});
Why call a convoluted (and low performance) scanning selector like this? Perhaps you have a reason?
If it was me I would just add IDs to the buttons and simply call them directly.
$('#radioid').value();
something along those lines. Does that help? Finding parents/children and scanning down the dom till you find something should IMHO be avoided at all costs. Sometimes it's useful but really it creates a maintence nightmare when in a year pages get refactored and someone not aware of your dom scanning code changes the HTML and then your code starts running against their HTML and the fun of jquery truly begins.
does that help at all?
Using IDs will save your life in jQuery.
Instead of finding the last val of the radio elements, I called .length on children of the .choices ul, stored that in a variable on each button click, and used if statements, and it works as it should.

Change radio button text inside <span>

I am searching for a different way to change the word FOO with javascript:
<div class="radio"">
<label for="radios-1" id="lbl_radio-1" class="unchecked_radio">
<input type="radio" name="radios" id="radios-1" value="1">
<span>FOO</span>
</label>
</div>
I came up with the solution
var v = document.getElementById('lbl_radio-1');
v.innerHTML=v.innerHTML.replace("<span>FOO</span>","<span>BAR</span>");
But I find it is not the right way. There must be something better, shorter, nicer...
Check this out: **Fiddle
Is there a way to directly address the radios-1 id? At least I did not succeed. And why can't I show the innerHTML for the latter, but for the former lbl_radio-1?
Use querySelector() to target the span that follows the radio button.
You can then set its text content directly:
var v = document.querySelector('#radios-1 + span');
v.textContent= 'BAR';
Fiddle
Because you're using jquery you could use :
$('#radios-1').next().text('BAR');
//OR
$('#radios-1').next('span').text('BAR');
Hope this helps.
Snippet
$('#radios-1').next().text('BAR');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="radio">
<label for="radios-1" id="lbl_radio-1" class="unchecked_radio">
<input type="radio" name="radios" id="radios-1" value="1"/>
<span>FOO</span>
</label>
</div>

Problems with retrieving radio button value for feedback form

I'm trying to build a simple feedback form. The user will answer a series of yes or no questions. If they choose no, then they will be provided with a comment form to include text.
Currently, I'm having problems with retrieving radio button values. I am trying to print them in the console, but nothing happens when I choose the appropriate choice. If the user chooses 'no', it needs to be able to remember the comment that will get submitted.
My JSFiddle is here: http://jsfiddle.net/787x18vx/
HTML
<p>You are providing feedback</p>
<form>
<div id="question-1">
<label for="question-1">Is this correct?</label>
<input type="radio" value="yes" name="choice-1" />Yes
<input type="radio" value="no" name="choice-1" />No
</div>
<div id="question-2">
<label for="question-2">Another question</label>
<input type="radio" value="yes" name="choice-2" />Yes
<input type="radio" value="no" name="choice-2" />No
</div>
<div id="question-3">
<label for="question-3">One more question</label>
<input type="radio" value="yes" name="choice-3" />Yes
<input type="radio" value="no" name="choice-3" />No
</div>
<br />
<button>Send Feedback</button>
</form>
jQuery
var firstInput = 'input[name=choice]';
var firstInputValue = $('input[name=choice-1]:checked').val();
$(firstInput).on('click', function() {
console.log(firstInputValue);
console.log($('input[name="choice-1"]:checked').val());
console.log($('input[name="choice-2"]:checked').val());
// if value === 'no' show comment form
});
You are using input[name=choice] selector which is not exisiting.
Use input[type=radio] instead.
var firstInput = 'input[type=radio]';
var firstInputValue = $('input[name=choice-1]:checked').val();
$(firstInput).on('click', function() {
console.log(firstInputValue);
console.log($('input[name="choice-1"]:checked').val());
console.log($('input[name="choice-2"]:checked').val());
// if value === 'no' show comment form
});
Fiddle
var firstInput = 'input[name=choice]';
This is looking for something specifically with the name choice, which doesn't appear to be in your html.
There are two quick ways about this.
First, just change your selector:
$('input[type=radio]').on('click', function(){...
This will trigger the function on a click of any radio
Another way is with the wildcard selector:
var firstInput = 'input[name^=choice]';
The ^ should make is so any input with the name starting with choice gets selected.
This method should work, but targeting input[type=radio] is probably a better solution,
You are missing the -1 in your name
var firstInput = 'input[name=choice-1]';
Your selector is trying to get tags with name exactly equals 'choice'. You can search by prefix with the following
var firstInput = 'input[name|="choice"]';
This will get all tags which name starts with 'choice'

How to set up groups of checkboxes which affect each other

Sorry for the ambiguous title, but it's quite hard to condense what I'm trying to do into a few words. Here's exactly what I'm trying to do:
I want to have a series of groups of checkboxes. One would be gender, with checkboxes for Male and Female, one would be Region, with checkboxes for North, East, South and West and so on.
The aim is to allow the user to select say, Male or Female, but as soon as they put a check in a checkbox of another group e.g. any of the Region checkboxes, all of their previous 'checks' from all other groups are removed.
The point is to only allow the user to select from one group of checkboxes at a time.
I can only think of checking which checkboxes have been marked on click using javascript, but was wondering if there was a simpler way which I may be missing.
I've also thought that maybe a hidden radio button for each group could work.
If anyone has a more elegant solution I'm eager to hear it.
Its been a long time since I've done any pure Javascript, libraries like jQuery make this kind of thing so easy. Anyway, something a bit like the following might work, you'd need to test it in a few browsers and tweak to what you need.
<form name="theForm">
<input type="checkbox" id="male" name="theGroup" onClick="clearGroup(this);">male
<input type="checkbox" id="female" name="theGroup" onClick="clearGroup(this);">female
<br />
<input type="checkbox" id="north" name="theGroup" onClick="clearGroup(this);">north
<input type="checkbox" id="south" name="theGroup" onClick="clearGroup(this);">south
<input type="checkbox" id="east" name="theGroup" onClick="clearGroup(this);">east
<input type="checkbox" id="west" name="theGroup" onClick="clearGroup(this);">west
</form>
<script>
function clearGroup(elem) {
var group = document.theForm.theGroup;
for (var i=0; i<group.length; i++) {
if (group[i] != elem) {
group[i].checked = false;
}
}
}
</script>
Here is a working example to play around with.
You could do the equivalent thing in jQuery as simply as
$('input:checkbox').click(function() {
$(this).siblings(':checked').attr('checked', false);
});
and you have no browser compatibility issues to worry about.
Managed to figure it out with a little help from fearofawhack planet. Seems really simple now.
Heres a link to the JSFiddle http://jsfiddle.net/aeeN4/
if you have different groups you can use this code below.
<script>
function clearGroup(elem) {
//alert(elem.name);
var group = document.getElementsByName(elem.name);
for (var i=0; i<group.length; i++) {
if (group[i] != elem) {
group[i].checked = false;
}
}
}
</script>
<form name="theForm">
<input type="checkbox" id="male" name="theGroup2" onClick="clearGroup(this);">male
<input type="checkbox" id="female" name="theGroup2" onClick="clearGroup(this);">female
<br />
<input type="checkbox" id="north" name="theGroup" onClick="clearGroup(this);">north
<input type="checkbox" id="south" name="theGroup" onClick="clearGroup(this);">south
<input type="checkbox" id="east" name="theGroup" onClick="clearGroup(this);">east
<input type="checkbox" id="west" name="theGroup" onClick="clearGroup(this);">west
</form>

Categories

Resources