Filtering html table (JS) - javascript

I have an html table in my view that I want to filter with multiple filters. In this case, I have 3 filters, but I can have much more.
Here is a little part of the code, to show the problem
$(document).ready(function () {
$('#datefilterfrom').on("change", filterRows);
$('#datefilterto').on("change", filterRows);
$('#projectfilter').on("change", filterProject);
});
function filterRows() {
var from = $('#datefilterfrom').val();
var to = $('#datefilterto').val();
if (!from && !to) { // no value for from and to
return;
}
from = from || '1970-01-01'; // default from to a old date if it is not set
to = to || '2999-12-31';
var dateFrom = moment(from);
var dateTo = moment(to);
$('#testTable tr').each(function (i, tr) {
var val = $(tr).find("td:nth-child(2)").text();
var dateVal = moment(val, "DD/MM/YYYY");
var visible = (dateVal.isBetween(dateFrom, dateTo, null, [])) ? "" : "none"; // [] for inclusive
$(tr).css('display', visible);
});
}
function filterProject() {
var contentToColor = {
"Заявка отменена": "#9900ff",
"Подтверждено менеджером Vchasno": "green",
"Отменено менеджером Vchasno": "#9900ff",
"Отклонено региональным менеджером": "#9900ff",
"Подтверждено региональным менеджером": "red"
};
var project = this.value;
var filter, table, tr, td, i;
filter = project.toUpperCase();
table = document.getElementById("testTable");
tr = table.getElementsByTagName("tr");
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[2];
if (td) {
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://rawgit.com/moment/moment/2.2.1/min/moment.min.js"></script>
<div class="row">
<div class="col-md-3">
<h4>Дата з</h4>
<input type="date" class="form-control" id="datefilterfrom" data-date-split-input="true">
</div>
<div class="col-md-3">
<h4>Дата до</h4>
<input type="date" class="form-control" id="datefilterto" data-date-split-input="true">
</div>
<div class="col-md-2">
<h4>Проект</h4>
<select id="projectfilter" name="projectfilter" class="form-control"><option value="1">Тестовый проект</option><option value="2">Тест2</option></select>
</div>
</div>
<table id="testTable" class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Дата</th>
<th scope="col">Проект</th>
</tr>
</thead>
<tbody id="report">
<tr>
<td class="proposalId">9</td><td> 17/07/2018</td> <td> Тестовый проект</td>
</tr>
<tr><td class="proposalId">8</td><td> 18/07/2018</td><td> Тестовый проект</td></tr>
<tr><td class="proposalId">7</td><td> 17/07/2018</td><td> Тест2</td></tr>
<tr style=""><td class="proposalId">3</td><td> 19/07/2018</td><td> Тест2</td></tr>
</tbody>
</table>
Here is the full working snippet
https://codepen.io/suhomlineugene/pen/JBBGXa
When I set date filter it filters table great, but when I set the second filter it gets data from the table that I have unfiltered.
Where is my problem?
Thank's for help!

the problem was filter = project.toUpperCase() is returning 1 or 2. I updated the logic to get the innerHTML and the do compare. Here is the modified code
function filterProject() {
var contentToColor = {
"Заявка отменена": "#9900ff",
"Подтверждено менеджером Vchasno": "green",
"Отменено менеджером Vchasno": "#9900ff",
"Отклонено региональным менеджером": "#9900ff",
"Подтверждено региональным менеджером": "red"
};
let dumb = this.options.selectedIndex;
dumb = this.options[dumb].innerHTML;
console.log(dumb);
var filter, table, tr, td, i;
filter = dumb.toUpperCase();
table = document.getElementById("testTable");
tr = table.getElementsByTagName("tr");
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[2];
if (td) {
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "table-row";
} else {
tr[i].style.display = "none";
}
}
}
}
Code pen link here

When you do filterProject(), check if you have already filtered out the rows you are iterating over:
....
for (i = 0; i < tr.length; i++) {
if(tr[i].style.display !== 'none'){
...
Here's a working codepen:
https://codepen.io/anon/pen/NBBxad

HTML
<input type="text" id="input_id" onkeyup="tableSearch('id', 'table', 0)">
Javascript
function tableSearch(input_id, table_id, col) {
var input, filter, table, tr, td, i;
input = document.getElementById(input_id);
filter = input.value.toUpperCase();
table = document.getElementById(table_id);
tr = table.getElementsByTagName('tr');
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName('td')[col];
if (td) {
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}

Related

Selecting elements from filter table

I have the following code to create a table of employees which allows me to filter through them based on a query term:
I want to add html buttons that would be included along with the employee in the table so I can add a
<button onclick="myFunction()">Click me</button>
which would allow me to then create and add employees to a new list of selected employees Image of elements I want to add I am not sure if this is possible to do so I'm asking for some help here. Alternatively, if it is not possible to add this HTML element into the table how would I go about modifying the code so if I clicked on a row of the filtered table it would allow me to select that row and then add it to the new list of selected employees.
Thanks so much!
<style>
th{
cursor: pointer;
color:#fff;
}
</style>
<div class="row">
<div class ="col">
<div class="card card-body">
<input id="search-input" class="form-control" type="text">
</div>
</div>
</div>
<table class="table table-striped">
<tr class="bg-info">
<th class="bg-info" data-colname="name" data-order="desc">Name &#9650</th>
<th data-colname="age" data-order="desc">Age &#9650</th>
<th data-colname="birthdate" data-order="desc">Birthday &#9650</th>
</tr>
<tbody id="myTable">
</tbody>
</table>
<script>
var myArray = [
{'name':'Michael', 'age':'30', 'birthdate':'11/10/1989'},
{'name':'Mila', 'age':'32', 'birthdate':'10/1/1989'},
{'name':'Paul', 'age':'29', 'birthdate':'10/14/1990'},
{'name':'Dennis', 'age':'25', 'birthdate':'11/29/1993'},
{'name':'Tim', 'age':'27', 'birthdate':'3/12/1991'},
{'name':'Erik', 'age':'24', 'birthdate':'10/31/1995'},
]
$('#search-input').on('keyup', function(){
var value= $(this).val()
console.log('value:', value)
var data = searchTable(value, myArray)
buildTable(data)
})
buildTable(myArray)
function searchTable(value, data){
var filteredData = []
for (var i = 0; i < data.length; i++){
value = value.toLowerCase()
var name = data[i].name.toLowerCase()
var age = data[i].age.toLowerCase()
var birthdate = data[i].age.toLowerCase()
if(name.includes(value)){
filteredData.push(data[i])
}
else if(age.includes(value)){
filteredData.push(data[i])
}
else if(birthdate.includes(value)){
filteredData.push(data[i])
}
}
return filteredData
}
$('th').on('click', function(){
var column = $(this).data('colname')
var order = $(this).data('order')
var text = $(this).html()
text = text.substring(0, text.length - 1);
if (order == 'desc'){
myArray = myArray.sort((a, b) => a[column] > b[column] ? 1 : -1)
$(this).data("order","asc");
text += '&#9660'
}else{
myArray = myArray.sort((a, b) => a[column] < b[column] ? 1 : -1)
$(this).data("order","desc");
text += '&#9650'
}
$(this).html(text)
buildTable(myArray)
})
function buildTable(data){
var table = document.getElementById('myTable')
table.innerHTML = ''
for (var i = 0; i < data.length; i++){
var colname = `name-${i}`
var colage = `age-${i}`
var colbirth = `birth-${i}`
var row = `<tr>
<td>${data[i].name}</td>
<td>${data[i].age}</td>
<td>${data[i].birthdate}</td>
</tr>`
table.innerHTML += row
}
}
</script>

Is there a way to implement on keyup event except one key?

I'm trying to develop a Javascript function that do some verification every time an input change (I'm using onkeyup event) except when we delete what we enter inside the input. Here is my actual code:
function myFunction() {
var input, filter, table, tr, td, i;
var cpt = 0;
var nbRow = 0;
input = document.getElementById("filterInput");
filter = input.value.toUpperCase();
table = document.getElementById("test");
thead = table.getElementsByTagName("tbody");
tr = table.getElementsByTagName("tr");
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[2];
if (td) {
nbRow = nbRow + 1;
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
cpt = cpt + 1;
}
}
}
if (nbRow == cpt) {
alert("The list is empty")
}
}
<input id="filterInput" onkeyup="myFunction()">
<table id="test">
<thead>
<tr>
<th>Titre1</th>
<th>Titre2</th>
<th>Titre3</th>
</tr>
</thead>
<tbody>
<tr>
<td>contenu1</td>
<td>contenu2</td>
<td>contenu3</td>
</tr>
</tbody>
</table>
How can I avoid a repetitive alert show everytime a user deletes one character?
EDIT :
I'm trying to avoid repetitive 'alert' without losing the verification after the user deletes one character.
If you want to ignore delete and backspace with onkeyup, you can add this check to the beginning of your function:
function myFunction(event) {
// capture what key was pressed
var key = event.keyCode || event.charCode;
if( key === 8 || key === 46 )
return; //if it's del or backspace, exit the function
// continue your function here
}
You can implement a validation in the function detecting which key was pressed...
function myFunction(e) {
if(e.keyCode !== 8){ // back key excluded
var input, filter, table, tr, td, i;
var cpt = 0;
var nbRow = 0;
input = document.getElementById("filterInput");
filter = input.value.toUpperCase();
table = document.getElementById("test");
thead = table.getElementsByTagName("tbody");
tr = table.getElementsByTagName("tr");
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[2];
if (td) {
nbRow = nbRow + 1;
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
cpt = cpt + 1;
}
}
}
if (nbRow == cpt) {
alert("The list is empty")
}
}
}
<input id="filterInput" onkeyup="myFunction(event)">
<table id="test">
<thead>
<tr>
<th>Titre1</th>
<th>Titre2</th>
<th>Titre3</th>
</tr>
</thead>
<tbody>
<tr>
<td>contenu1</td>
<td>contenu2</td>
<td>contenu3</td>
</tr>
</tbody>
</table>
Of course you would have to add the code for every key you want to exclude

How to make a double select filter?

i'm missing something on this code, my goal is to make 2 filter on this table, the select with id="myInput" must be the one who determine the appearing of the table and apply the first filter,that's the js:
function myFunction() {
// Declare variables
var input, filter, table, tr, td, i;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
table.style.display = '';
// 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")[0];
if (td) {
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
The second one (id="myInput2") should apply an additional filter, hiding the rows who dont match with another column,here's the js:
function myFunction2() {
// Declare variables
var input, filter, table, tr, td, i;
input = document.getElementById("myInput2");
filter = input.value.toUpperCase();
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
// 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")[5];
if (td) {
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
That's the html code (forget about br and other bad things, i'm just making an integration of existing code)
<label>Zona</label> <select id="myInput2" onchange="myFunction2()">
<option value="">Tutte le zone</option>
</select> <label>Gruppo</label>
<select id="myInput" onchange="myFunction()">
<option value="">Seleziona un gruppo di categoria</option>
</select> <br>
<br>
<table id="myTable" style="display: none;">
<tr class="header">
<th>Categoria</th>
<th>Descrizione</th>
<th>Classe</th>
<th>Tariffa</th>
<th>Zona</th>
</tr>
<c:forEach var="infoSezioni" items="${outParamInfoSezioni}">
<tr>
<td style="display:none;">${infoSezioni.gruppo}</td>
<td>${infoSezioni.categoria}</td>
<td>${infoSezioni.descr}</td>
<td>${infoSezioni.classe}</td>
<td>${infoSezioni.tariffa}</td>
<td>${infoSezioni.zonaCens}</td>
</tr>
</c:forEach>
</table>
the problem is that:
When i apply 1 of this filters, the other one just doesnt work, how i can fix that?
please review this one
in both filter one and two
//apply filter + checking flag
if (td.innerHTML.toUpperCase().indexOf(filter) < 0 && (!tr[i].dataset.filtered)) {
tr[i].style.display = "none";
//giving flag
tr[i].dataset.filtered = true;
}
Displaying Table when either input1 & input2 has value:
// and myFunction2() as well
function myFunction() {
// Declare variables
var input, filter, table, tr, td, i;
input = document.getElementById("myInput");
//remove unnecessary space
filter = input.value.trim().toUpperCase();
//return if no value
if(filter.length > 0) {return;}
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
//displaying table
table.style.display = 'block';
...

searching text within Html table

I just googling to find a script that I can use to find a text within HTML table.
Like I create a table of student names which have many columns and rows. I have a good script too that display whatever I try to search but it display full row...
function searchSname() {
var input, filter, found, table, tr, td, i, j;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td");
for (j = 0; j < td.length; j++) {
if (td[j].innerHTML.toUpperCase().indexOf(filter) > -1) {
found = true;
}
}
if (found) {
tr[i].style.display = "";
found = false;
} else {
tr[i].style.display = "none";
}
}
}
<input id='myInput' onkeyup='searchSname()' type='text'>
<table id='myTable'>
<tr>
<td>AB</td>
<td>BC</td>
</tr>
<tr>
<td>CD</td>
<td>DE</td>
</tr>
<tr>
<td>EF</td>
<td>GH</td>
</tr>
</table>
But know I am looking for making some changes to display exact text whatever I searched instead of full row like it will display text that I type to search and hide other unmatched fully....
Kindly let me know is it possible to display text only that I type to search within a table? Like if I try to find student name "AB" then it should display AB only instead of "AB BC".
This is much simpler than you are making it.
var cells = document.querySelectorAll("#myTable td");
var search = document.getElementById("myInput");
search.addEventListener("keyup", function(){
for(var i = 0; i < cells.length; ++i){
// This line checks for an exact match in a cell against what the
// user entered in the search box
//if(cells[i].textContent.toLowerCase() === search.value.toLowerCase()){
// This checks for cells that start with what the user has entered
if(cells[i].textContent.toLowerCase().indexOf(search.value.toLowerCase()) === 0){
cells.forEach(function(element){
element.style.display = "none";
});
cells[i].style.background = "yellow";
cells[i].style.display = "table-cell";
break;
} else {
cells[i].style.background = "white";
cells.forEach(function(element){
if(cells[i] !== element){
element.style.display = "table-cell";
}
});
}
}
});
table, td { border:1px solid black; border-collapse: collapse;}
<input id='myInput'>
<table id='myTable'>
<tr>
<td>AB</td>
<td>BC</td>
</tr>
<tr>
<td>CD</td>
<td>DE</td>
</tr>
<tr>
<td>EF</td>
<td>GH</td>
</tr>
</table>

Dynamic creation of table with DOM

Can someone tell me what's wrong with this code? I want to create a table with 2 columns and 3 rows, and in the cells I want Text1 and Text2 on every row. This code creates a table with 2 columns and 3 rows, but it's only text in the cells in the third row (the others are empty).
var tablearea = document.getElementById('tablearea');
var table = document.createElement('table');
var tr = [];
var td1 = document.createElement('td');
var td2 = document.createElement('td');
var text1 = document.createTextNode('Text1');
var text2 = document.createTextNode('Text2');
for (var i = 1; i < 4; i++){
tr[i] = document.createElement('tr');
for (var j = 1; j < 4; j++){
td1.appendChild(text1);
td2.appendChild(text2);
tr[i].appendChild(td1);
tr[i].appendChild(td2);
}
table.appendChild(tr[i]);
}
tablearea.appendChild(table);
You must create td and text nodes within loop. Your code creates only 2 td, so only 2 are visible. Example:
var table = document.createElement('table');
for (var i = 1; i < 4; i++){
var tr = document.createElement('tr');
var td1 = document.createElement('td');
var td2 = document.createElement('td');
var text1 = document.createTextNode('Text1');
var text2 = document.createTextNode('Text2');
td1.appendChild(text1);
td2.appendChild(text2);
tr.appendChild(td1);
tr.appendChild(td2);
table.appendChild(tr);
}
document.body.appendChild(table);
It is because you're only creating two td elements and 2 text nodes.
Creating all nodes in a loop
Recreate the nodes inside your loop:
var tablearea = document.getElementById('tablearea'),
table = document.createElement('table');
for (var i = 1; i < 4; i++) {
var tr = document.createElement('tr');
tr.appendChild( document.createElement('td') );
tr.appendChild( document.createElement('td') );
tr.cells[0].appendChild( document.createTextNode('Text1') )
tr.cells[1].appendChild( document.createTextNode('Text2') );
table.appendChild(tr);
}
tablearea.appendChild(table);
Creating then cloning in a loop
Create them beforehand, and clone them inside the loop:
var tablearea = document.getElementById('tablearea'),
table = document.createElement('table'),
tr = document.createElement('tr');
tr.appendChild( document.createElement('td') );
tr.appendChild( document.createElement('td') );
tr.cells[0].appendChild( document.createTextNode('Text1') )
tr.cells[1].appendChild( document.createTextNode('Text2') );
for (var i = 1; i < 4; i++) {
table.appendChild(tr.cloneNode( true ));
}
tablearea.appendChild(table);
Table factory with text string
Make a table factory:
function populateTable(table, rows, cells, content) {
if (!table) table = document.createElement('table');
for (var i = 0; i < rows; ++i) {
var row = document.createElement('tr');
for (var j = 0; j < cells; ++j) {
row.appendChild(document.createElement('td'));
row.cells[j].appendChild(document.createTextNode(content + (j + 1)));
}
table.appendChild(row);
}
return table;
}
And use it like this:
document.getElementById('tablearea')
.appendChild( populateTable(null, 3, 2, "Text") );
Table factory with text string or callback
The factory could easily be modified to accept a function as well for the fourth argument in order to populate the content of each cell in a more dynamic manner.
function populateTable(table, rows, cells, content) {
var is_func = (typeof content === 'function');
if (!table) table = document.createElement('table');
for (var i = 0; i < rows; ++i) {
var row = document.createElement('tr');
for (var j = 0; j < cells; ++j) {
row.appendChild(document.createElement('td'));
var text = !is_func ? (content + '') : content(table, i, j);
row.cells[j].appendChild(document.createTextNode(text));
}
table.appendChild(row);
}
return table;
}
Used like this:
document.getElementById('tablearea')
.appendChild(populateTable(null, 3, 2, function(t, r, c) {
return ' row: ' + r + ', cell: ' + c;
})
);
You need to create new TextNodes as well as td nodes for each column, not reuse them among all of the columns as your code is doing.
Edit:
Revise your code like so:
for (var i = 1; i < 4; i++)
{
tr[i] = document.createElement('tr');
var td1 = document.createElement('td');
var td2 = document.createElement('td');
td1.appendChild(document.createTextNode('Text1'));
td2.appendChild(document.createTextNode('Text2'));
tr[i].appendChild(td1);
tr[i].appendChild(td2);
table.appendChild(tr[i]);
}
<title>Registration Form</title>
<script>
var table;
function check() {
debugger;
var name = document.myForm.name.value;
if (name == "" || name == null) {
document.getElementById("span1").innerHTML = "Please enter the Name";
document.myform.name.focus();
document.getElementById("name").style.border = "2px solid red";
return false;
}
else {
document.getElementById("span1").innerHTML = "";
document.getElementById("name").style.border = "2px solid green";
}
var age = document.myForm.age.value;
var ageFormat = /^(([1][8-9])|([2-5][0-9])|(6[0]))$/gm;
if (age == "" || age == null) {
document.getElementById("span2").innerHTML = "Please provide Age";
document.myForm.age.focus();
document.getElementById("age").style.border = "2px solid red";
return false;
}
else if (!ageFormat.test(age)) {
document.getElementById("span2").innerHTML = "Age can't be leass than 18 and greater than 60";
document.myForm.age.focus();
document.getElementById("age").style.border = "2px solid red";
return false;
}
else {
document.getElementById("span2").innerHTML = "";
document.getElementById("age").style.border = "2px solid green";
}
var password = document.myForm.password.value;
if (document.myForm.password.length < 6) {
alert("Error: Password must contain at least six characters!");
document.myForm.password.focus();
document.getElementById("password").style.border = "2px solid red";
return false;
}
re = /[0-9]/g;
if (!re.test(password)) {
alert("Error: password must contain at least one number (0-9)!");
document.myForm.password.focus();
document.getElementById("password").style.border = "2px solid red";
return false;
}
re = /[a-z]/g;
if (!re.test(password)) {
alert("Error: password must contain at least one lowercase letter (a-z)!");
document.myForm.password.focus();
document.getElementById("password").style.border = "2px solid red";
return false;
}
re = /[A-Z]/g;
if (!re.test(password)) {
alert("Error: password must contain at least one uppercase letter (A-Z)!");
document.myForm.password.focus();
document.getElementById("password").style.border = "2px solid red";
return false;
}
re = /[$&+,:;=?##|'<>.^*()%!-]/g;
if (!re.test(password)) {
alert("Error: password must contain at least one special character!");
document.myForm.password.focus();
document.getElementById("password").style.border = "2px solid red";
return false;
}
else {
document.getElementById("span3").innerHTML = "";
document.getElementById("password").style.border = "2px solid green";
}
if (document.getElementById("data") == null)
createTable();
else {
appendRow();
}
return true;
}
function createTable() {
var myTableDiv = document.getElementById("myTable"); //indiv
table = document.createElement("TABLE"); //TABLE??
table.setAttribute("id", "data");
table.border = '1';
myTableDiv.appendChild(table); //appendChild() insert it in the document (table --> myTableDiv)
debugger;
var header = table.createTHead();
var th0 = table.tHead.appendChild(document.createElement("th"));
th0.innerHTML = "Name";
var th1 = table.tHead.appendChild(document.createElement("th"));
th1.innerHTML = "Age";
appendRow();
}
function appendRow() {
var name = document.myForm.name.value;
var age = document.myForm.age.value;
var rowCount = table.rows.length;
var row = table.insertRow(rowCount);
row.insertCell(0).innerHTML = name;
row.insertCell(1).innerHTML = age;
clearForm();
}
function clearForm() {
debugger;
document.myForm.name.value = "";
document.myForm.password.value = "";
document.myForm.age.value = "";
}
function restrictCharacters(evt) {
evt = (evt) ? evt : window.event;
var charCode = (evt.which) ? evt.which : evt.keyCode;
if (((charCode >= '65') && (charCode <= '90')) || ((charCode >= '97') && (charCode <= '122')) || (charCode == '32')) {
return true;
}
else {
return false;
}
}
</script>
<div>
<form name="myForm">
<table id="tableid">
<tr>
<th>Name</th>
<td>
<input type="text" name="name" placeholder="Name" id="name" onkeypress="return restrictCharacters(event);" /></td>
<td><span id="span1"></span></td>
</tr>
<tr>
<th>Age</th>
<td>
<input type="text" onkeypress="return event.charCode === 0 || /\d/.test(String.fromCharCode(event.charCode));" placeholder="Age"
name="age" id="age" /></td>
<td><span id="span2"></span></td>
</tr>
<tr>
<th>Password</th>
<td>
<input type="password" name="password" id="password" placeholder="Password" /></td>
<td><span id="span3"></span></td>
</tr>
<tr>
<td></td>
<td>
<input type="button" value="Submit" onclick="check();" /></td>
<td>
<input type="reset" name="Reset" /></td>
</tr>
</table>
</form>
<div id="myTable">
</div>
</div>
var html = "";
for (var i = 0; i < data.length; i++){
html +="<tr>"+
"<td>"+ (i+1) + "</td>"+
"<td>"+ data[i].name + "</td>"+
"<td>"+ data[i].number + "</td>"+
"<td>"+ data[i].city + "</td>"+
"<td>"+ data[i].hobby + "</td>"+
"<td>"+ data[i].birthdate + "</td>"+"<td><button data-arrayIndex='"+ i +"' onclick='editData(this)'>Edit</button><button data-arrayIndex='"+ i +"' onclick='deleteData()'>Delete</button></td>"+"</tr>";
}
$("#tableHtml").html(html);
You can create a dynamic table rows as below:
var tbl = document.createElement('table');
tbl.style.width = '100%';
for (var i = 0; i < files.length; i++) {
tr = document.createElement('tr');
var td1 = document.createElement('td');
var td2 = document.createElement('td');
var td3 = document.createElement('td');
::::: // As many <td> you want
td1.appendChild(document.createTextNode());
td2.appendChild(document.createTextNode());
td3.appendChild(document.createTextNode();
tr.appendChild(td1);
tr.appendChild(td2);
tr.appendChild(td3);
tbl.appendChild(tr);
}
when you say 'appendchild' you actually move your child from one parent to another.
you have to create a node for each cell.
In my example, serial number is managed according to the actions taken on each row using css. I used a form inside each row, and when new row created then the form will get reset.
/*auto increment/decrement the sr.no.*/
body {
counter-reset: section;
}
i.srno {
counter-reset: subsection;
}
i.srno:before {
counter-increment: section;
content: counter(section);
}
/****/
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script type='text/javascript'>
$(document).ready(function () {
$('#POITable').on('change', 'select.search_type', function (e) {
var selectedval = $(this).val();
$(this).closest('td').next().html(selectedval);
});
});
</script>
<table id="POITable" border="1">
<tr>
<th>Sl No</th>
<th>Name</th>
<th>Your Name</th>
<th>Number</th>
<th>Input</th>
<th>Chars</th>
<th>Action</th>
</tr>
<tr>
<td><i class="srno"></i></td>
<td>
<select class="search_type" name="select_one">
<option value="">Select</option>
<option value="abc">abc</option>
<option value="def">def</option>
<option value="xyz">xyz</option>
</select>
</td>
<td></td>
<td>
<select name="select_two" >
<option value="">Select</option>
<option value="123">123</option>
<option value="456">456</option>
<option value="789">789</option>
</select>
</td>
<td><input type="text" size="8"/></td>
<td>
<select name="search_three[]" >
<option value="">Select</option>
<option value="one">1</option>
<option value="two">2</option>
<option value="three">3</option>
</select>
</td>
<td><button type="button" onclick="deleteRow(this)">-</button><button type="button" onclick="insRow()">+</button></td>
</tr>
</table>
<script type='text/javascript'>
function deleteRow(row)
{
var i = row.parentNode.parentNode.rowIndex;
document.getElementById('POITable').deleteRow(i);
}
function insRow()
{
var x = document.getElementById('POITable');
var new_row = x.rows[1].cloneNode(true);
var len = x.rows.length;
//new_row.cells[0].innerHTML = len; //auto increment the srno
var inp1 = new_row.cells[1].getElementsByTagName('select')[0];
inp1.id += len;
inp1.value = '';
new_row.cells[2].innerHTML = '';
new_row.cells[4].getElementsByTagName('input')[0].value = "";
x.appendChild(new_row);
}
</script>
Hope this helps.
In My example call add function from button click event and then get value from form control's and call function generateTable.
In generateTable Function check first Table is Generaed or not. If table is undefined then call generateHeader Funtion and Generate Header and then call addToRow function for adding new row in table.
<input type="button" class="custom-rounded-bttn bttn-save" value="Add" id="btnAdd" onclick="add()">
<div class="row">
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<div class="dataGridForItem">
</div>
</div>
</div>
//Call Function From Button click Event
var counts = 1;
function add(){
var Weightage = $('#Weightage').val();
var ItemName = $('#ItemName option:selected').text();
var ItemNamenum = $('#ItemName').val();
generateTable(Weightage,ItemName,ItemNamenum);
$('#Weightage').val('');
$('#ItemName').val(-1);
return true;
}
function generateTable(Weightage,ItemName,ItemNamenum){
var tableHtml = '';
if($("#rDataTable").html() == undefined){
tableHtml = generateHeader();
}else{
tableHtml = $("#rDataTable");
}
var temp = $("<div/>");
var row = addToRow(Weightage,ItemName,ItemNamenum);
$(temp).append($(row));
$("#dataGridForItem").html($(tableHtml).append($(temp).html()));
}
//Generate Header
function generateHeader(){
var html = "<table id='rDataTable' class='table table-striped'>";
html+="<tr class=''>";
html+="<td class='tb-heading ui-state-default'>"+'Sr.No'+"</td>";
html+="<td class='tb-heading ui-state-default'>"+'Item Name'+"</td>";
html+="<td class='tb-heading ui-state-default'>"+'Weightage'+"</td>";
html+="</tr></table>";
return html;
}
//Add New Row
function addToRow(Weightage,ItemName,ItemNamenum){
var html="<tr class='trObj'>";
html+="<td>"+counts+"</td>";
html+="<td>"+ItemName+"</td>";
html+="<td>"+Weightage+"</td>";
html+="</tr>";
counts++;
return html;
}
You can do that using LemonadeJS.
<html>
<script src="https://lemonadejs.net/v2/lemonade.js"></script>
<div id='root'></div>
<script>
var Component = (function() {
var self = {};
self.rows = [
{ title:'Google', description: 'The alpha search engine...' },
{ title:'Bind', description: 'The microsoft search engine...' },
{ title:'Duckduckgo', description: 'Privacy in the first place...' },
];
// Custom components such as List should always be unique inside a real tag.
var template = `<table cellpadding="6">
<thead><tr><th>Title</th><th>Description</th></th></thead>
<tbody #loop="self.rows">
<tr><td>{{self.title}}</td><td>{{self.description}}</td></tr>
</tbody>
</table>`;
return lemonade.element(template, self);
});
lemonade.render(Component, document.getElementById('root'));
</script>
</html>

Categories