Looping through dynamically generated checkboxes to get values - javascript

I have a list of categories for products on my site and am trying to allow products to be listed under multiple categories.
When creating a product there is a list of categories with checkboxes generated from PHP like so:
$sql = "SELECT * FROM categories";
$stmt = DB::run($sql);
$categoryCount = $stmt->rowCount();
if ($categoryCount > 0) {
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)){
$id = $row["id"];
$category_name = $row["category"];
$category_checkboxes .= "<input type='checkbox' value='$id' name='cat_$id' id='cat_$id'> $category_name<br />";
}
}
I created a hidden input to determine the amount of available categories
<input type="hidden" name="cat_count" id="cat_count" value="<?php echo $categoryCount; ?>">
I am then trying to loop through these in JS to get which ones were selected to send via AJAX to my parsing script to add to the DB.
var categories;
var cat_count = document.getElementById("cat_count").value;
var i;
for(i=1; i<=cat_count; i++){
var cat_id = 'cat_'+i;
var cat = document.getElementById(''+cat_id+'').value;
categories += cat+',';
}
I have two issues with this:
First a category can be deleted so although there might be 3 categories these could have ID's like '1,3,5'. So my checkboxes will have these ID's but the JS is looking for '1,2,3' and it obviously gets an error when it is trying to get the value of a NULL element.
Second, if it can get the values, it will get all of the values of all checkboxes not just the ones that are checked which is what I need. Although if I get a way to loop through the ID's correctly this shouldn't be too difficult to but in a if checked condition.
Any suggestions or assistance with this would be greatly appreciated.

Here is a cleaner way to do this. You don't need cat_count; Add a class to your checkboxes, select all of them, get their value and append it to the categories variable; Working fiddle
var categories = "";
var checkboxes = Array.from(document.getElementsByClassName("checkbox"));
checkboxes.forEach(function(element, index) {
categories += element.value;
});

Id need to be unique so this line var cat_count = document.getElementById("cat_count").value; will always return a single element.
Change it by adding index to it
Instead of Id you can use name with
document.getElementsByName("'cat_$id'")

Thanks to #CBroe for getting there first, that worked for me.
var categories = '';
var category = document.getElementsByClassName("product_category");
var i;
for(i=0; i<category.length; i++){
if(category[i].checked == true){
var category_value = category[i].value;
categories += category_value+',';
}
}

Related

how to obtain the drop down selected option from a dynamic table

I am trying to extract selected option from a dynamically created table column. The code below works to extract the input values but not for the drop down values.
Dynamically generate HTML
$('#addr'+i).html("<td>"+ (i+1) +"</td><td><input name='Letter"+i+"' type='text' placeholder='Letter' class='form-control input-md' /> </td><td><input name='Start"+i+"' type='text' placeholder='Start' class='form-control input-md'></td><td><input name='End"+i+"' type='text' placeholder='End' class='form-control input-md'></td> <td> <select name='cars' id='cars'><option value='All'>All</option><option value='Even'>Even</option><option value='Odd'>Odd</option></select></td>");
javascript code
// start from the second row as the first one only contains the table's headers
for (let i = 1; i < targetTableRows.length; i++) {
var Inventorydict ={}
// loop over the contents of each row
for (let j = 0; j < targetTableRows[i].cells.length; j++) {
// something we could use to identify a given item
let currColumn = tableHeaders.cells[j].innerHTML;
// the current <td> element
let currData = targetTableRows[i].cells[j];
// the input field in the row
let currDataInput = currData.querySelector('input');
// is the current <td> element containing an input field? print its value.
// Otherwise, print whatever is insside
currDataInput ? console.log(`${currColumn}: ${currDataInput.value}`)
: console.log(`${currColumn}: ${currData.document.getElementById("addressType")}`);
if (currDataInput) {
Inventorydict[currColumn.replace(/\s/g, '')] = currDataInput.value;
} else {
Inventorydict[currColumn.replace(/\s/g, '')] = currData.innerHTML;
}
}
I use this to get the input values
let currDataInput = currData.querySelector('input');
I tried using this to get the selected option
let addresstype = currColumn.getElementById("addressType")
but it does not work. How can I obtain the drop down selected option ?
currColumn is being given a value in this point of your code:
let currColumn = tableHeaders.cells[j].innerHTML;
The innerHTML property returns a string, that's why you cannot use querySelector on it.
First of all, if you want to get the value of the select once every row, you should move that section outside of that inner cycle, that loops through each cell of that row.
Then, you will need to get a reference of the tr html element. This should be targetTableRows[i].
You can get your select element by using the querySelector on this element:
for (let i = 1; i < targetTableRows.length; i++) {
var Inventorydict ={}
// ...
let select = targetTableRows[i].querySelector("select");
let selectValue = select.value; // This will map to the "value" property of the selected option
}
However, please keep in mind that you should really select elements based on their class or input name, not by their type. Also, you should not assign the same id to multiple element of your page. This will help you avoid errors that will be hard to troubleshoot.

Javascript dynmaic table from filter

I first create the table layout(headers like this):
//DB Connection already established
$sql = "SHOW COLUMNS FROM fairtrade;";
$result = $dbConnection->query($sql);
if($result->num_rows > 0){
echo "<th> </th>";
while($row = $result->tech_assoc()){
echo "<th>" . $row['Field'] . "</th>";
}
}
This works just fine. And then i fill the table with the data.(It's a huge table, thats why i will only give a short example):
//DB Connection already established
$sql = "SELECT * FROM fairtrade;";
$result = $dbConnection->query($sql);
if($result->num_rows > 0 ){
while($row = $result->fetch_assoc()){
//use div to be able to resize the cells
echo "<tr><td><div class="tablediv">" . $row['ID'] . "</div></td>
<td><div class=tablediv>" . $row['Gender'] . "</div></td></tr>";
}
}
So this works just fine aswell. I got a <select id=filter_for> and an <input type=text id=filter_value> and javascript is doing the filtering like this:
function myFunction() {
// Declare variables
var input, filter, table, tr, td, i,countert,counterval;
input = document.getElementById("filter_value");
filter = input.value.toUpperCase();
table = document.getElementById("fairtrade_table");
tr = table.getElementsByTagName("tr");
countert = document.getElementById("filter_for");
counterval = countert.options[countert.selectedIndex].value;
// Loop through all table rows, and hide those who don't match the search query
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[counterval];
if (td) {
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
This again, works fine. And depending on the selected value from the <select> it searches the column for that specific value.
So. How could I change this filter?
I want to be able to search for multiple things.
For example, you have a table with four Columns [ID][GENDER][LASTNAME][NAME]. If someone selected multiple values (for example 2) [GENDER] and [NAME]. The filter searches in both columns. Where the values are separated by ",". So my input would look like this: "Male, George". This should give me all the information about every Male who's name is George.
Second question.
Is it possible to change this filter or add a new one for the table head? Let's take the example from above, four columns. But now we only want the as the criteria (because the select has all values from the table head). So the select has the values ID, Gender, Lastname, Name. If I select ID then I only see the ID Column(BUT ALL ROWS), if I select ID and GENDER then both of these columns are shown with all rows. How is this possible?
Anything i found when googling "Javascript table filter" were one value filters.
Thanks for your time.

Get ids of checked check boxes in a form using pure javascript

I have a table- each row has a checkbox of name checkBoxDelete. The id of the check box is unique(used the customer id).
I would like to get all the unique ids that were selected. So, I started by gathering all the elements of the form. Then check if it is a checkbox that is checked. If it is ,then get it's id.
var elLength = document.deleteForm.elements.length;
for (var i=0; i<elLength; i++){
var type = deleteForm.elements[i].type;
if (type=="checkbox" && deleteForm.elements[i].checked){
var rowID=deleteForm.elements[i].id;
checkedIds += rowID + ";" ;
count++;
}
}
However, rowID is always ";".
I believe I am not getting a reference to the checkbox correctly.
Change this var rowID=deleteForm.elements[i].id; to var rowID= document.deleteForm.elements[i].id;
You forgot document before selecting deleteForm

PHP: Shouldn´t $array[] = $x; add a new array item?

I have this script where I generate dynamically with javascript a bunch of text inputs.
After that I want to iterate between then in order to sum it´s contents and do a calculation.
The result of each iteration should be added to the end of an array. I don´t know why, but the array contents seems to be replaced every time the loop starts again, and it should add the new element created by the loop instead. But the only content it takes is the first one, and not the last one added.
Here´s the sample,
$totalCeldas = strip_tags($_POST['totalCeldas']);
$mesesTotales = array();
for ($vuelta=1; $vuelta<$totalCeldas; $vuelta++) {
$mes = 'mes'.$vuelta;
$anio = 'yr'.$vuelta;
$exp = 'exp'.$vuelta;
$valorMes = strip_tags($_POST[$mes]);
$valorAnio = strip_tags($_POST[$anio]);
$x = (($tYear - $valorAnio ) * 12) + ($tMonth- $valorMes);
$mesesTotales[] = $x;
echo '$valorAnio '.$valorAnio.'<br>';
echo '$valorMes '.$valorMes.'<br>';
//I´ve tried printing out each iteration in order to get to the problem, but it only prints out the first value.
foreach($mesesTotales as $valor){
echo 'El valor es '.$valor.'<br>';
}
I´ve also tried array_push, with the same result: It grabs only the result in the first iteration.
This is how the fields gets generated in Javascript:
function generarTabla1() {
var cant = document.forms["generar-tabla"]["cantMeses"].value;
if (cant && !isNaN(cant)) {
for ($i=0; $i<cant; $i++) {
var e = 0;
var celdaMes = " Mes <input style='width:5%;' type='text' name='mes"+($i+1)+"'> ";
var celdaYr = " Año <input style='width:8%;' type='text' name='yr"+($i+1)+"'> ";
var celdaExp = " Expensa $<input style='width:15%;' type='text' name='exp"+($i+1)+"'>
<br>";
$('#output').append(celdaMes, celdaYr, celdaExp); //agregamos las celdas necesarias
}
I rather answer this than deleting the question, in case someone else have the same silly issue:
Yes, the for loop has an issue: It should say lees or equal than, and not only less than.
So this:
for ($vuelta=1; $vuelta<$totalCeldas; $vuelta++) {
Changed for this:
for ($vuelta=1; $vuelta<=$totalCeldas; $vuelta++) {
worked.
I know, it´s silly, but I didn´t feel that was right to delete the question or let it go unanswered.

Append a header to dynamically-loaded tables using JQuery

I've been having a hard time trying to append new headers to tables I build dynamically using data grabbed from an AJAX call.
I've already asked here a question about my problem, but it seems that there's no logical answer to it.
So my problem is that I can't actually get the table I want to append my new info to, what I tired was this:
console.log(id); //This prints the right id!
//THIS is not working...
$('#'+id+' tr:first').append("<td>Well "+(wellCounter)+"</td>");
//...
//$('#'+401+' tr:first').append("<td>Well "+(wellCounter)+"</td>");--this will work
table+="<td>M "+fourthLevel.male+"</td>";
table+="<td>H "+fourthLevel.herm+"</td>";
But it didn't work, so I was wondering if you can help me with another way to get the same functionality without using the id to get the table. Maybe the closest function will work but I don't have experience with that, and I tried it but failed.
Here the full code:
$.each(data, function(index, firstLevel) {
$.each(firstLevel, function(index2, secondLevel) {
var id = firstLevel['id'];
var author = firstLevel['author'];
var date = firstLevel['date'];
var experimental_conditions = firstLevel['experimental_conditions'];
if(index2 == 'items'){
var table = '<div class=tableWrapper><table id=\"'+id+'\" class=\"experimentTable\">';
table += '<input id=\"basketButton\" type=\"submit\" value=\"Add to basket\" class=\"basketButton\" experimentBatch=\"'+id+'\"> <div class="superHeader"><span class=\"superHeader\">Date: '+date+', By '+author+'</span><br /><span class=\"subHeader\">Experimental conditions: '+experimental_conditions+'</span>'
table += '<tr><td></td><td COLSPAN=2>Totals</td></tr>';
table += '<tr id="header"><td width="20%">Genotype</td><td width="10%"><img src="images/herma.png"></td><td width="10%"><img src="images/male.png"></td>';
//for each table
$.each(secondLevel, function(index3, thirdLevel) {
var nWells = 0;
table += "<tr><td>"+thirdLevel['mutant_name_c']+"</td><td>"+thirdLevel['herm_total']+"</td><td>"+thirdLevel['male_total']+"</td>";
currentRow = 3;
wellCounter = 0;
//for each row
$.each(thirdLevel, function(index4, fourthLevel) {
wellCounter++;
if (fourthLevel.date_r != undefined){
console.log(id);
//THIS is not working...
$('#'+id+' tr:first').append("<td>Well "+(wellCounter)+"</td>");
//...
table+="<td>M "+fourthLevel.male+"</td>";
table+="<td>H "+fourthLevel.herm+"</td>";
}
});
});
table +='</table></div>'
$('#searchResults').append(table);
}
});
});
NOTE: Male and herm are worm genders, not options!
I didn't go through your code, but when I'm working with dynamic table in jquery i try with Jquery "OBJECT". something like
var $tbl = $('<table />'), $tr=$('<tr />'), $td=$('<td />');
then you can add attr, append etc, and is much easier to read, and manipulate.
$tbl.attr('id',id).append($tr.append($td);
etc.

Categories

Resources