How to clone textareas with cloneNode? - javascript

I have 2 tables, and with a button I want to clone the content from tb_new to tb_made:
var tab = document.getElementById('tb_new');
var clone=tab.getElementsByTagName('tr')[1].cloneNode(true);
var table = document.getElementById("tb_made");
table.appendChild(clone);
Everything is cloned fine, except one cell with a textarea.
How can I fix that?
Fiddle is here.

Writing in a <textarea> will only update its value, not its content.
To solve the issue you can do something like this:
function add() {
var tab = document.getElementById('tb_new');
var textAreas = tab.getElementsByTagName("textarea");
for (var i = 0; i < textAreas.length; ++i) {
textAreas[i].innerHTML = textAreas[i].value;
}
var clone = tab.getElementsByTagName('tr')[0].cloneNode(true);
var table = document.getElementById('tb_made');
table.appendChild(clone);
}
<table id="tb_new">
<tr>
<td>
<textarea>Test</textarea>
</td>
<td>
<input>
</td>
</tr>
</table>
<input type="button" value="add" onClick="add()">
<table id="tb_made">
<tr>
<td></td>
</tr>
</table>

Related

How do I add a class to a dynamic table's <td> element?

I have a dynamic table, where I need to sum up the values in a particular column, attaching an id property to each row would be the best way to achieve this. I'm only focused on setting and id for each <td> in every table row.
UPDATE: I have all 4 keys in the <td> but I would like each <td> to match what the value is.
JavaScript:
var prodArr = [];
data = [{SKU: "9372983-382L", retail_price: "11.75", list_price: "3.50", product_name: "Tennis balls"}];
function buildTable(data){
var table = document.getElementById('table');
const arr = data;
for(var obj of arr){
var row = document.createElement('tr');
row.setAttribute('id', Object.values(obj)[0]);
//redo this id stuff to maintain insert integrity for each column in the row.
for(var val of Object.values(obj)){
var col = document.createElement('td');
col.textContent = val;
row.appendChild(col);
col.setAttribute('class', Object.keys(obj));
}
var targetCell = row.getElementsByTagName("td");
targetCell[0].setAttribute('class', 'txtSku');
targetCell[1].setAttribute('class', 'txtRetailPrice');
targetCell[2].setAttribute('class', 'txtListPrice');
targetCell[3].setAttribute('class', 'txtProductName');
var input = document.createElement('input');
input.setAttribute('type', 'text');
//input.setAttribute('')
row.appendChild(input);
table.appendChild(row);
}
}
buildTable(data);
HTML:
<table id="table">
<tr>
<th><label>SKU:</label></th>
<th><label>Retail Price:</label></th>
<th><label>List Price</label></th>
<th><label>Product Name</label></th>
<th><label>Quantity</label></th>
</tr>
<tfoot>
<th><label id = "lblTotal">Total:</label><input type="text" name="txtTotal" id = "txtTotal">
<input type="button" value= "Add" id = "addTotals">
</th>
</tfoot>
</table>
When complete I would like the html markup to look like this:
<table id="table">
<tr>
<td><input type="text" name="txtCustomerName" id = "txtCustomerName"></td>
<td><input type="text" name="txtPhone" id = "txtPhone"></td>
<td><input type="text" name="txtEmail" id= "txtEmail"></td>
<td><input type="text" name="txtRopo" id= "txtRopo"></td>
<td><input type="text" name="txtAddress" id= "txtAddress"></td>
</tr>
<tr>
<th><label>SKU:</label></th>
<th><label>Retail Price:</label></th>
<th><label>List Price</label></th>
<th><label>Product Name</label></th>
<th><label>Quantity</label></th>
</tr>
<tr>
<td id="SKU">9372983-382L</td>
<td id="retailPrice">11.75</td>
<td id="listPrice">3.50</td>
<td id="prodName">Tennis balls</td>
<td id="quantity">1</td>
</tr>
<tfoot>
<th><label id = "lblTotal">Total:</label><input type="text" name="txtTotal" id = "txtTotal">
<input type="button" value= "Add" id = "addTotals">
</th>
</tfoot>
</table>
https://codepen.io/Postman507/pen/mdrKZoY
try this
tr.id("id"+i)
It will not be possible to retrieve more than 1 element using ID. Use a class instead. To add just 1 class, you can use HTMLElement.className="class_name". To add more, you can use HTMLElement.classList.add("class_name")
the problem is really your data element. Try to do something like this:
data= {row1:{names:[],ids:[]},
row2:{labels:[]},
row3:{ids[]}}
obviously filling in the arrays with your data. Then in your js you can build your table and add classes and id's as needed.
The solution was using the tables properties to get the rows, then I was able to access the cell data using this outside of the last for loop but inside the first:
var targetCell = row.getElementsByTagName("td");
targetCell[0].setAttribute('class', 'txtSku');
targetCell[1].setAttribute('class', 'txtRetailPrice');
targetCell[2].setAttribute('class', 'txtListPrice');
targetCell[3].setAttribute('class', 'txtProductName');

JavaScript: text element returning "undefined"

I'm trying to retrieve the entered text in each textbox, by querying and looping through by ID tag.
But when I print what I have retrieved it outputs "undefined".
Looks like your post is mostly code:
</head>
<body bgcolor="#E6E6FA">
<font color=black size=+3>Modifying Sentiment</font>
<table>
<tr>
<td>Text to Save:</td>
</tr>
<tr>
<td colspan="3">
Add positive adjective:
<img Adjective src="http://findicons.com/files/icons/2776/android_icons/96/ic_question_mark.png" alt="question" title="Adjective: is a word naming an attribute of a noun, such as sweet, red, or technical."
width=20 />
<br>
<textarea cols=40 rows=3 id="textbox" ></textarea>
<textarea id="textbox" style="width:512px;height:256px"></textarea>
</td>
</tr>
<tr>
<td>Filename to Save As:</td>
<td><input id="inputFileNameToSaveAs"></input></td>
<td><button onclick="saveTextAsFile()">Save Text to File</button></td>
</tr>
<tr>
<td>Select a File to Load:</td>
<td><input type="file" id="fileToLoad"></td>
<td><button onclick="loadFileAsText()">Load Selected File</button>
<td>
</tr>
</table>
<script type='text/javascript'>
function saveTextAsFile(){
var textBoxes = document.querySelectorAll('textbox');
var textToWrite;
for(var i in textBoxes){
textToWrite = textBoxes[i].value;
window.alert(textToWrite);
}
var textToWrite = document.getElementById("textbox").value;
var textFileAsBlob = new Blob([textToWrite], {type:'text/plain'});
var fileNameToSaveAs = document.getElementById("inputFileNameToSaveAs").value;
}
</script>
I have edited your javascript to point to textarea instead of textbox.
I also modified your for loop as I was getting additional outputs in the console. I also changed your alert to a console.log as jsbin was throwing an error of possible endless loop.
Try this:
function saveTextAsFile()
{
var textBoxes = document.querySelectorAll('textarea');
var textToWrite;
for(var i = 0; i < textBoxes.length; ++i){
textToWrite = textBoxes[i].value;
console.log(textToWrite);
}
textToWrite = document.getElementById("textarea").value;
var textFileAsBlob = new Blob([textToWrite],{type:'text/plain'});
var fileNameToSaveAs = document.getElementById("inputFileNameToSaveAs").value;
}
Trying using #textbox as this refers to the ID of the dom elements
Actually each id value in an html document should be unique. In your HTML code, I can see two id parameter with the same value "textbox". Try to change the first to "textbox-1" or whatever make sense to you but don't repeat the same value for id property and it should work.

Duplicating a div in html on a button click using javascript

I am trying to duplicate a whole div on a button click. I've used javascript clone() in order to duplicate the div. I've found the code to do the same here.
I tried the same way. But I didn't get the result. Can anyone help me with this?
Here is my code
html:
<tr>
<div id="duplicater">
<tr>
<td>Service Type:</td>
<td><input type="text" name="servicetype" id="servicetype"></td>
</tr>
<tr>
<td>Amount:</td>
<td><input type="text" name="amount" id="amount"></td>
</tr>
</div>
<tr><td><button id="button" onlick="duplicate()">Add More</button></td></tr>
</tr>
Javascript:
<script>
function duplicate()
{
var i = 0;
var original = document.getElementById('duplicater'); //alert("hi");
var clone = original.cloneNode(true); // "deep" clone
clone.id = "duplic" + ++i; // there can only be one element with an ID
//original.parentNode.appendChild(clone);
document.body.appendChild(clone);
}
jsfiddle
Your markup is invalid. tr element can't have div child. div element can't have tr child. The markup should be something like:
<tr id="service">
<td>
<span>Service Type:</span>
<input type="text" name="servicetype" id="servicetype">
</td>
<td>
<span>Amount:</span>
<input type="text" name="amount" id="amount">
</td>
</tr>
Also the attribute name is onclick not onlick. In the jsFiddle you choose one of the no wrap ... options otherwise JS interpreter can't find your function.
The i variable should be defined outside of the duplicate function otherwise the result is always duplic1, you could also use the length of the rows instead of a counter. Here is an example using insertBefore for inserting the cloned element before the last row:
function duplicate() {
var original = document.getElementById('service');
var rows = original.parentNode.rows;
var i = rows.length - 1;
var clone = original.cloneNode(true); // "deep" clone
clone.id = "duplic" + (i); // there can only be one element with an ID
original.parentNode.insertBefore(clone, rows[i]);
}
http://jsfiddle.net/4vgrvnn5/
Note that the descendant elements of the cloned element have IDs and your current code/logic doesn't consider this.
Your markup should be like the following. i.e table rows should only contain table cells (<th>,<td>).
<table> should not have <div>'s as direct child, For grouping <td> elements you can use <tbody>
<table>
<tfoot>
<tr>
<td>
<button id="addmore" onclick="duplicate()">Add More</button>
</td>
</tr>
</tfoot>
<tbody id="service">
<tr>
<td>Service Type:
<input type="text" name="servicetype" id="servicetype" />
</td>
</tr>
<tr>
<td>Amount:
<input type="text" name="amount" id="amount" />
</td>
</tr>
</tbody>
</table>
Corresponding script will be:
var i = 0;
function duplicate() {
var table = document.querySelector("table"),
original = document.getElementById('service'),
clone = original.cloneNode(true); // "deep" clone
clone.id = "duplic" + ++i; // there can only be one element with an ID
table.appendChild(clone);
}
You have a typo in the onclick as pointed out in comments.
The counter should be outside the function
JSFiddle wraps the script in an onload function if it is set to run onload, so inline handlers will not work. You should either set the fiddle script to no-wrap or explicitly declare the function to be global like window.duplicate = function(){}.
Updated Fiddle

Add rows to a html table from a textbox value

I want to copy the first row into the same table as many times as you type in, in a textbox.
<table id='table1'>
<tr>
<td>A</td><td>B</td><td>C</td>
</tr>
<tr id="row">
<td>1</td><td>2</td><td>3</td>
</tr>
<table>
<input id="Button1" type="button" value="button" onclick="showRow()"/>
<input id="Text1" type="text" />
<script>
function showRow() {
var header = Array();
$("#row").each(function (i) {
header[i] = $(this).text();
})
alert(header);
}
</script>
So I have created an array of the first row that alerts when you click the button.
An example of my question:
If i type 5 in the textbox and click on the button the table should look like this:
ABC
123
123
123
123
123
Is this possible?
I've made the class row rather than the id, so that we can target it (clone() would prevent duplicate ids anyway.)
You can just store the row as a jQuery object and then use a for() loop to clone that object and append it. Use the value entered in the textbox within your loop:
var $tbl = $('#table1'), origRow = $tbl.find('.row').first();
$('#Button1').on('click', function(){
var num = $('#Text1').val();
$tbl.find('.row').remove();
for(i=0; i<num; i++){
var newRow = origRow.clone();
$tbl.append(newRow);
}
});
JSFiddle
I wasn't sure whether you would want the table to empty each time or just add the rows on to the end. If you want the rows to be added to the end, just remove the $tbl.find('.row').remove(); line.
Try thisLink
<table id='table1'>
<tr>
<td>A</td><td>B</td><td>C</td>
</tr>
<tr class="row">
<td>1</td><td>2</td><td>3</td>
</tr>
<table>
<input id="Button1" type="button" value="button" onclick="showRow()"/>
<input id="Text1" type="number" />
$(document).ready(function () {
$('#Button1').click(function(){
var num = $('input[id="Text1"]').val();
alert(num);
for(var i=0;i<num;i++){
$('table[id="table1"]').append(' <tr class="row"><td>1</td><td>2</td><td>3</td></tr>');
}
});
});
Ofc it is, just parse the textbox val() or value as int and to a for() loop to that number
Using jquery there is a lot of ways to do it. Look at these jQuery functions :
clone()
appendTo()
insertAfter()
You can try this one:
Logic is simple: Get the count from textbox, create row count no of times and append that row after last row in table. $('#row').html() will give inner element of first row.
<script>
function showRow() {
var i, num = $('#Text1').val();
for(i=0; i<num; i++){
$('#table1 > tbody:last').append('<tr id=row'+i+1+'>'+$('#row').html()+'</tr>');
}
}
</script>
DEMO Link
LIVE DEMO
Try this:
Change your row to class.
HTML:
<table id='table1'>
<tr>
<td>A</td><td>B</td><td>C</td>
</tr>
<tr class="row">
<td>1</td><td>2</td><td>3</td>
</tr>
<table>
<input id="Button1" type="button" value="button" />
<input id="Text1" type="text" />
JQUERY:
$('#Button1').on('click',function(e) {
limit = $("#Text1").val();
for(i=0;i<parseInt(limit);i++) {
strText = $(".row").first().clone();
strText.appendTo("#table1");
}
});

creating table within table by pressing button

I currently have a table and in one of the <td>, I have input type of checkbox. where if user clicks on it, it will create different table.
<div style="padding-left:170px;">
<table width="80%" border="1" padding-left:50px>
<tr>
<td>
<table border="1" style="float:left">
<th>Portal01</th>
<tr>
<td style= "padding:12px;" align="left" >
<input type="test0" id = "test0" name="liveDiff" onchange = "expandService()"> blah_0
</td>
<td>
blah_1
</td>
<td>
blah_2
</td>
</tr>
</table>
</td>
</tr>
</table>
I have it set up where if user clicks on checkbox next to blah_0, it should create different table within this table. I am not sure if this is possible with JavaScript and if not, what would be alternate way to approach this situation.
it is possible.
function expandService(){
document.getElementById('the_id_of_the_td_that_will_contain_the_new_table').innerHTML =
'<table><tr>...</tr></table>';
}
Another way is to use appendChild(), here is an example:
function expandService(chkId, tblId, totalRows, totalCols){
var tbl = document.createElement('table');
tbl.id = tblId;
var row, col, spn;
for(var i=0; i<totalRows; i++){
row = document.createElement('tr');
for(var j=0; j<totalCols; j++){
col = document.createElement('td');
spn = document.createElement('span');
spn.innerHTML = 'your-text';
col.appendChild(spn);
row.appendChild(col);
}
tbl.appendChild(row);
}
var chk = document.getElementById(chkId);
// td is the parent of checkbox
chk.parentNode.appendChild(tbl);
}
Sample usage:
<input type="checkbox" id="test0" name="liveDiff" onchange="expandService(this.id, 'your-table-id', 5, 4)">
It creates a table with 5 rows and 4 columns.
This is possible with javascript. One potential way to go is to use innerHTML. Use jQuery or just document.getElementByID to select the element that corresponds to your cell and insert a table inside of it. Here is an example fiddle using your code as a base.
<div style="padding-left:170px;">
<table width="80%" border="1" padding-left:50px>
<tr>
<td>
<table border="1" style="float:left">
<th>Portal01</th>
<tr>
<td id="foo" style= "padding:12px;" align="left" >
<input type="test0" id = "test0" name="liveDiff"> blah_0
</td>
<td>
blah_1
</td>
<td>
blah_2
</td>
</tr>
</table>
</td>
</tr>
</table> ​
js:
var makeTable = function(contents){
return '<table><td>' + contents + '</td></table>'
}
document.getElementById("test0").onchange = function(){
document.getElementById("foo").innerHTML = makeTable("foo")
}
​

Categories

Resources