Selecting elements from filter table - javascript

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>

Related

How to add information to a table based on a button click in Javascript?

I have 2 functions, one dynamically creates a list, the other inserts a row after the row was added to the table.
What's happening now is when I click add to order, the product is added to the table, the new row is created, and when I click another product to add to the table, the old product disappears and the most recent product takes it's place and then creates a new row, so now I have 3 rows total, but only 1 product in the table, and 2 empty rows in the table. every time I add a product to the order, it just replaces the first row with the new product, and the old one is wiped away. I want every product I click to be added to the table and a new row created there after.
html:
<table id = "productsTable">
<tr>
<th>#</th>
<th>SKU</th>
<th>Product Name</th>
<th>Quantity</th>
<th>Retail Price</th>
<th>List Price</th>
</tr>
<tr>
<td>1</td>
<td><input type="text" id="productSKU" readonly ="true"/></td>
<td><input type="text" id="productName" readonly = "true"/></td>
<td><input type="text" id="quantity" /></td>
<td><input type="text" id="retailPrice" readonly = "true"/></td>
<td><input type="text" id="listPrice" readonly = "true"/></td>
<input type="button" id = "btnDeleteRow" value="-">
</tr>
</table>
JavaScript:
function populateProductList(jsonArr){
var html = "";
html += `<ul id="myULProducts">`;
for(var x = 0; x < jsonArr.length; x++){
html += `
<li SKU = "${jsonArr[x].SKU}">
<a href="#" class="products">
<strong>Product SKU:</strong> ${jsonArr[x].SKU}
<br><strong>Product Name:</strong> ${jsonArr[x].product_name}
<br><strong>Retail Price:</strong> ${jsonArr[x].retail_price}
<br><strong>List Price:</strong> ${jsonArr[x].list_price}
<br><br></a>
<button type="button" class="btnAddProductToOrder">Add to Order</button>
</li>
</div>`
}
html += `</ul>`;
var ol = document.createElement("ol");
ol.innerHTML = html;
var tableContainer = document.getElementById("product-list-container");
tableContainer.innerHTML = "";
tableContainer.appendChild(ol);
tableContainer.addEventListener("click", function(evt){
//populateCardGroupList();
var target = evt.target;
//if statement to see if the classList has a button edit
if(target.classList.contains("btnAddProductToOrder")){
//get the id of the card group clicked
var selectedId = target.closest("li").getAttribute("SKU");
//get the card group attached to that id and pass it the rest of the json Array of objects
var selectedProduct = getProductId(selectedId, jsonArr);
populateOrderFormProducts(selectedProduct);
}
});
}
document.getElementById("btnGetProductList").addEventListener("click", ()=>{
getAllProducts();
});
function populateOrderFormProducts(jsonArr){
document.querySelector("#productSKU").value = jsonArr.SKU;
document.querySelector("#productName").value = jsonArr.product_name;
document.querySelector("#quantity").value = 1;
document.querySelector("#retailPrice").value = jsonArr.retail_price;
document.querySelector("#listPrice").value = jsonArr.list_price;
insertRow();
}
function insertRow() {
var x = document.getElementById('productsTable');
var new_row = x.rows[1].cloneNode(true);
var len = x.rows.length;
new_row.cells[0].innerHTML = len;
var inp1 = new_row.cells[1].getElementsByTagName('input')[0];
inp1.id += len;
inp1.value = '';
var inp2 = new_row.cells[2].getElementsByTagName('input')[0];
inp2.id += len;
inp2.value = '';
var inp3 = new_row.cells[3].getElementsByTagName('input')[0];
inp3.id += len;
inp3.value = '';
var inp4 = new_row.cells[4].getElementsByTagName('input')[0];
inp4.id += len;
inp4.value = '';
var inp5 = new_row.cells[5].getElementsByTagName('input')[0];
inp5.id += len;
inp5.value = '';
x.appendChild(new_row);
}
This is what i'm trying to do but obviously this doesn't work:
function populateOrderFormProducts(jsonArr){
if(document.querySelector("#productSKU").value = null){
document.querySelector("#productSKU").value = jsonArr.SKU;
document.querySelector("#productName").value = jsonArr.product_name;
document.querySelector("#quantity").value = 1;
document.querySelector("#retailPrice").value = jsonArr.retail_price;
document.querySelector("#listPrice").value = jsonArr.list_price;
insertRow();
}
else if(document.querySelector("#productSKU").value != null){
document.querySelector("#productSKU2").value = jsonArr.SKU;
document.querySelector("#productName2").value = jsonArr.product_name;
document.querySelector("#quantity2").value = 1;
document.querySelector("#retailPrice2").value = jsonArr.retail_price;
document.querySelector("#listPrice2").value = jsonArr.list_price;
insertRow();
}
else if(document.querySelector("#productSKU2").value != null){
document.querySelector("#productSKU3").value = jsonArr.SKU;
document.querySelector("#productName3").value = jsonArr.product_name;
document.querySelector("#quantity3").value = 1;
document.querySelector("#retailPrice3").value = jsonArr.retail_price;
document.querySelector("#listPrice3").value = jsonArr.list_price;
insertRow();
}
}

Get nested array items to append to new column in HTML Table

I'm trying to append items from a 2D array into a table, but everything is appearing in the one column on the left. How can I separate tableDataArr[1] to start loading into the next column across?
Javascript
let names = []; //populated dynamically
let language = []; //populated dynamically
let tableDataArr = [names, language];
function renderData() {
for (let i = 0; i < tableDataArr.length; i++) {
tableDataArr[i].forEach(j => {
let newRow = document.createElement("tr");
newRow.className = "row";
newRow.innerHTML = `<td class='cell'>${j}</td>`;
leftTable.appendChild(newRow);
});
}
}
HTML
<div class='left-tbl-wrap'>
<table class='table' id='left-table'>
<tr class='row'>
<th class='th'>Name</th>
<th class='th'>Language</th>
<th class='th'>Latest tag</th>
<th class='th'><span class='delete'></span></th>
</tr>
</table>
</div>
For each iteration add name and language to the same row, then insert that row into table.
I added some elements in names and languages array to demostrate
let names = ["name1", "name2", "name3"]; //populated dynamically
let language = ["language1", "language2", "language3"]; //populated dynamically
let tableDataArr = [names, language];
const leftTable = document.querySelector("#left-table");
function renderData() {
tableDataArr[0].forEach((j, i) => {
let newRow = document.createElement("tr");
newRow.className = "row";
newRow.innerHTML = `<td class='cell'>${j}</td><td class='cell'>${tableDataArr[1][i]}</td>`;
leftTable.appendChild(newRow);
});
}
renderData();
<div class='left-tbl-wrap'>
<table class='table' id='left-table'>
<tr class='row'>
<th class='th'>Name</th>
<th class='th'>Language</th>
<th class='th'>Latest tag</th>
<th class='th'><span class='delete'></span></th>
</tr>
</table>
</div>
It should be like that
function renderData() {
for (let i = 0; i < tableDataArr.length; i++) {
let newRow = document.createElement("tr");
tableDataArr[i].forEach(j=> {
newRow.className = "row";
newRow.innerHTML = `<td class='cell'>${j}</td>`;
leftTable.appendChild(newRow);
});
}
}
Because you may do not need to iterate table row in the second loop. If you do like that it will be add each row with only one table data.

Filtering html table (JS)

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";
}
}
}
}

How to better formatting my HTML Table with titles and labels

How would I modify my code (below) to turn the table element (circled in red), into a table with a Title, and then headers above each column ("Load" and "kWh") for the left and right columns, respectively?
The elements, "name" and "watts" are what I want to create a label for ("Load" and "kWh"), in addition to a title above the table which says "Power Usage". Right now, there is no formatting, and I am having trouble going from the tutorials at W3 schools, into my code.
function(){
var wrapper = document.createElement("div");
if(!this.loaded) {
wrapper.innerHTML = "Loading...";
return wrapper;
}
if(this.xml !== null){
var table = document.createElement("table");
table.classList.add("xsmall", "table");
var channels = this.xml.getElementsByTagName("channel");
for(var i = 0; i < channels.length; i++){
var row = document.createElement("tr");
for(var n = 0; n < channels[i].children.length; n++){
if(channels[i].children[n].tagName === "name" || channels[i].children[n].tagName === "watts"){
var element = document.createElement("td");
element.classList.add(channels[i].children[n].tagName);
if (channels[i].children[n].textContent != 0){
element.innerHTML = channels[i].children[n].textContent;
row.appendChild(element);
table.appendChild(row);
}
else {
table.removeChild(row); }
}
}
}
wrapper.appendChild(table);
} else {
console.log("Returned no Data");
wrapper.innerHTML = "NO DATA";
}
return wrapper;
},
First Try:
You just want to build out a table similar to the following using the JS you've already written:
<table>
<caption>Put title here</caption>
<thead>
<tr>
<th>Load</th>
<th>kWh</th>
</tr>
</thead>
<tbody>
<tr>
<td>Kitchen Lights</td>
<td>2.799</td>
</tr>
</tbody>
</table>

Add table values to input field on button click

I have a DataTable that stores names only. I want to have a button that will add all the names in the DataTable to an text input field.
<div id="myTabDiv">
<table name="mytab" id="mytab1">
<thead>
<tr>
<th>name</th>
</tr>
</thead>
<tbody>
<tr>
<td>chris</td>
</tr>
<tr>
<td>mike</td>
</tr>
</tbody>
</table>
<button id="add" >ADD</button>
<input type="text" id="text">
</div>
After click the "add" button, I want the names to appear in the text field separated by a comma.
And if possible, If the button is clicked again, remove the names?
I created the whole solution on codepen. This is the function used:
var clicks = 0;
function csv() {
var box = document.getElementsByName('text')[0];
if(clicks === 0){
var newcsv = "";
var tds = document.getElementsByTagName("TD");
for(var i = 0; i < tds.length; i++)
{
newcsv += tds[i].innerHTML;
if(i != tds.length-1) newcsv += ",";
}
box.value = newcsv;
clicks++;
}
else{
clicks = 0;
box.value = "";
}
}
This is bound to onclick event of a button.
Assign id to input
<input type=text id="textbox"/>
Just loop though table
var table = document.getElementById("mytab1");
var textbox=document.getElementById("textbox")
for (var i = 0, row; row = table.rows[i]; i++) {
for (var j = 0, col; col = row.cells[j]; j++) {
if(textbox.value=="")
{
textbox.value=row.cells[j].innerText;
}
else
{
textbox.value+= textbox.value+','+row.cells[j].innerText;
}
}
}

Categories