This is the checkboxes in my HTML:
<input type="checkbox" name="sides" id="1" value="French Fries" >French Fries<br />
<input type="checkbox" name="sides" id="2" value="Baked Potato">Baked Potato<br />
<input type="checkbox" name="sides" id="3" value="Cole Slaw">Cole Slaw<br />
<input type ="button" value = "Enter my side dish selections" onclick="checkbox(sides.value1,sides.value2)"/>
What i want is when the user clicks the button, it should take first two checked boxes and then display it as:
function checkbox(dish1,dish2) {
document.getElementById("side_one").innerHTML = dish1;
document.getElementById("side_two").innerHTML = dish1;
}
I am confused on how to do this, can you please help me here.
You can select the first two checked inputs with [...document.querySelectorAll( ":checked" )].slice( 0, 2 );.
What it does is to create an Array from a NodeList made of all the elements that matches the :checked pseudo-class and slice it in an new Array of two items.
Then you just need to grab the .value of the found <input> elements:
document.querySelector('[type="button"]').onclick = (evt) => {
const checked = [...document.querySelectorAll( ":checked" )].slice( 0, 2 );
checkbox( ...checked.map( (input) => input.value ) )
};
function checkbox(dish1 = "", dish2 = "") {
document.getElementById("side_one").innerHTML = dish1;
document.getElementById("side_two").innerHTML = dish2;
}
<input type="checkbox" name="sides" id="1" value="French Fries" >French Fries<br />
<input type="checkbox" name="sides" id="2" value="Baked Potato">Baked Potato<br />
<input type="checkbox" name="sides" id="3" value="Cole Slaw">Cole Slaw<br />
<input type ="button" value = "Enter my side dish selections"/>
<p id="side_one"></p>
<p id="side_two"></p>
If you want it to search only in the content of a specific element, you just need to make the CSS selector in querySelectorAll more specific.
You can use something like the following:
Array.from(document.getElementsByName('entree')).filter(input => input.checked).map(input => input.value)
This makes an array out of node list of interest, filters out all unchecked elements and returns an array that will have zero or more values depending on what is checked. You can then .join() it or otherwise do as you see fit.
basically, radio is a NodeList, so you can do this
const radioValue = (radio.length > 0) ? radio[0].value : "";
Related
Hi I'm new to web development and working on simple projects and I am stuck on a problem if anyone can help. I have a 3 checkboxes that a user can check on what their favourite things are to do. After completing the question I am trying to log the value of the chosen boxes however I am getting unidentified results if anyone can help id be grateful. This is the code:
html:
What is your favorite thing to do:
<p id = "favoriteThings">
<input type="checkbox" name="TV" value=1>Watch TV
<input type="checkbox" name="Books" value=2>Read Books
<input type="checkbox" name="work" value=3>Work
</p>
JS:
var favoriteThings = document.getElementById("favoriteThings");
console.log("favorite things: " + favoriteThings.value);
I am assuming that the problem is the paragraph tag is the ID but can someone give me a fix to this? As I don't want to give each checkbox the same ID as I heard its bad practice.
thanks in advance.
When you want to group your checkbox (or radio) inputs, use the same name for your group of inputs
Use a different value
Use querySelectorAll() to get your desired elements using the Attribute selector "[]"
Use nodeList.forEach() to iterate your elements
Use addEventListener() to attach an Event, "input" in your case:
const ELs_favorite = document.querySelectorAll("[name=favorite]");
const get_favorite = () => {
const checked_values = [...ELs_favorite].reduce((arr, EL) => {
if (EL.checked) arr.push(EL.value);
return arr;
}, []);
console.log(checked_values);
};
ELs_favorite.forEach(EL => {
EL.addEventListener("input", get_favorite);
});
What is your favorite thing to do:
<p>
<label><input type="checkbox" name="favorite" value="tv">Watch TV</label>
<label><input type="checkbox" name="favorite" value="books">Read Books</label>
<label><input type="checkbox" name="favorite" value="work">Work</label>
</p>
In the example above, Array.reduce() is used to collect only the values of the checked input elements into an Array.
you can give each checkbox the same id (there is no problem).
Solution:
<p id = "favoriteThings">
<input type="checkbox" name="favoriteThings" value="TV" or "1" onclick="MyNameFunction()">Watch TV
<input type="checkbox" name="favoriteThings" value="Read Books" or "2" onclick="MyNameFunction()">Read Books
<input type="checkbox" name="favoriteThings" value="Work" or "3" onclick="MyNameFunction()">Work
</p>
js
var choices = [];
var els = document.getElementsByName('favoriteThings');
console.log("Favourite things: ");
for (var i=0;i<els.length;i++){
if ( els[i].checked ) {
console.log(els[i].value);
}
Is this a good solution to check multiple radio buttons with 1 label? I have a form with multiple steps. The last step shows a summary about the previous steps and I need to get all data from there. Is there a better option? How can I get the text from the input fields and insert it to the summary? JavaScript?
$('label').click(function() {
id = this.id.split('-');
if (id[0] === '1') {
id[0] = '2';
} else {
id[0] = '1';
}
$('#' + id[0] + '-' + id[1]).prop('checked', true);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="one">
<input type="radio" id="1-1" name="1-level">
<label for="1-1" id="1-1">1</label>
<input type="radio" id="1-2" name="1-level">
<label for="1-2" id="1-2">2</label>
</div>
<div class="two">
<input type="radio" id="2-1" name="2-level">
<label for="2-1" id="2-1">1</label>
<input type="radio" id="2-2" name="2-level">
<label for="2-2" id="2-2">2</label>
</div>
Add a form element to wrap your input elements in. Forms can access all the inputs that are inside of it and see their names and their values. So in this case it is important that you use the value attribute on your input elements. Start by doing the above and make your code look like the example below.
Also, be careful with id's. They need to be unique, so they can only appear once in every document. Right now the label and their input elements have the same id.
<form id="step-form">
<div class="one">
...
</div>
</form>
Like #Shilly suggested, use the FormData API. This API is designed to get all the values from a form, think input, textarea and select elements and puts all of that data into a single object. This way you can create as many form-elements as you want, add them to the form and store their values in a single object.
The data in that object will be read as key-value pairs, which in this case are the name and value attribute values. For example: ['1-level', '2'], here we see the input with the name '1-level' and the value '2'.
I would not recommend using other input elements to show your results or summary. This could be confusing for the user as it suggests input. Instead print your results in plain text or create a list.
I do not know the jQuery equivalent of many of these API's or methods, so I've used Vanilla JavaScript to create a demo which, hopefully, demonstrates what you try to accomplish.
If you have any question, I've been unclear, or have not helped you in any way. Please let me know.
const form = document.getElementById('step-form');
const summary = document.getElementById('step-summary');
const clear = document.getElementById('step-clear');
// Remove all children of the summary list.
function clearSummary() {
while(summary.firstElementChild) {
summary.firstElementChild.remove();
}
}
// Clear list on click.
clear.addEventListener('click', event => {
clearSummary();
});
form.addEventListener('submit', event => {
// Clear list first.
clearSummary();
// Create a fragment to store the list items in.
// Get the data from the form.
const fragment = new DocumentFragment();
const formData = new FormData(event.target);
// Turn each entry into a list item which display
// the name of the input and its value.
// Add each list item to the fragment.
for (const [ name, value ] of formData) {
const listItem = document.createElement('li');
listItem.textContent = `${name}: ${value}`;
fragment.appendChild(listItem);
}
// Add all list items to the summary.
summary.appendChild(fragment);
event.preventDefault();
});
<form id="step-form">
<div class="one">
<input type="radio" id="1-1" name="1-level" value="1">
<label for="1-1">1</label>
<input type="radio" id="1-2" name="1-level" value="2">
<label for="1-2">2</label>
</div>
<div class="two">
<input type="radio" id="2-1" name="2-level" value="1">
<label for="2-1">1</label>
<input type="radio" id="2-2" name="2-level" value="2">
<label for="2-2">2</label>
</div>
<div class="three">
<input type="radio" id="3-1" name="3-level" value="1">
<label for="3-1">1</label>
<input type="radio" id="3-2" name="3-level" value="2">
<label for="3-2">2</label>
</div>
<ul id="step-summary"></ul>
<button type="submit">Review form</button>
<button type="button" id="step-clear">Clear summary</button>
</form>
I'm trying to refactor my Javascript/Jquery to use a select option and hidden input value in order to sort the divs on the page.
Currently, my JS works but it's hiding all divs whose hidden input has a value of 0. I want to keep the logic, but instead of hiding, just reorder the divs.
So if the user selects Recently_ordered from the select box, then any div whose hidden input has a value of 1 would show first and all with 0 would show after. Basically, all items remain on page but reorder slightly.
here's the working script that currently hides:
<script type="text/javascript">
$(function(){
$('#filterText').on('change', function() {
var currentVal = $(this).val();
$(".group-container").show();
if (currentVal == 'recently_ordered') {
$('.group-container input[name="reorder"]').each(function (index, value){
if($(this).val() == "0"){
$(this).parent('.group-container').hide();
}
});
}
});
});
</script>
And the basic structure of the HTML:
#foreach ($orderFormData->pgroups as $pgroup)
<div class="group-container">
<input type="hidden" name="topseller" value="{{$pgroup->topseller}}" />
<input type="hidden" name="reorder" value="{{$pgroup->reorder}}"/>
Grab the .group-container elements as array, sort it according to their reorder value and append them to the DOM in the order of the array.
The snippet is really verbose but should give enough informations to follow the code.
The functions used in this snippet should all have a link to the official documentation or the description in the Mozilla Development Network in the comments.
The "groups" in the DOM have the mentioned hidden input fields and an additional <p> element which shows the value of the topseller and reorder fields which should make it easier to follow the changes from the script.
$(function() {
$("#filterText").on("change", function() {
var container = $(".container"), // get the surrounding container, used for appending the sorted groups
groups = $(".group-container").get(), // grab the "groups" and make them a regular array
// .get() -> https://api.jquery.com/get/
currentVal = this.value; // the value of the selected option
groups
// first we have to sort them in the "correct" order
// Array.prototype.sort() -> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
.sort(function(left, right) {
var topsellerValueLeft = parseInt(left.querySelector('input[name="topseller"]').value, 10), // get the value of the topseller field and make it a number
topsellerValueRight = parseInt(right.querySelector('input[name="topseller"]').value, 10), // get the value of the topseller field and make it a number
// Element.prototype.querySelector -> https://developer.mozilla.org/en-US/docs/Web/API/Element/querySelector
// parseInt() -> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt
// parseInt($(left).find('input[name="topseller"]').val(), 10)
// parseInt($(right).find('input[name="topseller"]').val(), 10)
// would yield the same result, but we don't need two full-blown jQuery objects just to get the value
reorderValueLeft,
reorderValueRight;
// in case of "recently ordered" we sort the groups on their reorder value
if (currentVal === "recently_ordered") {
reorderValueLeft = parseInt(left.querySelector('input[name="reorder"]').value, 10); // get the value of the reorder field and make it a number
reorderValueRight = parseInt(right.querySelector('input[name="reorder"]').value, 10); // get the value of the reorder field and make it a number
// we have to check the reorder value only when the values are different
if (reorderValueLeft !== reorderValueRight) {
return reorderValueRight - reorderValueLeft; // sort descending -> 1 ... 0
}
}
// either we are not supposed to sort the items by their reordered value
// or they have the same reordered value
// hence we will then sort them on their topseller value
// this time in ascending order
return topsellerValueLeft - topsellerValueRight;
})
// now we append the elements to the DOM in the same order as we find them in the array
// this will "remove" the groups one by one from the DOM and append it at their correct new spot
// Array.prototype.forEach() -> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
.forEach(function(group) {
container.append(group); // .append() -> https://api.jquery.com/append/
});
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="filterText">
<option value="default">default</option>
<option value="recently_ordered">recently ordered</option>
</select>
<br />
<div class="container">
<div class="group-container">
<p>1 | 1</p>
<input type="hidden" name="topseller" value="1" />
<input type="hidden" name="reorder" value="1" />
</div>
<div class="group-container">
<p>2 | 0</p>
<input type="hidden" name="topseller" value="2" />
<input type="hidden" name="reorder" value="0" />
</div>
<div class="group-container">
<p>3 | 1</p>
<input type="hidden" name="topseller" value="3" />
<input type="hidden" name="reorder" value="1" />
</div>
<div class="group-container">
<p>4 | 0</p>
<input type="hidden" name="topseller" value="4" />
<input type="hidden" name="reorder" value="0" />
</div>
</div>
(or on jsfiddle.net)
I have a checkboxes like this:
while($userRow=$resultForUsers->fetch_assoc()){
$nameOfUser=$userRow['users_name'];
$userId=$userRow['user_facebook_id'];
$userFBPicture=$userRow['users_picture'];
echo "
<tr class='tr-data-users'>
<td class='text-center'>
<input type='checkbox' class='checkbox' onclick='if(this.checked){selo(this.value)}else{izbaci(this.value)}' value=$userId>
</td>
So, for each user in my database I'm having one checkbox with value of his id. I need id's of all checked users(i.e checkboxes) in one array. I did it this way:
<input type='checkbox' class='checkbox' onclick='if(this.checked){put(this.value)}else{remove(this.value)}' value=$userId>
var niz={};
var index=0;
function put(o){
niz[index++]=o;
console.log(niz);
}
So, console.log now displays id's of all checked checkboxes. What I want to do is if checkbox is unchecked then to remove that id(i.e chechbox value) from array. I tried it like this:
onclick='if(this.checked){put(this.value)}else{remove(this.value)}'
var niz={};
var index=0;
function put(o){
niz[index++]=o;
console.log(niz);
remove(o,niz);
}
function remove(o,niz){
if($.inArray(o,niz)){
console.log('radim');
var indexNiza= $.inArray(o,niz);
niz= $.grep(niz,function(a,o){
return (a!=o);
});
}
}
As you can see this else part should handle if checkbox is unchecked and remove that id from array, but it doesn't work. Would really appreciate help on this.
It seems that the code you have written is taking a very complex route for a simple job. You can see the following for a good example on how to obtain all of the values into their own arrays for the checked and unchecked states.
In the demonstration, I enumerate through the checked and unchecked checkboxes if the user changes the state of any checkbox, and store the checked values in an array named cbChecked and the unchecked values get stored in cbUnchecked
The key here is the selectors used:
Selector usage
Get all 'checked' objects
:checked
Get all 'unchecked' objects
:not(:checked)
Demonstration
$(document).ready(function() {
$("input[type='checkbox']").change(function() {
var cbChecked = new Array();
var cbUnchecked = new Array();
$("input[type='checkbox']:checked").each(function() {
cbChecked[cbChecked.length] = this.value;
});
$("input[type='checkbox']:not(:checked)").each(function() {
cbUnchecked[cbUnchecked.length] = this.value;
});
$("p#cbChecked").html( cbChecked.join() );
$("p#cbUnchecked").html( cbUnchecked.join() );
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h2> The checkbox form</h2>
<form id="foo">
<p>A : <input type="checkbox" id="a" value="a"></p>
<p>B : <input type="checkbox" id="b" value="b"></p>
<p>C : <input type="checkbox" id="c" value="c"></p>
<p>D : <input type="checkbox" id="d" value="d"></p>
<p>E : <input type="checkbox" id="e" value="e"></p>
<p>F : <input type="checkbox" id="f" value="f"></p>
</form>
<h2>Checked Values</h2>
<p id="cbChecked"></p>
<h2>Unchecked Values</h2>
<p id="cbUnchecked"></p>
I have a form with a bunch of inputs. Sometimes the form will have 1 input and sometimes up to 10 inputs. When someone fills out each input I want a tag field at the bottom to be populated also. Right now I have it working but only with a set number of inputs. (3 at the moment).
Im trying to figure out how to make it work regardless of how many inputs there are on the page.
HTML
Input1 <input id="input1" name="input1" type="text" value="" />
<br/>
Input2 <input id="input2" name="input2" type="text" value="" />
<br/>
Input3 <input id="input3" name="input3" type="text" value="" />
<br/>
<p>List of inputed text</p>
<span id="allInputs"></span>
Jquery
$("#input1,#input2,#input3").change(function () {
var inputArray = [$("#input1").val(), $("#input2").val(), $("#input3").val()];
$("#allInputs").text(inputArray.join(' '));
});
A nice to have also would be putting them into another input instead of a span and adding a comma after each one except for the last one.
I know Im probably missing something very simple here.
In your example you are only allowing for 3 inputs as you have 3 input boxes, when any of those input boxes change your tags are then being transferred to the span.
Now it sounds like you wish to allow for multiple entries regardless of how many inputs. You could try something simple such as the below fiddle.
http://jsfiddle.net/K2g4z/
Html:
<div>
<strong>Enter your tag and click add</strong>
<br/>
<input type="text" id="tagEntry" />
<button id="tagAdd">Add</button>
</div>
<div>
<strong>Entered Tags</strong>
<br/>
<input type="text" id="tagsEntered" />
</div>
Javascript:
var tags = [];
$(function() {
$('#tagAdd').click(function(){
//get the tag value and trim the spaces
var tVal = $('#tagEntry').val().trim();
if(tVal == '')
return;
//reset the entry box
$('#tagEntry').val('');
//verify tag not already saved
for(var i=0;i<tags.length;i++)
if(tags[i] == tVal)
return;
//add the tag to the array
tags.push(tVal);
//set the tags entry box
$('#tagsEntered').val(tags.join(', '));
});
});
UPDATE:
The JSFiddle link http://jsfiddle.net/K2g4z/1/ now supports using multiple inputs of as many as you need. To achieve this instead of selecting on element ID we bind to a class name. Given the following Html.
<div>
<strong>Enter your tag and click add</strong>
<br/>
<strong>Tag 1</strong>
<input type="text" id="tagEntry" class="tagEntry" />
<br/>
<strong>Tag 2</strong>
<input type="text" class="tagEntry" />
<br/>
<strong>Tag 3</strong>
<input type="text" class="tagEntry" />
<br/>
<strong>Tag 4</strong>
<input type="text" class="tagEntry" />
<br/>
<strong>Tag 5</strong>
<input type="text" class="tagEntry" />
</div>
<div>
<strong>Entered Tags</strong>
<br/>
<input type="text" id="tagsEntered" />
</div>
All the tag input boxes have a class of tagEntry now this class will become our selector. With the following JS we can bind the blur event to every tag that has a class of tagEntry. This will now update the tags box every time any of the inputs changed.
var tags = [];
$(function() {
$('.tagEntry').blur(function(){
//get the tag value and trim the spaces
var tVal = $(this).val().trim();
if(tVal == '')
return;
//reset the entry box
$(this).val('');
//verify tag not already saved
for(var i=0;i<tags.length;i++)
if(tags[i] == tVal)
return;
//add the tag to the array
tags.push(tVal);
//set the tags entry box
$('#tagsEntered').val(tags.join(', '));
});
});
As you can see our handler binds to all the inputs, as any of the inputs receives the blur event the method of extracting the tags is executed.
$("#input1,#input2,#input3").change(function () {
var inputArray = [$("#input1").val(), $("#input2").val(), $("#input3").val()];
$("#masterinput").val(inputArray.join(' '));
});
You probably want to narrow the selector so it isn't selecting all text inputs on the page.
var inputs$ = $("input:text").change(function () {
var inputArray = [];
$.each(inputs$, function(i, v) {
inputArray.push($(v).val());
}
$("#allInputs").text(inputArray.join(' '));
});
Here you go:
var str = "";
$("input[type=text]").change(function () {
$("input[type=text]").each(function(){
str += $(this).val()+",";
};
});
$("#allInputs").html(str);