Remove a duplicate row in table when being added from an array? - javascript

I have something like this:
getELE("btnAddStudent").addEventListener("click", function(){
var ID = getELE("txtID").value;
var Name = getELE("txtName").value;
var Score = getELE("txtScore).value;
var St = new Student(ID, Name, Score);
List.Add(St);
var table = getELE("tbodyStudent");
for (var i = 0; i < List.arrSt.length; i++) {
var tr = document.createElement("tr");
for (var key of ['ID', 'Name', 'Score'])
{
var td = document.createElement("td");
td.innerHTML = List.arrSt[i][key];
tr.appendChild(td);
}
table.appendChild(tr);
}
});
The problem is whenever I add a new student, the table will add a whole list of students instead of adding just the new student to it making it have duplicate students.
How do I add just the new student instead of the whole list?
I have tried to tweak this into my "for" loop but still doesn't work.

Your code seems that you add whole list again to your table.
Here's updated code. Please try this.
getELE("btnAddStudent").addEventListener("click", function(){
var ID = getELE("txtID").value;
var Name = getELE("txtName").value;
var Score = getELE("txtScore).value;
var St = new Student(ID, Name, Score);
var table = getELE("tbodyStudent");
var tr = document.createElement("tr");
for (var key of ['ID', 'Name', 'Score'])
{
var td = document.createElement("td");
td.innerHTML = St[key];
tr.appendChild(td);
}
table.appendChild(tr);
List.Add(St);
});

The solution for this is add the tr when you are adding a new student.
var table = getELE("tbodyStudent");
var tr = document.createElement("tr");
for (var key of ['ID', 'Name', 'Score'])
{
var td = document.createElement("td");
// add here the new Student data
td.innerHTML = newStudentData[key];
tr.appendChild(td);
}
table.appendChild(tr);

I agree with above solution.
It is a good solution Adding a row when you add a new student.

Related

Send row data when clicking button?

I have the next information object
var data = [
{
name: 'John Doe',
transactions: [{...},{...},{...}]
},
{...}
];
Im inserting this data into a table like this:
function addRowsData(data) {
var table = document.getElementById('main-table');
var rowCount = table.rows.length;
var tBody = document.createElement('tbody');
table.appendChild(tBody);
for (var i = 0; i < data.length; i++) {
var info = data[i];
var tr = tBody.insertRow();
for(var key in info){
if(key == 'transactions') continue;
var td = document.createElement('td');
td.innerHTML = info[key];
tr.appendChild(td);
}
var tdButton = document.createElement('td');
var button = document.createElement('button');
var clientId = info.id;
button.setAttribute('type', 'button');
button.setAttribute('class', '"btn btn-primary');
button.setAttribute('id', clientId);
button.innerHTML = 'More'
tdButton.appendChild(button);
tr.appendChild(tdButton)
button.addEventListener('click', function() {
openModal(info.transactions);
});
}
}
function openModal(transactions) {
console.log(transactions);
var modal = document.getElementById('my-modal');
var close = document.getElementsByClassName('close')[0];
close.addEventListener('click', closeModal, false);
modal.style.display = 'block';
}
Each row has a button and when is clicked opens a modal, on this modal I want to show the data from the transactions array, I tried doing it like this openModal(info.transactions); but this always shows the data from the last element. Is there a way to accomplish this, that when I click on the row button, I can access to the transactions array?
In your code, you reference info in the event listener. However, the variable info changes throughout the for loop, so at the end of the for loop, info will be the last index. To fix this, maybe instead of passing info in, you can pass in eval(data[i]), so it will input the actual data instead of a variable which changes.

Avoid display duplicate elements in table

So I saved some data in localStorage.
I get them back from localstorage to the table.
When I click on the button to enter new data, the data entered earlier is duplicated in the table. When I refresh the page, everything is fine.
$(document).ready(function() {
function save() {
list.forEach(function(item) {
var nameNode = document.createTextNode(item.name);
var surnameNode = document.createTextNode(item.surname);
var dataNode = document.createTextNode(item.data);
var nrNode = document.createTextNode(item.nr);
var tdName = document.createElement("td");
var tdSurname = document.createElement("td");
var tdData = document.createElement("td");
var tdNr = document.createElement("td");
tdName.appendChild(nameNode);
tdSurname.appendChild(surnameNode);
tdData.appendChild(dataNode);
tdNr.appendChild(nrNode);
var tr = document.createElement("tr");
tr.appendChild(tdName);
tr.appendChild(tdSurname);
tr.appendChild(tdData);
tr.appendChild(tdNr);
// download table and insert cells and rows
var table = document.getElementById("table");
table.appendChild(tr);
});
}
list = jQuery.parseJSON(localStorage.getItem("osoba") === null ? [] : localStorage.getItem("osoba"));
save();
$("#send").click(function() {
var osoba = {};
osoba["name"] = document.getElementById("name").value;
osoba["surname"] = document.getElementById("subname").value;
osoba["data"] = document.getElementById("date_bth").value;
osoba["nr"] = document.getElementById("numer_phone").value;
list.push(osoba);
localStorage.setItem("osoba", JSON.stringify(list));
document.getElementById("name").value = "";
document.getElementById("surname").value = "";
document.getElementById("date_bth").value = "";
document.getElementById("numer_phone").value = "";
save();
});
});
How to avoid duplication in the table without reloading the page?
When you save, you need to first clear the data already on the table or it will be added to it again when you call save. Here's how you do that:
$(document).ready(function(){
function save() {
$("#table tr").remove(); // <- this
list.forEach(function (item) {
var nameNode = document.createTextNode(item.name);
var surnameNode = document.createTextNode(item.surname);
var dataNode = document.createTextNode(item.data);
var nrNode = document.createTextNode(item.nr);
var tdName = document.createElement("td");
var tdSurname = document.createElement("td");
var tdData = document.createElement("td");
var tdNr = document.createElement("td");
tdName.appendChild(nameNode);
tdSurname.appendChild(surnameNode);
tdData.appendChild(dataNode);
tdNr.appendChild(nrNode);
var tr =document.createElement("tr");
tr.appendChild(tdName);
tr.appendChild(tdSurname);
tr.appendChild(tdData);
tr.appendChild(tdNr);
// download table and insert cells and rows
var table = document.getElementById("table");
table.appendChild(tr);
});
}
list = jQuery.parseJSON(localStorage.getItem("osoba") === null ? [] : localStorage.getItem("osoba"));
save();
$("#send").click(function(){
var osoba = {};
osoba["name"] = document.getElementById("name").value;
osoba["surname"] = document.getElementById("subname").value;
osoba["data"] = document.getElementById("date_bth").value;
osoba["nr"] = document.getElementById("numer_phone").value;
list.push(osoba);
localStorage.setItem("osoba",JSON.stringify(list));
document.getElementById("name").value="";
document.getElementById("surname").value="";
document.getElementById("date_bth").value="";
document.getElementById("numer_phone").value="";
save();
});
});

Firebase - Generate table from database data

I would like to know how to create a table like thisfrom some data in a firebase database like this
There would need to be a column for ID, Title, Number of Answers, Correct Answer and Type. Preferably this should be done using jQuery.
Thank you in advance.
Get data
Read the firebase database documentation and references.
The basic firebase read operation looks like this:
var ref = firebase.database().ref("location");
ref.once("value")
.then(function(snapshot) {
var key = snapshot.key;
var value = snapshot.val();
console.log(key + ": " + value);
});
Of course you have to add scripts for firebase and firebase database before.
If you want to loop through an data you can use forEach function, for example:
var query = firebase.database().ref("location2");
query.once("value").then(function(snapshot) {
snapshot.forEach(function(childSnapshot) {
var key = childSnapshot.key;
var value = childSnapshot.val();
console.log(key + ": " + value);
});
});
Table
You can create table dynamically using JS - functions like createElement and createDocumentFragment
For example:
var fragment = document.createDocumentFragment();
var animalsArray = ["Elephant", "Dog", "Cat"];
var table = document.createElement("table");
for (var i = 0; i < animalsArray.length; i++) {
var tr = document.createElement("tr");
var td = document.createElement("td");
td.textContent = animalsArray[i];
tr.appendChild(td);
table.appendChild(tr);
}
fragment.appendChild(table);
document.body.appendChild(fragment);
Table built from data in Firebase database
And now connect concepts above together. Create a table. Get data from firebase database. At every ireration over this data: create new table row with cells built from key and value of an element. In example below I used for loop to not duplicate the same operation for every cell.
Full example:
Data tree in Firebase Database:
{
"location2" : {
"hello" : "world",
"hi" : "Mark"
}
}
Code:
var fragment = document.createDocumentFragment();
var table = document.createElement("table");
var query = firebase.database().ref("location2");
query.once("value").then(function(snapshot) {
snapshot.forEach(function(childSnapshot) {
var tr = document.createElement("tr");
var trValues = [childSnapshot.key, childSnapshot.val()];
for (var i = 0; i < trValues.length; i++) {
var td = document.createElement("td");
td.textContent = trValues[i];
tr.appendChild(td);
}
table.appendChild(tr);
});
});
fragment.appendChild(table);
document.body.appendChild(fragment);

How to add different columns to a dynamic table from database with javascript

I have a function building a dynamic table. I'm having trouble figuring out how to set each column to a different data set from the database. Right now it just shows the same value in each column.
A little background. I'm building a table with 6 columns and lots of rows (all depends how much data the database has). Right now it's only showing one column in all of the 6 columns, so they repeat.
How can I set each column to a different value for the 6 columns?
function addTable() {
var len = errorTableData.length;
var myTableDiv = document.getElementById("myDynamicTable");
var table = document.createElement('TABLE');
table.border='1';
table.id = "dataTable";
var tableBody = document.createElement('TBODY');
table.appendChild(tableBody);
for (var i=0; i<len; i++){
var tr = document.createElement('TR');
tr.className = "rowEditData";
tableBody.appendChild(tr);
for (var j=0; j<6; j++){
var countyName = errorTableData['CountyName'][i];
var stateName = errorTableData['StateName'][i];
var td = document.createElement('TD');
td.className = "mdl-data-table__cell--non-numeric";
td.appendChild(document.createTextNode(countyName));
td.appendChild(document.createTextNode(stateName));
tr.appendChild(td);
}
}
myTableDiv.appendChild(table);
}
Here is the ajax call:
function triggerDataTable(index) {
// Make AJAX requests for model systems
$.ajax({
type: "POST",
url: "qry/getAllData.php",
async: true,
dataType: "html",
data: {ErrorOptions: control.settings.errorOptions},
success: function (result) {
//console.warn(result);
errorData = JSON.parse(result);
//loop through data
var len = errorData.length;
for(i=0; i<len; i++) {
if ('VersionKey' in errorData[i]) {
vKey = (errorData[i]['VersionKey']);
} else if ('ErrorCode' in errorData[i]) {
var errorCode = (errorData[i]['ErrorCode']);
} else if ('SourceKey' in errorData[i]) {
var sourceKey = (errorData[i]['SourceKey']);
} else { //data here
errorTableData = errorData[i];
}
}
addTable();
}
});
}
The errorData is the data from the database. As you can see I've tried to add 2 variables but when I do that it just puts both of them in the same box and repeats throughout the whole table.
It looks like you are printing the exact same data 6 times for each row. You create a td element, then add country and state names to it, but the variable you are using for the index on your data set is coming from your outer loop, so on the inner loop it never changes, and you are literally grabbing the same value every time:
function addTable() {
var len = errorTableData.length;
var myTableDiv = document.getElementById("myDynamicTable");
var table = document.createElement('TABLE');
table.border='1';
table.id = "dataTable";
var tableBody = document.createElement('TBODY');
table.appendChild(tableBody);
for (var i=0; i<len; i++){
// You set i here, presumably to get each row in your dataset
var tr = document.createElement('TR');
tr.className = "rowEditData";
tableBody.appendChild(tr);
for (var j=0; j<6; j++){
var countyName = errorTableData['CountyName'][i];
var stateName = errorTableData['StateName'][i];
// Above, you are using i, not j
var td = document.createElement('TD');
td.className = "mdl-data-table__cell--non-numeric";
td.appendChild(document.createTextNode(countyName));
td.appendChild(document.createTextNode(stateName));
tr.appendChild(td);
}
}
myTableDiv.appendChild(table);
}
It would be easier to help if you could post some json with the data you are getting from the DB
Based on the edit on your post and looking at the success callback, I think you have small problem that can be easily fixed:
First, initialize an empty array for errorTableData
success: function (result) {
errorTableData = [];
In your if/else block:
} else { //data here
errorTableData = errorData[i];
}
Should be:
} else { //data here
errorTableData[i] = errorData[i];
}
Then in your inner loop:
var countyName = errorTableData['CountyName'][i];
var stateName = errorTableData['StateName'][i];
Becomes:
var countyName = errorTableData[i]['CountyName'][j];
var stateName = errorTableData[i]['StateName'][j];
This is just a guess because I can't see the actual data.

Not sure I quite understand variable scope in Javascript

Sorry if this seems a bit easy. I'm still relatively new to Javascript.
I am generating a list of checkboxes. On the onClick of a checkbox, i want to make it pop up its associated text. ie. Checkbox named "one" should then display "one". In my example it only displays "two".
However the click() callback method only ever calls the text of the last added checkbox. Does the 'v' variable in here not get assigned per checkbox? It seems like the'v' is behaving like a global variable.
this.view = document.createElement("div");
var tbody = document.createElement("tbody");
var popupValues = {"A", "B"};
for (var i=0;i<this.popupValues.length;i++) {
var v = popupValues[i];
var tr = document.createElement('tr');
var tdCheck = document.createElement('td');
var ChkBx = document.createElement('input')
ChkBx.type = 'checkbox';
tdCheck.appendChild(ChkBx);
var self = this;
$(ChkBx).live('change', function(){
if($(this).is(':checked')){
alert('checked' + v);
} else {
alert('un-checked' + v);
}
});
var td = document.createElement("td");
td.appendChild(document.createTextNode('' + v));
tr.appendChild(tdCheck);
tr.appendChild(td);
tbody.appendChild(tr);
}
table.appendChild(tbody);
document.appendChild(table)
Here is jsfiddle :
http://jsfiddle.net/n5GZW/2/
Anyone know what I am doing wrong?
UPDATE: updated JSFiddle
"Does the 'v' variable in here not get assigned per checkbox?"
Well, it's assigned, but not declared for each checkbox.
In Javascript variables only have function scope. Even if you try to create a new variable in each iteration of the loop, it's only a single variable declared at the function level, shared by all iterations. The declaration is hoisted to the function level, only the assignment happens inside the loop.
You can use an immediatey executed function expression to create another scope inside the loop, where you can create a new variable for each iteration:
for (var i=0;i<this.popupValues.length;i++) {
(function(v){
// code of the loop goes in here
// v is a new variable for each iteration
}(popupValues[i]));
}
you can do
var table = document.createElement("table");
var tbody = document.createElement("tbody");
var popupValues = [
"one", "two"
];
for (var i = 0; i < popupValues.length; i++) {
var v = popupValues[i];
var tr = document.createElement('tr');
var tdCheck = document.createElement('td');
var ChkBx = document.createElement('input');
ChkBx.type = 'checkbox';
ChkBx.value=v;
tdCheck.appendChild(ChkBx);
var td = document.createElement("td");
td.appendChild(document.createTextNode('' + v));
tr.appendChild(tdCheck);
tr.appendChild(td);
tbody.appendChild(tr);
var self = this;
$(ChkBx).click('change', function () {
if ($(this).is(':checked')) {
alert('check ' + $(this).val());
} else {
alert('un-checked');
}
});
}
table.appendChild(tbody);
document.body.appendChild(table)
http://jsfiddle.net/n5GZW/4/
add ChkBx.value=v; to get value like $(this).val() on click
You could've searched in SO for event binding in for loop.
Here is one solution:
Try this:
this.view = document.createElement("div");
var tbody = document.createElement("tbody");
var popupValues = {"A", "B"};
for (var i=0;i<this.popupValues.length;i++) {
var v = popupValues[i];
var tr = document.createElement('tr');
var tdCheck = document.createElement('td');
var ChkBx = document.createElement('input')
ChkBx.type = 'checkbox';
tdCheck.appendChild(ChkBx);
var self = this;
(function(val) {
$(ChkBx).on('change', function(){
if($(this).is(':checked')){
alert('checked' + val);
} else {
alert('un-checked' + val);
}
});
})(v);
var td = document.createElement("td");
td.appendChild(document.createTextNode('' + v));
tr.appendChild(tdCheck);
tr.appendChild(td);
tbody.appendChild(tr);
}
table.appendChild(tbody);
document.appendChild(table);

Categories