i'm just learned the javascript. i'm trying to make a simple front-end for practice. so, i've been struggling to select all checkbox inside 'td'.
<table>
<tr class="top1000">
<td><input type="checkbox" onclick="ropangTopping()"><label>milo</label></td>
<td><input type="checkbox" onclick="ropangTopping()"><label>chocolate</label></td>
<td><input type="checkbox" onclick="ropangTopping()"><label>chocochip</label></td>
<td><input type="checkbox" onclick="ropangTopping()"><label>koko krunch</label></td>
</tr>
<tr class="top3000">
<td><input type="checkbox" onclick="ropangTopping()"><label>mozarella</label></td>
<td><input type="checkbox" onclick="ropangTopping()"><label>cheddar</label></td>
<td><input type="checkbox" onclick="ropangTopping()"><label>green tea</label></td>
<td><input type="checkbox" onclick="ropangTopping()"><label>boba</label></td>
</tr>
</table>
when i initialized with this var topping1000 = document.querySelector(".top1000 td input[type=checkbox]");, it just select the first checkbox. but when i use querySelectorAll it didn't select anything. i know this is a silly question. any answer would be appriciated it. thanks in advance.
You're almost there. You do need to use
querySelectorAll()
to grab all the nodes.
But then you need to loop through those nodes and check each one in turn.
One way to do this (there are several) might be to use a forEach loop:
toppings1000.forEach((topping1000) => {topping1000.checked = true;});
N.B. Note the names of the variables I'm using immediately above. I'm distinguishing between the collection of multiple nodes (toppings1000):
toppings1000 // with an 's' to indicate that it's a plural set
and the individual node in each iteration of the forEach loop (topping1000):
topping1000 // no 's' this time - it's just a single node
Working Example:
var toppings1000 = document.querySelectorAll(".top1000 td input[type=checkbox]");
toppings1000.forEach((topping1000) => {
topping1000.checked = true;
});
<table>
<tr class="top1000">
<td><input type="checkbox" onclick="ropangTopping()"><label>milo</label></td>
<td><input type="checkbox" onclick="ropangTopping()"><label>chocolate</label></td>
<td><input type="checkbox" onclick="ropangTopping()"><label>chocochip</label></td>
<td><input type="checkbox" onclick="ropangTopping()"><label>koko krunch</label></td>
</tr>
<tr class="top3000">
<td><input type="checkbox" onclick="ropangTopping()"><label>mozarella</label></td>
<td><input type="checkbox" onclick="ropangTopping()"><label>cheddar</label></td>
<td><input type="checkbox" onclick="ropangTopping()"><label>green tea</label></td>
<td><input type="checkbox" onclick="ropangTopping()"><label>boba</label></td>
</tr>
</table>
Related
I have a Javascript / Jquery function that controls groups of checkboxes.
The checkboxes are created on PHP form from a database call so I am iteratively going through a recordset and creating checkboxes in html.
For each checkbox I assign it a class of "checkboxgroup" + a numeric identifier to create a group of 'like' records.
I end up with multiple checkboxes like this:
<tr class="tablebody">
<td><input name="contactresolveid2048" id="contactresolveid2048" type="checkbox" class="checkboxgroup0"/></td>
<td>David Smith</td>
</tr>
<tr class="tablebody">
<td><input name="contactresolveid19145" id="contactresolveid19145" type="checkbox" class="checkboxgroup0"/></td>
<td>graham Foots</td>
</tr>
<tr class="tablebody">
<td><input name="contactresolveid19146" id="contactresolveid19146" type="checkbox" class="checkboxgroup0"/></td>
<td>Tom Silly</td>
</tr>
As you can see, these 3 checkboxes have a class of 'checkboxgroup0'
The following function detects a click on ANY of the checkbox groups on a form (of which there may be many) and unchecks any checkboxes (belonging to the same group) that are not the clicked one.
$('[class^="checkboxgroup"]').click(function() {
var thisClass = $(this).attr('class');
var $checkboxgroup = $('input.'+thisClass);
$checkboxgroup.filter(':checked').not(this).prop('checked', false);
});
Under most circumstances this works fine when the only class is 'checkboxgroup0'.
However when validation takes place JQuery validate appends a 'valid' or 'error' class to the class list of any fields that pass or fail validation, so I can endup having an .attr(class) of 'checkboxgroup0 valid'.
My question is this:
How do I return the whole class name of the partially selected class WITHOUT any extraneous classes?
By using the selector $('[class^="checkboxgroup"]') I need the whole part of that selector 'checkboxgroup0' and no other classes that may be assigned to it.
This issue you've encountered is one of the reasons why using incremental id/class attributes are not good practice.
To work around this issue with your JS you can instead use the same class on every checkbox. You can then group them by a data attribute instead. Using this method means that the number of classes on an element or their position within the class attribute string does not matter.
Try this example:
$('.checkboxgroup').click(function() {
let $this = $(this);
let $group = $(`.checkboxgroup[data-group="${$this.data('group')}"]`);
$group.not(this).prop('checked', false);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr class="tablebody">
<td><input name="contactresolveid2048" id="contactresolveid2048" type="checkbox" class="checkboxgroup" data-group="0" /></td>
<td><label for="contactresolveid2048">David Smith</label></td>
</tr>
<tr class="tablebody">
<td><input name="contactresolveid19145" id="contactresolveid19145" type="checkbox" class="checkboxgroup" data-group="0" /></td>
<td><label for="contactresolveid19145">graham Foots</label></td>
</tr>
<tr class="tablebody">
<td><input name="contactresolveid19146" id="contactresolveid19146" type="checkbox" class="checkboxgroup" data-group="0" /></td>
<td><label for="contactresolveid19146">Tom Silly</label></td>
</tr>
</table>
However, it's worth noting that what you're attempting to do can be far better achieved using HTML alone. Simply use a radio input and give them all the same name attribute, then you get the behaviour you're trying to create for free:
<table>
<tr class="tablebody">
<td><input name="contactresolve" id="contactresolveid2048" type="radio" /></td>
<td><label for="contactresolveid2048">David Smith</label></td>
</tr>
<tr class="tablebody">
<td><input name="contactresolve" id="contactresolveid19145" type="radio" /></td>
<td><label for="contactresolveid19145">graham Foots</label></td>
</tr>
<tr class="tablebody">
<td><input name="contactresolve" id="contactresolveid19146" type="radio" /></td>
<td><label for="contactresolveid19146">Tom Silly</label></td>
</tr>
</table>
I have a large table of inputs and on click event I need to extract the input values of each row to send them to the server.
I need to ask if there is a better way to do it to prevent all that hard coding.
My below code works somehow, but I haven't checked if the input has type radio, so I need to write more code to finalize it.
I am not sure if am doing well or if you can share a better way on this.
Here is what I do below:
Iterate over each table row and assign each row id to the object as a
key.
Iterate over that object to get each row's input values
Save the input to the object as values seperated by _ to be splitted as an array
Live Demo
<!DOCTYPE html>
<html>
<body>
<table>
<tbody id="dynamic_form_tbody">
<tr id="123">
<td><input type="text"></td>
<td><input type="date"></td>
<td><input type="radio" name="choice" value="yes"> <input type="radio" name="choice" value="no"></td>
</tr>
<tr id="1256">
<td><input type="text"></td>
<td><input type="date"></td>
<td><input type="radio" name="choice" value="yes"> <input type="radio" name="choice" value="no"></td> </tr>
<tr id="1212">
<td><input type="text"></td>
<td><input type="date"></td>
<td><input type="radio" name="choice" value="yes"> <input type="radio" name="choice" value="no"></td> </tr>
</tbody>
</table>
<input type="button" id="log" value="console.log data">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script>
$(document).ready(() => {
var $btn = $('#log')
$btn.click(e => {
var table_tbody = $('#dynamic_form_tbody')
var dynamic_form_data = {}
//collect each row's id
table_tbody.find("tr").each(function (e) {
console.log('tr found with id: ' + $(this).attr('id'))
id = $(this).attr('id')
dynamic_form_data[id] = ""
})
for (let id in dynamic_form_data) {
$(`tr#${id} input`).each(function (e) {
let $this_val = $(this).val() || null
dynamic_form_data[id] += [$this_val + '_']
})
}
console.log(dynamic_form_data)
})
})
</script>
</body>
</html>
Some issues:
Your radiobuttons all have the same name, so that you can only select one in the whole table. I suppose you should be able to select one in each row.
$(this).val() || null: null is not useful, as an empty string is fine. If you decide to produce a string instead of an array, then null becomes "null", which is indistinguishable from an input that really has those characters. I would therefore drop || null.
[$this_val + '_'] converts a string to an array, but then that array is immediately converted back to a string when assigned with +=.
+ '_' will add also an underscore after the last value.
Both radio button values (yes, no) are always added to the result, without taking the selection into account. You should only take the one that is checked
To avoid that neither of the two radio buttons is selected, provide a default in the HTML definition, using the checked attribute
There seems no reason to not do the job in one cycle instead of two. You can select all the inputs that are not radio buttons, plus the checked radio buttons.
$(() => {
$('#log').click(e => {
var dynamic_form_data = {};
$('#dynamic_form_tbody').find('tr').each(function () {
var $inputs = $(this).find(':checked,input:not([type="radio"])');
dynamic_form_data[$(this).attr('id')] = $inputs.map(function() {
return $(this).val();
}).get(); // Chain `.join("_")` if you want a string instead of array.
});
console.log(dynamic_form_data);
});
})
<table>
<tbody id="dynamic_form_tbody">
<tr id="123">
<td><input type="text"></td>
<td><input type="date"></td>
<td><input type="radio" name="choice123" value="yes" checked> <input type="radio" name="choice123" value="no"></td>
</tr>
<tr id="1256">
<td><input type="text"></td>
<td><input type="date"></td>
<td><input type="radio" name="choice1256" value="yes" checked> <input type="radio" name="choice1256" value="no"></td>
</tr>
<tr id="1212">
<td><input type="text"></td>
<td><input type="date"></td>
<td><input type="radio" name="choice1212" value="yes" checked> <input type="radio" name="choice1212" value="no"></td>
</tr>
</tbody>
</table>
<input type="button" id="log" value="console.log data">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
how are you?
How can I get all values of a inputs inside a one TR in a table? I'd find examples, with not for a specific row (with ID)
I have this table:
<table>
<tr id="a">
<td><input id="a_01" value="the value of a_01"></td>
<td><input id="a_02" value="the value of a_02"></td>
</tr>
<tr id="b">
<td><input id="b_01" value="the value of b_01"></td>
<td><input id="b_02" value="the value of b_02"></td>
</tr>
</table>
For example: i'm triying to get all value inputs of a tr with id="b".
Thanks a lot for yout help!
You can use a selector to target the elements. To do so, you don't need jQuery, since you can use the querySelector and querySelectorAll functions:
document.querySelector('button').addEventListener('click', function(){
// Radio input value
var value = document.querySelector('input[name="idvalue"]:checked').value;
// Here's the selector for the input elements
var elements = document.querySelectorAll('#' + value + ' input');
// You can iterate the result and use the element values
elements.forEach(e => {console.log(e.id + ': ' + e.value);});
});
<table>
<tr id="a">
<td><input id="a_01" value="the value of a_01"></td>
<td><input id="a_02" value="the value of a_02"></td>
</tr>
<tr id="b">
<td><input id="b_01" value="the value of b_01"></td>
<td><input id="b_02" value="the value of b_02"></td>
</tr>
</table>
<div>
<input type="radio" name="idvalue" id="radioa" value="a" checked /><label for="radioa">Show values for #a</label>
<input type="radio" name="idvalue" id="radiob" value="b" /><label for="radiob">Show values for #b</label>
</div>
<button>Show Values of selected #id</button>
If you really really need t do it in jquery, you can use the same selector to target the elements: $("#b input").
I suggest you further read about selectors. Here's the MDN link.
I have a list of checkboxes that require one or two certain boxes to be checked in order to return true, however I am unsure how to go about finding if only the required boxes are checked and no other boxes are.
The HTML for the checkboxes are as follows:
<table style="width:135px; height:200px; margin: 0 auto; margin-top: -200px;">
<tr>
<td><input type="checkbox" class="f1s1c"></td>
<td><input type="checkbox" class="f1s2"></td>
<td><input type="checkbox" class="f1s3"></td>
<td><input type="checkbox" class="f1s4"></td>
</tr>
<tr>
<td><input type="checkbox" class="f2s1"></td>
<td><input type="checkbox" class="f2s2"></td>
<td><input type="checkbox" class="f2s3"></td>
<td><input type="checkbox" class="f2s4"></td>
</tr>
<tr>
<td><input type="checkbox" class="f3s1"></td>
<td><input type="checkbox" class="f3s2"></td>
<td><input type="checkbox" class="f3s3"></td>
<td><input type="checkbox" id="cCorrect1"></td>
</tr>
<tr>
<td><input type="checkbox" class="f4s1"></td>
<td><input type="checkbox" class="f4s2"></td>
<td><input type="checkbox" class="f4s3"></td>
<td><input type="checkbox" class="f4s4"></td>
</tr>
</table>
As you can see there are many possible chekboxes however in this case only cCorrect1 must be checked in order for the javascript to return true. All the other checkboxes are as classes as I have multiple tables that follow the same structure.
Currently my Javascript returns true if cCorrect1 is checked but obviously also returns true if any other box is also checked along with it.
My Javascript:
//Quiz Functions
$("#checkC").click(function(){
if(cCorrect1.checked){
cCorrect = true;
}else if(cCorrect1.checked == false){
cCorrect = false;
}
});
Would using an array that checks through the checkboxes and finds out when cCorrect1 is checked would work? I think that may be on the right track but I do not know how to go about that.
Any input and help is much appreciated.
Assuming you have a way to find the right set of checkboxes (a shared class on all of them, etc.) you can count the number of checked boxes in the list. If it's 1, and your target box is checked, you're good.
In this example, I added an id to the table containing the checkboxes to make them easier to find. Removed the style so the table is visible.
$("#checkC").click(function(){
// the one we want
var cCorrect1 = $('#cCorrect1');
// all checked checkboxes in the table
var checks = $('#boxes input[type=checkbox]:checked');
var cCorrect = cCorrect1.prop('checked') && (checks.length == 1);
alert(cCorrect ? "correct" : "incorrect");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table id="boxes" >
<tr>
<td><input type="checkbox" class="f1s1c"></td>
<td><input type="checkbox" class="f1s2"></td>
<td><input type="checkbox" class="f1s3"></td>
<td><input type="checkbox" class="f1s4"></td>
</tr>
<tr>
<td><input type="checkbox" class="f2s1"></td>
<td><input type="checkbox" class="f2s2"></td>
<td><input type="checkbox" class="f2s3"></td>
<td><input type="checkbox" class="f2s4"></td>
</tr>
<tr>
<td><input type="checkbox" class="f3s1"></td>
<td><input type="checkbox" class="f3s2"></td>
<td><input type="checkbox" class="f3s3"></td>
<td><input type="checkbox" id="cCorrect1"></td>
</tr>
<tr>
<td><input type="checkbox" class="f4s1"></td>
<td><input type="checkbox" class="f4s2"></td>
<td><input type="checkbox" class="f4s3"></td>
<td><input type="checkbox" class="f4s4"></td>
</tr>
</table>
<button id="checkC">check</button>
What you could do is create an array of right answers, discover the selected answers per row, and decide if it's "correct" or "incorrect".
You can use this code to return of array of checkboxes state (0 for unchecked, 1 for checked), and decide what to do from there:
var $table = this.$('tbody');
$(".resultBtn").click(function(){
var outStr = '';
for(var i= 0,len=$table.children().length;i<len;i++){
var $tr = $table.children().eq(i);
outStr += 'row' + (i+1) + ' checked boxes:[';
for(var j= 0;j<$tr.children().length;j++){
var $td = $tr.children().eq(j);
if($td.find(':checked').length > 0 ){
$td.addClass('selected');
outStr += '1,';
} else{
outStr += '0,';
}
if(j==$tr.children().length-1) outStr = outStr.substring(0, outStr.length - 1);
}
outStr += ']';
}
alert(outStr);
});
example:
http://jsfiddle.net/y3yp4ag1/2/
Lets say I have table with 10 rows and in each row 10 columns of checkboxes
before the user submits I want to add the following validation:
in each row at least two checkbox are checked!
<form name="myForm">
<div data-ng-controller="myController">
<table border="1">
<tr>
<td><input type="checkbox" /></td>
<td><input type="checkbox" /></td>
<td><input type="checkbox" /></td>
<td><input type="checkbox" /></td>
<td><input type="checkbox" /></td>
<td><input type="checkbox" /></td>
<td><input type="checkbox" /></td>
<td><input type="checkbox" /></td>
<td><input type="checkbox" /></td>
<td><input type="checkbox" /></td>
</tr>
...
</table>
<button data-ng-click="save()" ng-disabled="$myForm.invalid">Save</button>
</form>
$scope.save = function() {
if (myForm.$valid){
alert("can submit the form...")
}
};
How to do this? where to add the validation functionality?
I recently answered a similar question with a custom directive that allows the user to define groups of controls (text-fields, selects, checkboxs, whatever) and require that at least one control in each group not empty.
It should be easy to modify so that at least two controls are not empty.
Then myForm.$valid will always be "up-to-date" (so you can use it to give visual feedback or allow the form to be submitted).
If your checkboxes are static in the HTML, You can bind the checkboxes to boolean models like:
<input type="checkbox" ng-model="checked[1]">
Validate
and then use something like this to validate
$scope.checked = {};
$scope.validate = function() {
var count=0;
angular.forEach($scope.checked, function(k,v){ if (k) count++; });
if (count > 2)
alert("validated");
};
To extend this to multiple rows is trivial.
You can see this working on here: http://plnkr.co/edit/thbJ81KWUDyF6WTcWL9u?p=preview
Of course you can define an array in the controller and use the ng-repeat directive in conjunction with this idea.