I have a modal with 2 input fields, and a table with two columns. I'm trying write a function that adds a new row to the table when a button is clicked. However when I test my code nothing happens.
The input fields have the id's "modal_type" and "modal_price", the table has the id "acc_table1"
JS:
{
var new_acc=document.getElementById("modal_type").value;
var new_bal=document.getElementById("modal_price").value;
var table=document.getElementsById("acc_table1");
var table_len=(table.rows.length)-1;
var row = table.insertRow(table_len).outerHTML="<tr id='acc_row"+table_len+"'><td id='acc_name"+table_len+"'>"+new_acc+"</td><td id='acc_balance"+table_len+"'>"+new_bal+"</td></tr>";
document.getElementById("modal_type").value="";
document.getElementById("modal_price").value="";
}
I'd appreciate any suggestions on what I could change!
Try this:
const newRow = table.insertRow(-1); // appends a new row
newRow.itemId = 'acc_row'; // set item id to the new row
const accCell = newRow.insertCell(0); // add a cell to the new row at index 0
accCell.itemId = 'acc_name'; // set item id to the cell
const accText = document.createTextNode(new_acc); // create a text node for new_acc
accCell.appendChild(accText); // set text node to acc cell
const balCell = newRow.insertCell(1); // add a cell to the new row at index 1
balCell.itemId = 'acc_balance'; // set item id to the cell
const balText = document.createTextNode(new_bal); // create a text node for new_bal
balCell.appendChild(balText); // set text node to bal cell
Related
I created a table in javascript that uses for loop adding 7 empty rows to the HTML table. But, it seems like these rows (or columns) have default sizes. Tried every possible way to resize them, but no luck. I have div element and inside has two tables for reference. Using also "display: inline- block". Here is my javascript code:
document.addEventListener("DOMContentLoaded", function(){
// Get the current page's URL
const currentUrl = window.location.href;
// Check if the current page's URL is the URL of the exam page
if (currentUrl.includes("exam.html")) {
// Get the table element from the HTML document
const lowBoundAndGradeTable = document.querySelector(".low_boundAndGrade");
// create an empty array to store the exam data
let gradeData = [];
// Check if there is data stored in localStorage
if (localStorage.getItem("gradeData")) {
// Retrieve the data from localStorage and parse it as JSON
gradeData = JSON.parse(localStorage.getItem("gradeData"));
}
// Loop through the examData to insert the rows
gradeData.forEach((data, index) => {
// create a new table row
const row = lowBoundAndGradeTable.insertRow();
// insert the cells into the row
const lowBoundCell = row.insertCell();
lowBoundCell.innerHTML = `<input type="text" name="low bound." value="${data.lowBound}">`;
const gradeCell = row.insertCell();
gradeCell.innerHTML = `<input type="text" name="grade" value="${data.grade}">`;
// add a change event listener to each input field
lowBoundCell.querySelector("input").addEventListener("change", function(){
gradeData[index].lowBound = this.value;
localStorage.setItem("gradeData", JSON.stringify(gradeData));
})
gradeCell.querySelector("input").addEventListener("change", function(){
gradeData[index].grade = this.value;
localStorage.setItem("gradeData", JSON.stringify(gradeData));
});
});
// Loop to insert 7 rows if studentData array is empty
if(gradeData.length == 0){
for (let i = 0; i < 7; i++) {
// create a new table row
const row = lowBoundAndGradeTable.insertRow();
// insert the cells into the row
const lowBoundCell = row.insertCell();
lowBoundCell.innerHTML = `<input type="text" name="low bound${i}">`;
const gradeCell = row.insertCell();
gradeCell.innerHTML = `<input type="text" name="grade${i}">`;
// add the data to the examData array
gradeData.push({ lowBound: "", grade: "" });
}
// set the examData in localStorage
localStorage.setItem("gradeData", JSON.stringify(gradeData));
}
}
});
I want to resize the rows so that I can enter numbers in it. But, these cells are kinda big that does not look like user friendly.
I am working on a project where I am finding difficulty in adding datetimepicker to dynamically added table rows. I have added datetimepicker to static table rows and it is working fine for them but not working for dynamically added table rows.
The tutorial I am following for datetimepicker
https://eonasdan.github.io/bootstrap-datetimepicker/
My Code I tried: I am cloning hidden rows.
Row Clone function:
// Table Add Function
$('.table-add').click(function () {
var $clone = $TABLE.find('tr.hide').clone(true).removeClass('hide table-line');
hid = $TABLE.find('tr.hide').attr('id');
// //Assigning every table row a unique ID
var max=0;
$('table').find('tr').each(function(){
var id=parseInt($(this).attr('id'));
if (id>=max){
max = id;
}
});
//cloning row with new ID
$clone.attr('id', parseInt(max)+1);
//always assign new id to new table row, will be easy to recognize rows
$clone.find('input.myinput').attr('id', parseInt(max)+1);
$clone.find("[name='datepicker']").datetimepicker();
//$("[name='datepicker']").datetimepicker();
$hiddentr = $('table').find('tr.hide');
//add dynamic word picker to cloned rows dynamically
$clone.find('td:nth-last-child(4)').after('{% if obj.word_picker == "Y" %} <td><input id="wordpicker" style="border:none"; data-role="tagsinput" class="myinput" name="unique_tag"/></td>{% endif %}');
$clone.appendTo( $('#'+hid).parent());
//submitting form after row clone
submitForm();
});
HTML of hidden td:
<td>
<div style="position: relative">
<input class = "form-control" type= "text" name = "datepicker" id= "datetime">
</div>
</td>
Messy but just init datetimepisker each time after you add a row...
$('#datetimepicker1').datetimepicker();
$('#datetimepicker2').datetimepicker();
etc
I was able to initialize the datetimepicker once the element was completely generated into the dom. working codepen
function addTableRow() {
var tbodyElement = document.getElementById("tbody");
var trElement = document.createElement("tr");
trElement.id = "generatedTr";
for (var x=0; x<3; x++) {
var tdElement = document.createElement("td");
var textNode = document.createTextNode("Generated td: " + x);
tdElement.appendChild(textNode);
trElement.appendChild(tdElement);
}
var finalTdElement = document.createElement("td");
var inputElement = document.createElement("input");
inputElement.setAttribute("type", "text");
inputElement.id = "generatedInput";
finalTdElement.appendChild(inputElement);
trElement.appendChild(finalTdElement);
tbodyElement.appendChild(trElement);
$('#generatedInput').datetimepicker();
}
If you have multiple elements that are being generated that needs the datetime picker, then I would suggest creating a class on all of them, then simply instantiate the plugin against that class like so.
$('.dateTimePickers').datetimepicker();
I would suggest don't initialize the datetimepicker every time after each element. better use following code. It will work like a charm.
I have been doing lot of research for this. Thus, Recommending to use Following code.
$('body').on('focus',".datetimepicker", function(){
$(this).datetimepicker();
});
I'm using Firebase to store users info and I'm wanting to populate divs with each users info so it can be either accepted or deleted (but not deleted from Firebase).
So I wanted it to be structured something like this:
----------------------
Name
Email
Date
----------------------
Name
Email
Date
----------------------
and so on....
What I'm currently getting back is something like this:
What is the proper way to generate a div dependent upon how much data is in Firebase and format the content as specificed?
HTML:
<div>Some entry here
<h4 id="name"></h4>
<h4 id="date"></h4>
<h6 id="email"></h6>
<button id="0" class="remove">Remove</button>
</div>
<div>Another entry here
<button id="1" class="remove">Remove</button>
</div>
Javascript:
var ref = firebase.database().ref('requests');
ref.on('value', function(snapshot) {
snapshot.forEach(function(child) {
var datas = child.val();
var email = child.val().Email;
var name = child.val().Name;
var date = child.val().Scheduled_Date;
date = date.replace('.', '/');
$('#name').append(name);
$('#email').append(email);
$('#date').append(date);
});
});
For each child, you are appending the values to the same HTML elements (i.e. all the names are appended to the h4 element with id "name", all the emails to the one with id "email" and so on).
So it is normal they are displayed on a line (one row).
You have to create a new placeholder for each child (and it's set of values). You can do that with e.g. a table, like:
var tableRef = document.getElementById('myTable').getElementsByTagName('tbody')[0];
var ref = firebase.database().ref('requests');
ref.on('value', function(snapshot) {
snapshot.forEach(function(child) {
var datas = child.val();
var email = child.val().Email;
var name = child.val().Name;
var date = child.val().Scheduled_Date;
date = date.replace('.', '/');
// Insert a row in the table at the last row
var newRow = tableRef.insertRow(tableRef.rows.length);
// Insert a cell in the row at index 0
var newCell = newRow.insertCell(0);
// Append a text node to the cell with name value
var newText = document.createTextNode(name); // <-- name value from the child
newCell.appendChild(newText);
var newRow = tableRef.insertRow(tableRef.rows.length);
var newCell = newRow.insertCell(0);
var newText = document.createTextNode(email); // <-- email value from the child
newCell.appendChild(newText);
var newRow = tableRef.insertRow(tableRef.rows.length);
var newCell = newRow.insertCell(0);
var newText = document.createTextNode(date); // <-- date value from the child
newCell.appendChild(newText);
});
});
Inspired by How to insert row in HTML table body in Javascript?. See the fiddle in this SO post.
Or you can do it with divs, here is a possible code:.
HTML
<div id="parentDiv"></div>
JavaScript
var element;
var ref = firebase.database().ref('requests');
ref.on('value', function(snapshot) {
snapshot.forEach(function(child) {
var datas = child.val();
var email = child.val().Email;
var name = child.val().Name;
var date = child.val().Scheduled_Date;
date = date.replace('.', '/');
element = document.createElement("div");
element.appendChild(document.createTextNode(name));
document.getElementById('parentDiv').appendChild(element);
element = document.createElement("div");
element.appendChild(document.createTextNode(email));
document.getElementById('parentDiv').appendChild(element);
element = document.createElement("div");
element.appendChild(document.createTextNode(date));
document.getElementById('parentDiv').appendChild(element);
//You could add a specific css class to this div to generate the bottom border
});
});
To be complete, note that you could also use some MVVM javascript frameworks like vue.js, knockout.js as well as angular, react... in order to easily reflect in your HTML DOM the results of queries to your backend (and vice-versa).
(This is my first question here and I am new to programming)
I am stuck on a problem and I tried to take something from here:
http://jsfiddle.net/4pEJB/
Dynamically generated table - using an array to fill in TD values
The function I created receive two vectors and creates a table with 2 columns, one for each vector, and lines = vector.length.
The function works fine, it seems to create the table as I need, but it doesn't show the table created on the browser screen after button click. By using some 'alert()' on the for loops I was able to verify that it uses the correct data.
In fact, when the button is clicked, it calls another function that processes some data and passes two vectors on this function I am showing here, but this part works well.
Here is the HTML part:
<div class="tableDiv">
<input type="button" onclick="createtable([1,3,5,7,9],[2,4,6,8,10])" value="Show data">
</div>
And here is the JavaScript part:
function createtable(vet_1,vet_2){
var tableDiv = document.getElementById("tableDiv");
var table = document.createElement("table");
var tableBody = document.createElement('tbody');
for (var r=0;r<vet_1.length;r++){
var row = document.createElement("tr");
for (var c=0;c<2;c++){
var cell = document.createElement("td");
if (c==0){cell.appendChild(document.createTextNode(vet_1[r]));}
else if(c==1){cell.appendChild(document.createTextNode(vet_2[r]));}
row.appendChild(cell);
}
tableBody.appendChild(row);
}
tableDiv.appendChild(table);
}
When the function finishes the table feed, it stops on tableDiv.appendChild(table);
Any advice or suggestions will be greatly appreciated! (I speak portuguese, I am sorry for some errors)
EDIT: it's possible to avoid the increment on the number of table rows that occurs every time we click the button (the solution provided generates one new table under the previous table). To solve this, I just added this line on the beggining of the function code (need to put the button outside the div and let the div empty, otherwise it will hide the button):
document.getElementById("tableDiv").innerHTML = "";
you are capturing by id, but you set up a class.chang it to id
<div id="tableDiv">
and append the tableBody into table.You're populating the table body with rows, but never appended the body into the table element.
function createtable(vet_1,vet_2){
var tableDiv = document.getElementById("tableDiv");
var table = document.createElement("table");
var tableBody = document.createElement('tbody');
for (var r=0;r<vet_1.length;r++){
var row = document.createElement("tr");
for (var c=0;c<2;c++){
var cell = document.createElement("td");
if (c==0){cell.appendChild(document.createTextNode(vet_1[r]));}
else if(c==1){cell.appendChild(document.createTextNode(vet_2[r]));}
row.appendChild(cell);
}
tableBody.appendChild(row);
}
table.appendChild(tableBody) // append tableBody into the table element
tableDiv.appendChild(table);
}
<div id="tableDiv">
<input type="button" onclick="createtable([1,3,5,7,9],[2,4,6,8,10])" value="Show data">
</div>
You try to append the var table to the tableDiv but the var table is stil empty.
Before append the tableBody to the var table and it will work.
Use id instead of class in your HTML Markup
<div id="tableDiv">
and then use the following code.
function createtable(vet_1,vet_2){
var tableDiv = document.getElementById("tableDiv");
var table = document.createElement("table");
var tableBody = document.createElement('tbody');
for (var r=0;r<vet_1.length;r++){
var row = document.createElement("tr");
for (var c=0;c<2;c++){
var cell = document.createElement("td");
if (c==0){cell.appendChild(document.createTextNode(vet_1[r]));}
else if(c==1){cell.appendChild(document.createTextNode(vet_2[r]));}
row.appendChild(cell);
}
tableBody.appendChild(row);
}
table.appendChild(tableBody);
tableDiv.appendChild(table);
}
First you are accessing the div using id whereas the node is defined with a class.
Secondly, you have to append the body to the table node first, and then append the table to the div selected.
Try this code snippet to move on.
My doubt is quite confusing. I'll break it down as simple as possible.
In HTML page I have a table inside a forEach loop. So multiple tables will occur. But all the tables has same header but rest of the values are different. So I need to set the table header in JavaScript to reduce the HTML code.
function myFunction()
{
var table = document.getElementById("myTable");
var header = table.createTHead();
var row = header.insertRow(0);
var cell = row.insertCell(0);
cell.innerHTML = "<b>Resource Name</b>";
}
This is the code I have used. But id doesn't repeat again. So the table header is only coming for first table.
Any solutions or alternatives for id ?
var tables = document.getElementsByTagName("table");
var len = tables.length, i=0, header, row, cell;
for(;i<len;i++){
header = tables[i].createTHead();
row = header.insertRow(0);
cell = row.insertCell(0);
cell.innerHTML = "<b>Resource Name</b>";
}
http://fiddle.jshell.net/4AmmP/1/
Edit (Using class)
Add class to the tables you want to get affected (say class="myTableClass") and use the below edited code
var tables = document.getElementsByTagName("table");
var len = tables.length, i=0, header, row, cell;
for(;i<len;i++){
/* Check if the table has the class "myTable" */
if(tables[i].className === "myTable") {
header = tables[i].createTHead();
row = header.insertRow(0);
cell = row.insertCell(0);
cell.innerHTML = "<b>Resource Name</b>";
}
}
http://fiddle.jshell.net/4AmmP/2/