I'm building an app and on this app I have to add items on a table, and I would like to add a checkbox on each line that I add, but I'm having troubles on trying to do that.
Would you know how to add a checkbox on each line that I add on the table?
below is the code where I add line per line to my table
function addDataToTbody(nl, data) { // nl -> NodeList, data -> array with objects
data.forEach((d, i) => {
var tr = nl.insertRow(i);
Object.keys(d).forEach((k, j) => { // Keys from object represent th.innerHTML
var cell = tr.insertCell(j);
cell.innerHTML = d[k]; // Assign object values to cells
});
nl.appendChild(tr);
})
}
I tried to do something like
tr.append("<td> <div class='form-control'>\
<input type='checkbox' /> \
<label for='chk'/>select</div>\
</td>");
But that just adds a text to my table and not the checkbox itself.
<div id="table-wrapper" class="table-responsive">
<table class="table table-hover" id="PartData">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">FUNÇÃO</th>
<th scope="col">DESCRIÇÃO</th>
<th scope="col">QUANTIDADE</th>
<th scope="col">FABRICANTE DO PAINEL</th>
<th scope="col">PEÇA</th>
<th scope="col">REVISÃO</th>
</tr>
</thead>
<tbody>
<tr>
</tr>
</tbody>
</table>
</div>
above is my HTML code.
Thanks in advance!
As Teemu said in the comments, the solution was
"Create the cell in the loop like you've created the other cells. Then, instead of append, use insertAdjacentHTML to add the HTML for the button. Notice, that this has to be done after setting innerHTML, otherwise the said property overrides everything what was in the cell."
So that's my final function:
function addDataToTbody(nl, data) { // nl -> NodeList, data -> array with objects
data.forEach((d, i) => {
var tr = nl.insertRow(i);
//cell2.type = checkbox;
Object.keys(d).forEach((k, j) => { // Keys from object represent th.innerHTML
console.log(j)
var cell = tr.insertCell(j);
cell.innerHTML = d[k]; // Assign object values to cells
});
tr.insertAdjacentHTML('beforeEnd', "<td> <div class='form-control'>\
<input id = 'deleteChck' type='checkbox' /> \
<label for='chk'/>Delete</div>\
</td>");
nl.appendChild(tr);
})
}
And it works
Related
first I'm sorry if at some point I express myself badly, English is not my native language. I am developing an application in which the user sends 2 values through a form and in another page I use one of those data (string with comma separated options) to show a specific table and hide the others, and with the second data (Integer) I show one of the rows of that table.
What I already have:
I have the form and send the data through the Query String, I capture that data, I assign a variable to the integer and to the text string I separate it by commas and create an array.
URL Example: app.tables.example/?id=123&ops=option1%2c+option2
//Read parameters sent by form
const param = new Proxy(new URLSearchParams(window.location.search), {
get: (searchParams, prop) => searchParams.get(prop)
});
//Assign integer to a variable
let num = param.id;
//Assign options to a variable
let op = param.ops;
//Separate string with commas
let opsplit = op.split(',');
Up to here everything is perfect, I can print all the variables without any problem, now I need to compare the array with the id of each table, show the one that corresponds and hide the others. (The id of the tables is the same that user passes with the text string).
The tables look something like this:
<div id="option1" class="table-1">
<table width="100%">
<thead>
<tr>
<th align="left">Option1</th>
<th align="left">Integer</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">Number</td>
<td align="left">Info</td>
</tr>
<tr>
<td align="left">1</td>
<td align="left">textblock</td>
</tr>
<tr>
<td align="left">2</td>
<td align="left">textblock</td>
</tr>
</tbody>
</table>
</div>
//As you can see the id of each table corresponds to what the user chose
<div id="option2" class="table-1">
<table width="100%">
<thead>
<tr>
<th align="left">Option2</th>
<th align="left">Integer</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">Number</td>
<td align="left">Info</td>
</tr>
<tr>
<td align="left">1</td>
<td align="left">textblock</td>
</tr>
<tr>
<td align="left">2</td>
<td align="left">textblock</td>
</tr>
</tbody>
</table>
</div>
The problem:
I'm supposed to use the array elements in a "for" loop and compare them with the id of each table, then show that table and hide others, but I don't know exactly how to do it.
function myFunction() {
var input, filter, table, tr, td, i, y, txtValue;
for (r = 0; r<opsplit.length; r++){
input = opsplit[r];
filter = function(x){
return x.toUpperCase();
};
opsplit = opsplit.map(filter);
}
//When I test this, it does not return any value,
//innerHTML error
for(y = 0; y<opsplit.length; y++){
table = document.getElementById(opsplit[y]).innerHTML;
//I use this section to test, it should show me the row,
//but since the previous loop failed, it does nothing.
// What I really need is to show the whole
// table where this data is located and hide the other tables.
tr = table.getElementsByTagName("tr");
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[0];
if (td) {
txtValue = td.textContent || td.innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
}
myFunction();
I am really stuck at the moment and would appreciate any help. What is the correct way to use the string array, and how can I hide the tables that the user does not need?
Ok, thanks to those who took the time to write a comment, but I found the solution, I had to convert the form data to a string and an integer. Then I was able to compare that string to the classes id. I am writing the answer in case anyone finds it useful.
//Read parameters sent by form
const param = new Proxy(new URLSearchParams(window.location.search), {
get: (searchParams, prop) => searchParams.get(prop)
});
//Assign number to a variable
let num = param.id;
//Convert to integer
let numint = parseInt(num);
//Assign options to a variable
let op = param.ops;
//Convert to String
let opstr = op.string();
//Separate string with commas
let opsplitstr = opstr.split(',');
//Assign class to a variable
tableclass = document.getElementsByClassName('table-1');
//Compare table class ids with string array
if (opsplitstr[0] == tableclass[0].id{
}
//We need a loop if we need compare all elements
TLDR: The URL does not send information about the data type, so I had to read it and convert it according to my need.
I have a web app, frontend using HTML5, backend using Django.
I the JavaScript part I dynamically create the table header based on user selection in the previous page. But when I tried to set the data-field attribute to load the data dynamically, it could not work. although there's no error in F12 dev tool, the data could not shown in the table (I checked in dev tool, the data-field is there but no data shown in frontend. The first fixed one , course dose shown).
<table id="thisTable" contenteditable='true' class="table table-bordered table-sm" width="100%" cellspacing="0" style="font-size: 1.0rem;"
id="bk-table"
data-toggle="table"
data-toolbar="#toolbar"
data-cookie="true"
data-cookie-id-table="materialId"
data-show-columns="true"
data-show-refresh="true"
data-show-fullscreen="true"
data-show-export="true"
data-height="650"
{# data-sticky-header="true"#}
{# data-sticky-header-offset-left="7em"#}
{# data-sticky-header-offset-right="7em"#}
data-click-to-select="true"
data-id-field="id"
data-show-footer="true"
data-url="/api/materials/"
data-query-params="queryParams"
data-remember-order="true"
data-pagination="true"
data-side-pagination="server"
data-total-field="count"
data-data-field="results">
<thead class="thead-dark" >
<tr contenteditable='true'>
<!--th data-sortable="true" >ID</th-->
<th data-field="courseCode" data-sortable="true" data-formatter="renderCourse"></th>
</tr>
</thead>
</table>
<script>
const eText_iBookStore = ['Course Code', 'Course Material Title', 'eISBN/VBID', 'iSBN']
function queryParams(params) {
params['limit'] = localStorage['Format'];
params['discipline'] = localStorage['discipline'];
params['Add_Information'] = localStorage['Add_Information'];
if (params['Add_Information'] == "eText_iBookStore")
{
//document.getElementsByTagName("th")[0].setAttribute("data-field", "id");
//document.getElementsByTagName("th")[1].setAttribute("data-field", "courseCode");
//document.getElementsByTagName("th")[3].setAttribute("data-field", "book.isbn");
for (i=0;i<eText_iBookStore.length;i++)
{
var tr = document.getElementById('thisTable').tHead.children[0],
th = document.createElement('th');
tr.appendChild(th);
}
$( "table thead tr th" ).each(function( index ) {
$( this ).text(eText_iBookStore[index]);
console.log(eText_iBookStore[index]);
console.log( index + ": " + $( this ).text() );
});
document.getElementsByTagName("th")[2].setAttribute("data-field", "book.title");
} }</script>
The data-field attribute dynamically loaded in js does not work like that added in HTML, (the former could not load data )
the code is working well and adding the attribute but you are creating unnecessary loop inside the loop of eText_iBookStore so i remove .each loop and added the array element directly
because i haven't something like your code inside my localStorage i just set a value to them and created the eText_iBookStore array
function queryParams(params) {
params['limit'] = "data"
params['discipline'] = "data"
params['Add_Information'] = "eText_iBookStore"
var eText_iBookStore = [1,2,3,4]
if (params['Add_Information'] == "eText_iBookStore") {
for (var i = 0;i < eText_iBookStore.length; i++) {
var tr = document.getElementById('thisTable').tHead.children[0],
th = document.createElement('th');
th.innerText = eText_iBookStore[i];
tr.appendChild(th);
}
document.getElementsByTagName("th")[2].setAttribute("data-field", "book.title");
}
}
queryParams({})
I have a table element defined below as $table. I am trying to run a function on every cell a specific column that is defined by a specific table heading - qc_statusTh. I have found the index of that table heading (qc_statusColumnIndex) and have been able to grab the next table cell in that column - qc_statusCell.
However, I am not able to loop through the table cells and run a function on each table cell in that column.
Here is the JavaScript code I have so far:
$(document).ready(function() {
var $table = $("table.tables.list");
if ($table.length > 0) {
var qc_statusTh = $("th.headersub:contains('qc_status')");
var qc_statusColumnIndex = $(qc_statusTh).index();
var qc_statusCell = $($table).find("td").eq(qc_statusColumnIndex);
// this does not work. this only replaces the first cell
// in the row after qc_statusTh with "TESTING"
$(qc_statusCell).each(function() {
$(this).replaceWith("TESTING");
});
}
});
How can I edit this code to loop through each cell in the table that has an equal index to qc_statusColumnIndex?
If you think about it, you really want to iterate (using each) over the rows of the table, not the cells. If you do that, you can then grab the nth td element from each row and apply your transformation.
$(document).ready(function() {
var $table = $("table.tables.list");
if ($table.length > 0) {
var qc_statusTh = $("th.headersub:contains('qc_status')");
var qc_statusColumnIndex = $(qc_statusTh).index();
var qc_rows = $($table).find('tr');
$(qc_rows).each(function() {
$(this).find('td').eq(qc_statusColumnIndex).replaceWith("TESTING");
});
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="tables list">
<thead>
<th class="headersub">qc_example</th>
<th class="headersub">qc_status</th>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Ok</td>
</tr>
<tr>
<td>2</td>
<td>Ok</td>
</tr>
<tr>
<td>3</td>
<td>Error</td>
</tr>
</tbody>
</table>
I am trying to filter the rows of a table to display the results of entered text in the search bar. The code below does the job but for some reason filters the column headings as well.
$('#search').keyup(function () {
var data = this.value.split(" ");
var rows = $(".Info").find("tr").hide();
if(this.value ==""){
rows.show();
return;
}
rows.hide();
rows.filter(function(i,v){
var t = $(this);
for (var d = 0; d < data.length; d++) {
if (t.is(":Contains('" + data[d] + "')")) {
return true;
}
}
return false;
}).show();
});
HTML
<input type = "search" name = "search" id = "search">
<table style ="width:95%" class = "Info">
<tr>
<th>Select </th>
<th>Name</th>
<th>Number</th>
<th>Date</th>
</tr>
</table>
The user adds rows which is why i haven't written any HTML for it.
Any help would be appreciated. Thanks in advance
http://jsfiddle.net/szjhngwm/
It looks like you need to filter using tbody
<table style ="width:95%" class = "Info">
<thead>
<tr>
<th>Select </th>
<th>Name</th>
<th>Number</th>
<th>Date</th>
</tr>
<thead>
<tbody>
</tbody>
</table>
var rows = $(".Info tbody tr").hide();
Another way to do this would be to use jQuery's :gt() selector.
The only thing that would change is this line:
var rows = $(".Info").find("tr:gt(0)").hide();
Notice the addition of :gt(0) to your tr.
This is a function that, when passed a table as an argument, applies a different style color to alternating rows to improve readability. i.e. first row is dark grey, second row is light grow, third row is dark grey etc.
As mentioned, it gets passed the whole table as an argument. None of the rows have ids. Starting at this line var aTBODY = oTable.getElementsByTagName("tbody");, I understand what is happening. Namely, it gets the table body and then all the rows within it and stripes them alternately.
1) But what is happening exactly in the first five lines of the program? The comments don't explain it clearly for me.
2) does looping over a table length (i.e idArray.length) create an array of rows? what is happening with var id = idArray[indx]; ?
3) When it says, in the comments, get the table that corresponds to this id, using the code var oTable = document.getElementById(id) why is this a necessary step? what is happening?
thank you if you can explain
function createStripedTable(idArray) {
// for each table ID that we're given, stripe all the rows.
for (var indx = 0; indx < idArray.length; indx++) {
var id = idArray[indx];
// get the table that corresponds to this ID
var oTable = document.getElementById(id);
if (oTable == null)
return;
// get its table body, which contains all the TR tags
var aTBODY = oTable.getElementsByTagName("tbody");
// set the CSS class for each one of the TR tags
for (var i = 0; i < aTBODY.length; i++) {
// get an array of all the TR tags in the TBODY
var aTR = aTBODY[i].getElementsByTagName("tr");
for (var j = 0; j < aTR.length; j++) {
// the % operator divides the given number by another
// and returns the remainder. This is how we alternate the
// rows.
aTR[j].className = (j % 2 == 1) ? "stripe1" : "stripe2";
}
}
}
}
Here's the code that's calling it.
function() {createStripedTable(new Array("MSFTQuotes"))
Here's an excerpt of the one and only one table that is passed.
<body>
<table id="MSFTQuotes">
<thead>
<tr>
<th colspan="7" align="center">
<span class="TableTitle">Stock Activity for Aug 5, 2008 - Nov 5, 2008 </span>
</th>
</tr>
<tr>
<th align="center" width="14%">
<div align="right" class="style5">
Date</div>
</th>
<th align="center" width="14%">
<div align="right" class="style5">
Open</div>
</th>
<th align="center" width="14%">
<div align="right" class="style5">
High</div>
</th>
<th align="center" width="14%">
<div align="right" class="style5">
Low</div>
</th>
<th align="center" width="14%">
<div align="right" class="style5">
Close</div>
</th>
<th align="center" width="14%">
<div align="right" class="style5">
Volume</div>
</th>
<th align="center" width="14%">
<div align="right" class="style5">
Adj Close</div>
</th>
</tr>
</thead>
<tbody>
<tr>
<td align="right">
5-Nov-08
</td>
<td align="right">
29.21
</td>
<td align="right">
29.36
</td>
<td align="right">
29.03
</td>
<td align="right">
29.31
</td>
<td align="right">
95,337,696
</td>
<td align="right">
29.31
</td>
The function accepts an array of id values corresponding to table elements. It loops through those IDs and does its striping work on all of the tbody elements within the tables.
Somewhat more annotated (see TJC:s):
function createStripedTable(idArray) {
// for each table ID that we're given, stripe all the rows.
// TJC: Loop through all of the IDs in the given array
for (var indx = 0; indx < idArray.length; indx++) {
// TJC: Get the ID value for index `indx` in the array
var id = idArray[indx];
// get the table that corresponds to this ID
var oTable = document.getElementById(id);
if (oTable == null) // TJC: Invalid ID, ignore it
return;
// get its table body, which contains all the TR tags
// TJC: Get the `tbody`s under the table. One table
// can have multiple `tbody` elements.
var aTBODY = oTable.getElementsByTagName("tbody");
// set the CSS class for each one of the TR tags
for (var i = 0; i < aTBODY.length; i++) {
// get an array of all the TR tags in the TBODY
// TJC: It's actually a NodeList, but you can largely
// treat it as an array
var aTR = aTBODY[i].getElementsByTagName("tr");
for (var j = 0; j < aTR.length; j++) {
// the % operator divides the given number by another
// and returns the remainder. This is how we alternate the
// rows.
aTR[j].className = (j % 2 == 1) ? "stripe1" : "stripe2";
}
}
}
}
The good news is that IE9 finally supports the nth-child pseudo-class, so someday you'll be able to stop doing this with code.
idArray is an array of all IDS for more than one table. This function will change the alternate rows for each of the tables whose id is in idArray.
The outer loop is iterating through ids. The first five lines inside the loop are assuming they are ids of tables, and fetching the contents of the table element corresponding to each ID.
The next five lines in the loop then fetch the table body contents and change the css class of alternate rows.
Add these lines before the first for loop in the code
var tabarray=new Array();
tabarray.push(thetableidYoupassed);
idArray=tabArray
'thetableidYoupassed' is the actual argument with which you called the function 'createStripedTable'
Keep the rest of the code as it is...This should work fine...
Your method accepts an array of table IDs. So all the tables need to have IDs.
function createStripedTable(idArray) { //idArray is an array of table IDs
Then it loops through them and gets the ID one by one
for (var indx = 0; indx < idArray.length; indx++) {
var id = idArray[indx]; //this is the ID of a table
Then it checks whether the table actually exists in the DOM or not
var oTable = document.getElementById(id); //IF the table with a matching ID is not found, you get NULL
if (oTable == null)
return; //no table that matches the ID? return
Ideally, that line should be continue or something similar. Because in this instance. If you pass your method an array like ['table1', 'table2', 'faketable', 'table3'], your method won't strip table3 because it never gets there in the array (because of the return)