I have a function which creates a DOM element onClick. That Element contains inputs with array names.
At the start I already have one element (the same like those which I create onClick).
<tbody id="elementsBody">
<tr id="element1"> // 1 becomes 2 and so on when new element is added
<td>
<input type="hidden" name="numbers[]" value="1" /> // 1 becomes 2 and so on when new element is added
</td>
<td>
<input type="text" name="titles[]" />
</td>
</tr>
// Newly created Elements goes in here!!!
</tbody>
This is my function which creates more elements like the one above.
And also creates a Delete Button DIV for this newly created element.
function addElement() {
var elementsBody = document.getElementById('elementsBody');
var numbers = document.forms[1].elements['numbers[]'];
var number = numbers.length+1;
if (isNaN(number)) {
var number = 2;
}
var numberInput = '<td><input type="hidden" name="numbers[]" value="'+ number + '" /></td>';
var titleTd = '<td><input type="text" name="titles[]" /></td>';
// This is the Delete Button DIV
// I want to create a function (deleteElement) which Removes This Element
var deleteButton = '<td><div onClick="deleteElement('+ number + ')">Delete Element</div></td>';
elementsBody.insertAdjacentHTML('beforeend', '<tr id="element' + number + '">' + numberInput + titleTd + deleteButton + '</tr>');
}
I want to create a function (deleteElement) which Removes this Added Element onClick.
After Removing an Element, I want that function to reorder all the elements values and ID's. For example if I remove the Element number 2, the value and ID of the third Element must become 2.
Not JQuery.
Please Help me with that!
You are going to have build an array of all elements involved.
Delete From the target to the end.
Delete the target from the array
Renumber in the array
Then add what's left back.
If it was me I'd be looking at having an other ElementID (DisplayElmentID ?) then you wouldn't have to do all this stuff. ie leave the ID attibute used by the DOM the heck alone
Thanks #Esailija for help! Solution (fiddle):
function addElement() {
var elementsBody = document.getElementById('elementsBody');
var numberInput = '<td><input type="hidden" name="numbers[]" value="" /></td>';
var titleTd = '<td><input type="text" name="titles[]" /></td>';
var deleteButton = '<td><div onClick="this.parentNode.parentNode.parentNode.removeChild(this.parentNode.parentNode); update();">Delete Element</div></td>';
elementsBody.insertAdjacentHTML('beforeend', '<tr>' + numberInput + titleTd + deleteButton + '</tr>');
update();
}
function update() {
var inputs = document.getElementById('elementsBody').querySelectorAll("input[type='text']");
[].forEach.call(inputs, function(input, index) {
input.value = index + 1;
});
}
<table>
<tbody id="elementsBody">
<tr>
<td>
<input type="hidden" name="numbers[]" value="1" />
</td>
<td>
<input type="text" name="titles[]" />
</td>
</tr>
</tbody>
</table><button onclick="addElement();">add</button>
Related
I have a function which creates a DOM element onClick. That Element contains inputs with array names.
At the start I already have one element (the same like those which I create onClick).
<tbody id="elementsBody">
<tr id="element1"> // 1 becomes 2 and so on when new element is added
<td>
<input type="hidden" name="numbers[]" value="1" /> // 1 becomes 2 and so on when new element is added
</td>
<td>
<input type="text" name="titles[]" />
</td>
</tr>
// Newly created Elements goes in here!!!
</tbody>
This is my function which creates more elements like the one above.
And also creates a Delete Button DIV for this newly created element.
function addElement() {
var elementsBody = document.getElementById('elementsBody');
var numbers = document.forms[1].elements['numbers[]'];
var number = numbers.length+1;
if (isNaN(number)) {
var number = 2;
}
var numberInput = '<td><input type="hidden" name="numbers[]" value="'+ number + '" /></td>';
var titleTd = '<td><input type="text" name="titles[]" /></td>';
// This is the Delete Button DIV
// I want to create a function (deleteElement) which Removes This Element
var deleteButton = '<td><div onClick="deleteElement('+ number + ')">Delete Element</div></td>';
elementsBody.insertAdjacentHTML('beforeend', '<tr id="element' + number + '">' + numberInput + titleTd + deleteButton + '</tr>');
}
I want to create a function (deleteElement) which Removes this Added Element onClick.
After Removing an Element, I want that function to reorder all the elements values and ID's. For example if I remove the Element number 2, the value and ID of the third Element must become 2.
Not JQuery.
Please Help me with that!
You are going to have build an array of all elements involved.
Delete From the target to the end.
Delete the target from the array
Renumber in the array
Then add what's left back.
If it was me I'd be looking at having an other ElementID (DisplayElmentID ?) then you wouldn't have to do all this stuff. ie leave the ID attibute used by the DOM the heck alone
Thanks #Esailija for help! Solution (fiddle):
function addElement() {
var elementsBody = document.getElementById('elementsBody');
var numberInput = '<td><input type="hidden" name="numbers[]" value="" /></td>';
var titleTd = '<td><input type="text" name="titles[]" /></td>';
var deleteButton = '<td><div onClick="this.parentNode.parentNode.parentNode.removeChild(this.parentNode.parentNode); update();">Delete Element</div></td>';
elementsBody.insertAdjacentHTML('beforeend', '<tr>' + numberInput + titleTd + deleteButton + '</tr>');
update();
}
function update() {
var inputs = document.getElementById('elementsBody').querySelectorAll("input[type='text']");
[].forEach.call(inputs, function(input, index) {
input.value = index + 1;
});
}
<table>
<tbody id="elementsBody">
<tr>
<td>
<input type="hidden" name="numbers[]" value="1" />
</td>
<td>
<input type="text" name="titles[]" />
</td>
</tr>
</tbody>
</table><button onclick="addElement();">add</button>
I have created a table dynamically using Javascript .i am able to add rows but not able to delete.
MyHtml:
<div id="Mutipletextboxhandler" style="text-align: center;" class="step" name="Mutipletextboxhandler">
</div>
<input id="Hidden" type="hidden" runat="server" value="" />
<input id="btnAddexisting" type="button" value="Insert item" onclick="AddmultipleTextBox()" />
And my Javascript:
<script type="text/javascript">
function AddmultipleTextBox() {
var div = document.createElement('DIV');
div.innerHTML = GetDynamicmultipleTextBox("");
document.getElementById("Mutipletextboxhandler").appendChild(div);
}
function GetDynamicmultipleTextBox(value) {
return '<table id="d"><tr><td><input name = "mDynamicTextBox1" type="text" value = "' + value + '" /></td><td><input name = "mDynamicTextBox2" type="text" value = "' + value + '" /></td'+
'<td><input name = "mDynamicTextBox3" type="text" value = "' + value + '" /></td>'+
'<td><input type="button" value="Remove" onclick = "RemovemultipleTextBox(this)" /></td>' +
'</tr></table>'
}
**//Problamatic Function is below:**
function RemovemultipleTextBox(div) {
document.getElementById("Mutipletextboxhandler").removeAttributeNode(div);
}
function RecreateDynamicmultipleTextboxes() {
var mvalues = eval('<%=mValues%>');
if (mvalues != null) {
var html = "";
for (var i = 0; i < mvalues.length; i++) {
html += "<div>" + GetDynamicmultipleTextBox(mvalues[i]) + "</div>";
}
document.getElementById("Mutipletextboxhandler").innerHTML = html;
}
}
window.onload = RecreateDynamicmultipleTextboxes;
</script>
Question-Addition of rows is working fine but when i delete ,then
"NO Such interface supported" Error is coming.
Its working fine if i have no tables and only one texbox.
Somebody please help.
try document.getElementById("Mutipletextboxhandler").removeChild(div)
Update:
you can update your funtion as something like this
function RemovemultipleTextBox(div) {
while((div.tagName != "HTML" || div.tagName != "TABLE") && div.id != "d") {
div = div.parentNode
}
if(div.tagName == "TABLE") {
document.getElementById("Mutipletextboxhandler").removeChild(div.parentNode);
}
}
edit:
Let's redo this with a proper handler.
Step 1: Add a class to your input button and remove the onclick.
<input class="button-remove" type="button" value="Remove" />
Step 2: Add this logic every place you call GetDynamicmultipleTextBox. We create the box into a variable, then select the button out of this box and add an event listener.
var box = GetDynamicmultipleTextBox();
box.querySelector('.button-remove').addEventListener('click', function (event) {
var button = event.target,
div = button.parentNode.parentNode.parentNode.parentNode;
document.getElementById("Mutipletextboxhandler").removeChild(div);
});
Step 3: document.getElementById("Mutipletextboxhandler").appendChild(box);
This is my HTML code:
<table id="display_table"><tr>
<td>No. of Questions: </td>
<td><input type="text" id="questions_num"></td>
</tr><tr>
<td>No. of Options: </td>
<td><input type="text" id="options_num"></td>
</tr></table>
I want to make it such that when the user enters x in the text input (whose id is options_num), x rows will be created. For each new row that is created, there should be a left column and a right column. The left column will contain the "Option" + somenumber, where somenumber refers to the row that has been created, and the right column will create a text input.
This is what I have tried in my JS:
document.getElementById("options_num").onkeyup = function() {
var options_num = parseInt(document.getElementById("options_num").value);
var display_text = '<tr><td>No. of Questions: </td><td><input type="text" id="questions_num"></td></tr><tr><td>No. of Options: </td><td><input type="text" id="options_num"></td></tr>'
for(var i = 1; i <= options_num; i++) {
display_text += "<tr><td>Option " + i + ": </td><td>" + "<input type='text' id='option_" + i + "'</td></tr>";
}
document.getElementById("display_table").innerHTML = display_text;
document.getElementById("options_num").value = options_num.toString();
document.getElementById("options_num").focus();
}
And it works when I first enter a value into the text input (whose id is question_num), but when I change the value, it does not work (it does not do anything). Demo.
So how do I get my JS code to work?
The reason it doesn't work after the first time, is that innerHTML actually destroys event binding. So after you modify table.innerHTML browser completely rebuilds new DOM elements without original onkeyup event listener attached.
I would recommend to change HTML a little, it will make everything simpler:
<table id="display_table">
<tbody>
<tr>
<td>No. of Questions:</td>
<td><input type="text" id="questions_num"/></td>
</tr>
<tr>
<td>No. of Options:</td>
<td><input type="text" id="options_num"/></td>
</tr>
</tbody>
<tbody id="rows"></tbody> <!-- append generated HTML here -->
</table>
and modified JS:
document.getElementById("options_num").onkeyup = function () {
var options = document.getElementById("options_num"),
optionsNum = parseInt(options.value),
tbody = document.getElementById("rows"),
rows = '';
for (var i = 1; i <= optionsNum; i++) {
rows += "<tr><td>Option " + i + "</td><td>" + "<input type='text' id='option_" + i + "'</td></tr>";
}
tbody.innerHTML = rows;
options.focus();
}
So the idea is to put table rows into tbody and it makes easy adding new and replacing replacing old rows.
Demo: http://jsfiddle.net/8yYyW/2/
Sorry, if this is too basic.
I am trying to add rows to a table if current number of rows are
less than a user's demand.
At the same time, I need to delete the
extra rows if current number of rows are more than a user's need.
My code is working, but I think it does not make a lot of sense. So I am wondering if anyone could correct my mistakes and make my code more reasonable. (I was trying to use two indices to control this add or remove activity. One index check the current existed elements and get the difference between user's new input. Then do the add or remove movements. But I failed to do this.)
In addition, is it possible to adjust the width of added <td> without changing the shape of the first table row? Thanks for your help! Here is a demo.
HTML
<form method="post" id="form1" action=index.html>
<table class="tab tab_Application" border="0">
<tr>
<th>
<label for="id_noa">Number of Applications:</label>
</th>
<td>
<select name="noa" id="id_noa">
<option value="">Make a selection</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
</td>
</tr>
<tr id='noa_header' style="display:none">
<th>App#</th>
<th>Month</th>
<th>Day</th>
<th>Mass Applied (kg/hA)</th>
<th>Slow Release (1/day)</th>
</tr>
</table>
</form>
JS
$(document).ready(function () {
var i = 1
$('#id_noa').change(function () {
var total = $(this).val()
$('#noa_header').show()
//I was trying to use two indices to control this add or remove activity. One index check the current existed elements and get the difference between user's new input. Then do the add or remove movements. But I failed to do this.
while (i <= total) {
$('.tab_Application').append('<tr class="tab_noa1"><td><input type="text" size="5" value="' + i + '"/></td><td><input type="text" size="5" name="mm' + i + '" id="id_mm' + i + '""/></td><td><input type="text" size="5" name="dd' + i + '" id="id_dd' + i + '""/></td><td><input type="text" size="5" name="ma' + i + '" id="id_ma' + i + '""/></td><td><input type="text" size="5" name="sr' + i + '" id="id_sr' + i + '" value="0""/></td></tr>');
i = i + 1;
}
while (i-1 > total) {
$(".tab_Application tr:last").remove();
i=i-1
}
$('</table>').appendTo('.tab_Application');
})
});
I took the ideas presented by #B3aT, edited, and fleshed out to make this (available at my fork of OP's jsfiddle:
var row_i = 0;
function emptyRow() {
row_i++;
this.obj = $("<tr></tr>");
this.obj.append('<td><input type="text" size="5" value="' + row_i + '"/></td>');
this.obj.append('<td><input type="text" size="5" name="mm' + row_i + '" id="id_mm' + row_i + '""/></td>');
this.obj.append('<td><input type="text" size="5" name="dd' + row_i + '" id="id_dd' + row_i + '""/></td>');
this.obj.append('<td><input type="text" size="5" name="ma' + row_i + '" id="id_ma' + row_i + '""/></td>');
this.obj.append('<td><input type="text" size="5" name="sr' + row_i + '" id="id_sr' + row_i + '" value="0""/></td>');
}
function refresh(new_count) {
if(new_count > 0) {
$("#noa_header").show();
}
else {
$("#noa_header").hide();
}
var old_count = parseInt($('tbody').children().length);
var rows_difference = parseInt(new_count) - old_count;
if (rows_difference > 0)
{
for(var i = 0; i < rows_difference; i++)
$('tbody').append((new emptyRow()).obj);
}
else if (rows_difference < 0)//we need to remove rows ..
{
var index_start = old_count + rows_difference + 1;
$('tr:gt('+index_start+')').remove();
row_i += rows_difference;
}
}
$(document).ready(function () {
$('#id_noa').change(function () {
refresh( $(this).val() );
})
});
The reason the emptyRow function is so long is that I wanted to make the number of columns easy to manipulate. Each column is appended individually, so changing the default pattern is simple.
In the html, I had to add the thead and tbody tags as described in #B3aT's answer. The thead includes the first two rows, because row 1 is the select box and row 2 is the actual header for the table. The tbody is empty to start.
As far as changing styles for individual rows (like adjusting column width), you'd be better off not using a table. Table-like behavior can be as simple as using float:left in your column style, making sure to place a div with clear:both at the end of each row.
At these situations jQuery excels, let us play with all sort of selectors.
First you need to separate the header and body of the table (thead and tbody).
(Code not tested).
function refresh(new_count) {
//how many applications we have drawed now ?
var old_count = parseInt($('tbody').children().count());
//the difference, we need to add or remove ?
var rows_difference = parseInt(new_count) - old_count;
//if we have rows to add
if (rows_difference > 0)
{
//$('tbody').append() or prepend() new empty rows based on your pattern with a loop
}
else if (rows_difference < 0)//we need to remove rows ..
{
var index_start = old_count - rows_difference;//for the LAST X rows
$('tr:gt('+index_start+')').remove();
}
}
I want the variable inputname to go up by 1 every time a new <input /> is added
e.g.
<input name="1" />
<input name="2" />
<input name="3" />
---html---
<p class="add">Add</p>
<div class="added"></div>
---jQuery/javascript---
$(document).ready(function() {
$("p.add").click(function() {
var inputname = somevar;
var added = "<input type=\"text\" name=\""+inputname+"\" />";
$("div.added").append(added);
});
});
here it is on jsfiddle.net if it helps -> http://jsfiddle.net/gamepreneur/54kzw/
Set inputname like this:
var inputname = $('.added input').length + 1;
This gets the total number of added inputs and increments by one, resulting in the new name.
Change the variable scope
Use this:
// declare your variable here so it exists throughout every call, instead of being
// delcared new with every call.
var inputname = somevar;
$(document).ready(function() {
$("p.add").click(function() {
var added = "<input type=\"text\" name=\""+(inputname++)+"\" />";
$("div.added").append(added);
});
});
Alternatives:
Grab the number of inputs ($('div.added input').length) and use that for a counter.
Grab the id of the last item $('div.added input:last').prop('name')) and increment it.
You need to declare inputname in the global scope so that it lasts longer than just the duration of the click function and then you need to increment it each time you use it.
I modified your fiddle to this: http://jsfiddle.net/jfriend00/54kzw/2/
var inputname = 1;
$(document).ready(function() {
$("p.add").click(function() {
var added = "<input type='text' name='" + inputname++ + "' />";
$("div.added").append(added);
});
});
Try
$(document).ready(function() {
$("p.add").click(function() {
var inputname = $('input', $("div.added")).length + 1;
var added = "<input type=\"text\" name=\"" + inputname + "\" />";
$("div.added").append(added);
});
});
Consider adding some other selectors to choose those inputs (like a class selector)