Reordering <tr> not working for newly append <tr> [duplicate] - javascript

This question already has answers here:
Event binding on dynamically created elements?
(23 answers)
Closed 3 years ago.
I am trying to add a row dynamically by clicking the add button and later i am trying to move up and down by clicking the respected buttons... In the code i amhaving 3 static rows, the data typed in the textbox goes up and down perfectly. But regarding the ROW which i have dynamically created, there is no action.
I came to know that javascript wont get action for dynamically created elements.. If so, what i have to do solve this issue...Thanks...
var html = '<tr><td>row 4</td><td><input type="text" name="uname"></td><td><input type="button" value="move up" class="move up" /></td><td><input type="button" value="move down" class="move down" /></td></tr>';
$(function() {
$('#addRow').click(function() {
$('tbody').append(html);
});
$('#mytable input.move').click(function() {
var row = $(this).closest('tr');
if ($(this).hasClass('up'))
row.prev().before(row);
else
row.next().after(row);
});
});
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<table>
<tbody id="mytable">
<tr>
<td>row 1</td>
<td><input type="text" name="uname"></td>
<td><input type="button" value="move up" class="move up" /></td>
<td><input type="button" value="move down" class="move down" /></td>
</tr>
<tr>
<td>row 2</td>
<td><input type="text" name="uname"></td>
<td><input type="button" value="move up" class="move up" /></td>
<td><input type="button" value="move down" class="move down" /></td>
</tr>
<tr>
<td>row 3</td>
<td><input type="text" name="uname"></td>
<td><input type="button" value="move up" class="move up" /></td>
<td><input type="button" value="move down" class="move down" /></td>
</tr>
</tbody>
</table>
<button id="addRow">Add</button>
</body>
</html>
I would like to add new tr with controls dynamically and later i would like to reorder the same by clicking the up and down button and then to get its values in the reordered form..

Use Jquery Event Delegation
$(document).on('click', '#mytable input.move', function() { ... });
var html = '<tr><td>row 4</td><td><input type="text" name="uname"></td><td><input type="button" value="move up" class="move up" /></td><td><input type="button" value="move down" class="move down" /></td></tr>';
$(function() {
$('#addRow').click(function() {
$('tbody').append(html);
});
$(document).on('click', '#mytable input.move', function() {
var row = $(this).closest('tr');
if ($(this).hasClass('up'))
row.prev().before(row);
else
row.next().after(row);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tbody id="mytable">
<tr>
<td>row 1</td>
<td><input type="text" name="uname"></td>
<td><input type="button" value="move up" class="move up" /></td>
<td><input type="button" value="move down" class="move down" /></td>
</tr>
<tr>
<td>row 2</td>
<td><input type="text" name="uname"></td>
<td><input type="button" value="move up" class="move up" /></td>
<td><input type="button" value="move down" class="move down" /></td>
</tr>
<tr>
<td>row 3</td>
<td><input type="text" name="uname"></td>
<td><input type="button" value="move up" class="move up" /></td>
<td><input type="button" value="move down" class="move down" /></td>
</tr>
</tbody>
</table>
<button id="addRow">Add</button>

My personal preferred is to write Javascript always in vanilla JS. So I rewrote the answer in vanilla JS.
//define table
const table = document.getElementById('table');
//set eventlisteners for the up,down and add buttons
Array.from(document.getElementsByClassName('table__move-up')).map(button => button.addEventListener('click' , () => moveRowUp(button.parentNode.parentNode)));
Array.from(document.getElementsByClassName('table__move-down')).map(button => button.addEventListener('click' , () => moveRowDown(button.parentNode.parentNode)));
Array.from(document.getElementsByClassName('add__row')).map(button => button.addEventListener('click' , () => addRow(table)));
//the function to move the row up
function moveRowUp(row) {
if (row == table.children[0]) return;
row.parentNode.insertBefore(row, row.previousElementSibling);
}
//the function to move the row down
function moveRowDown(row) {
if (row == table.children[table.children.length - 1]) return;
row.parentNode.insertBefore(row.nextElementSibling, row);
}
//the function to add a new row to the table
function addRow() {
//add new tr
const row = document.createElement('TR');
table.appendChild(row);
//add a new column with inside the text. For example row 6
const tableNameCell = document.createElement('TD');
row.appendChild(tableNameCell);
tableNameCell.innerText = `row ${table.children.length}`;
//add a new column with inside the text input
const inputCell = document.createElement('TD');
row.appendChild(inputCell);
const inputText = document.createElement('INPUT');
inputCell.appendChild(inputText);
inputText.type = 'text';
//add a new column with inside the move up button
const moveUpCell = document.createElement('TD');
row.appendChild(moveUpCell);
const inputButtonUp = document.createElement('INPUT');
moveUpCell.appendChild(inputButtonUp);
inputButtonUp.type = 'button';
inputButtonUp.value = 'move up';
inputButtonUp.addEventListener('click' , () => moveRowUp(inputButtonUp.parentNode.parentNode));
//add a new column with inside the move down button
const moveDownCell = document.createElement('TD');
row.appendChild(moveDownCell);
const inputButtonDown = document.createElement('INPUT');
moveDownCell.appendChild(inputButtonDown);
inputButtonDown.type = 'button';
inputButtonDown.value = 'move down';
inputButtonDown.addEventListener('click' , () => moveRowDown(inputButtonDown.parentNode.parentNode));
}
<body>
<table>
<tbody id="table">
<tr>
<td>row 1</td>
<td><input type="text"></td>
<td><input type="button" value="move up" class="table__move-up" /></td>
<td><input type="button" value="move down" class="table__move-down" /></td>
</tr>
<tr>
<td>row 2</td>
<td><input type="text"></td>
<td><input type="button" value="move up" class="table__move-up" /></td>
<td><input type="button" value="move down" class="table__move-down" /></td>
</tr>
<tr>
<td>row 3</td>
<td><input type="text"></td>
<td><input type="button" value="move up" class="table__move-up" /></td>
<td><input type="button" value="move down" class="table__move-down" /></td>
</tr>
</tbody>
</table>
<button class="add__row">Add</button>
</body>

Related

Passing the value from an input ID through a function

Within my PHP I have a while loop that is gong through the entries in the DB.
I would like to have a input where I can change a columns value.
<td><input type="text" id="cardId-<?php echo $cardId; ?>" /></td>
<td><button type="button" class="btn btn-primary mb-2" onclick="update(<!-- pass cardId-0.val() -->)">Submit</button></td>
My JS
function update(id) {
var inputVal = document.getElementById("cardId-<?php echo $cardId; ?>").value;
console.log(inputVal);
}
How can I make this work. No matter which one I click on, it only passes the first value in the first box.
Delegation is a good idea
Please change
"table tbody"
and "mb-2"
to better selectors matching your actual markup
window.addEventListener("load",function() {
document.querySelector("table tbody").addEventListener("click",function(e) {
const tgt = e.target;
if (tgt.classList.contains("mb-2")) { // if tgt has a class mb-2
const inp = tgt.closest("tr").querySelector("input[id^=card]"); // starting with "card"
console.log(inp.id,inp.value);
}
});
});
<table>
<tbody>
<tr>
<td><input type="text" id="cardId-1" /></td>
<td><button type="button" class="btn btn-primary mb-2">Submit</button></td>
</tr>
<tr>
<td><input type="text" id="cardId-2" /></td>
<td><button type="button" class="btn btn-primary mb-2">Submit</button></td>
</tr>
<tr>
<td><input type="text" id="cardId-3" /></td>
<td><button type="button" class="btn btn-primary mb-2">Submit</button></td>
</tr>
<tr>
<td><input type="text" id="cardId-4" /></td>
<td><button type="button" class="btn btn-primary mb-2">Submit</button></td>
</tr>
</tbody>
</table>

Javascript table tr deletes on tr (Dynamic tr delete and re-generate tr id)

I have a code which deletes a tr and regenerate tr's id sequence wise.
But It works on tr click and I want to do this on a button click. How I do this.
Here is my code
Here tr id is dynamic and a combination of alphabets and numbers
< script type = "text/javascript" >
$("tr").click(function() {
$(this).nextAll().each(function() {
var id = $(this).prop("id", function(index, idvalue) {
console.log(idvalue);
myArray = idvalue.split(/[0-9]+/);
var id_text = myArray[0];
console.log(id_text);
var id_num = idvalue.replace(/^\D+/g, '');
console.log(id_num);
var new_no = id_num - 1;
var new_id = id_text + '' + new_no;
return new_id;
});
});
$(this).remove();
});
<
/script>
<table>
<tbody>
<tr id='a1'>
<td>Row 1</td>
<td><input type="button" id="btn" name="btn" value="delete" /></td>
</tr>
<tr id='a2'>
<td>Row 2</td>
<td><input type="button" id="btn" name="btn" value="delete" /></td>
</tr>
<tr id='a3'>
<td>Row 3</td>
<td><input type="button" id="btn" name="btn" value="delete" /></td>
</tr>
<tr id='a4'>
<td>Row 4</td>
<td><input type="button" id="btn" name="btn" value="delete" /></td>
</tr>
<tr id='a5'>
<td>Row 5</td>
<td><input type="button" id="btn" name="btn" value="delete" /></td>
</tr>
</tbody>
</table>
First thing is - Ideally you shouldn't put the same id values of all the rows. id is for unique identifier in the entire DOM.
Next is - As you are doing with $(tr), it will take the entire row.
You can try something like:
$("[name=btn]").click(function () {
$(this).parents('tr').remove();
});
to remove the desired row on click of the button.
For rest of the manipulations, you can add your logic.

New table row is not creating using JQuery clone method

I have a table in in that table I have a button for adding new row .In that table I want to dynamically add new row when user will click the add row button. I but it is not working. The HTML and JQuery code is there in JSFiddle . Please suggest.
<table id="myTable" border="1">
<tr>
#*<td>SR</td>*#
<td>Name</td>
<td>Age</td>
<td>Delete?</td>
<td>Add</td>
</tr>
<tr>
#*<td>1</td>*#
<td><input size=25 type="text" id="nmbox" /></td>
<td><input size=25 type="text" id="agbox" /></td>
<td><input type="button" id="delRow" value="Delete" onclick="deleteRow(this)" /></td>
<td><input type="button" id="addRow" value="Add " onclick="insRow()" /></td>
</tr>
</table>
var new_row1 = $('#mytable tr:last').clone();
$('#mytable').append(new_row1);
1) id selector mismatched $('#myTable tr:last'). caps T
2) id should be unique for each element .
function insRow(){
var new_row1 = $('#myTable tr:last').clone();
$('#myTable').append(new_row1);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="myTable" border="1">
<tr>
#*<td>SR</td>*#
<td>Name</td>
<td>Age</td>
<td>Delete?</td>
<td>Add</td>
</tr>
<tr>
#*<td>1</td>*#
<td><input size=25 type="text" /></td>
<td><input size=25 type="text" /></td>
<td><input type="button" value="Delete" onclick="deleteRow(this)" /></td>
<td><input type="button" value="Add " onclick="insRow()" /></td>
</tr>
</table>
To add child elements into cloned one without jQuery:
clone = ElementTo.cloneNode();
while (ElementToBeCloned.firstChild){
clone.appendChild(ElementToBeCloned.lastChild);
}

remove readonly attribute from multiple fields on clicking button in jquery

I have a table with the details of the student. These fields are readonly field and can be edited on clicking the edit button. But I am having problem to select all the input fields of that row at once on clicking the edit button.
Here is my html code
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Checklist</th>
<th>Id</th>
<th>Student Name</th>
<th>Address</th>
<th>Phone</th>
<th>Class</th>
<th colspan="2">Actions</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<input type="checkbox" id="editCheck" class="btn1" />
<input type="checkbox" id="deleteCheck" />
</td>
<td>1</td>
<td><input type="text" class="form-control item" readonly="readonly" /></td>
<td><input type="text" class="form-control item" readonly="readonly" /></td>
<td><input type="text" class="form-control item" readonly="readonly" /></td>
<td>12</td>
<td><button type="button" class="btn btn-info btn-xs" id="btn1">Edit</button></td>
<td><button type="button" class="btn btn-danger btn-xs" id="dbtn1">Delete</button></td>
</tr>
<tr>
<td>
<input type="checkbox" id="editCheck" class="btn2" />
<input type="checkbox" id="deleteCheck" />
</td>
<td>1</td>
<td><input type="text" class="form-control item" readonly="readonly" /></td>
<td><input type="text" class="form-control item" readonly="readonly" /></td>
<td><input type="text" class="form-control item" readonly="readonly" /></td>
<td>12</td>
<td><button type="button" class="btn btn-info btn-xs" id="btn2">Edit</button></td>
<td><button type="button" class="btn btn-danger btn-xs" id="dbtn2">Delete</button></td>
</tr>
</tbody>
</table>
And here is the jquery. I have made the checkbox selected on pressing the edit button.
$(document).ready(function(){
$('.btn.btn-info.btn-xs').click(function(){
var newClass = $(this).attr('id');
$('.'+newClass).prop('checked','true');
});
});
</script>
You can simply add this into your click handler
$(this).closest('tr').find('input').removeAttr('readonly');
Which finds the tr containing the clicked button, locates all of its input elements, and removes their readonly attribute.
Live example: http://jsfiddle.net/zxsq0m5n/
Incidentally, you could use the same trick to locate your checkbox, negating the need to tie it together with the edit button using id/class
$('.btn.btn-info.btn-xs').click(function(){
var $tr = $(this).closest('tr')
$tr.find('input:checkbox').first().prop('checked','true');
$tr.find('input').removeAttr('readonly');
});
Live example: http://jsfiddle.net/zxsq0m5n/1/
$('.btn.btn-info.btn-xs').on('click', function (e) {
var $btn = $(e.currentTarget),
newClass = '.' + $btn.attr('id');
$btn
.parents('tr')
.find(newClass).prop('checked', true)
.end()
.find('input').removeAttr('readonly');
});
You can update your code to following
Logic - Get the tr row i.e. parent of parent of input -> tr -> td -> button. Then for that row find all the input and remove the attribute. Please note you can add conditions if required
$('.btn.btn-info.btn-xs').click(function(){
var newClass = $(this).attr('id');
$('.'+newClass).prop('checked','true');
$(this).parent().parent().find("input").each(function(){
$(this).removeAttr("readonly");
});
});

How to get button input to display on textarea

<body>
<center>
<h1>Online Calculator</h1>
<hr/>
<form name="frmCalculator" action="">
<table border="1" cellpadding="1" cellspacing="1" width="30%">
<tr>
<td colspan="4"><textarea style="width:100%" name="txtResult"></textarea></td>
</tr>
<tr>
<td colspan="4"><input type="reset" style="width:100%"/></td>
</tr>
<tr>
<td><input type="button" value=" 7 " onclick="7"/></td>
<td><input type="button" value=" 8 " onclick="8"/></td>
<td><input type="button" value=" 9 " onclick="9"/></td>
<td><input type="button" value=" + " onclick="plus()"/></td>
</tr>
<tr>
<td><input type="button" value=" 4 " onclick="4"/></td>
<td><input type="button" value=" 5 " onclick="5"/></td>
<td><input type="button" value=" 6 " onclick="6"/></td>
<td><input type="button" value=" - " onclick="subtract()"/></td>
</tr>
<tr>
<td><input type="button" value=" 1 " onclick="1"/></td>
<td><input type="button" value=" 2 " onclick="2"/></td>
<td><input type="button" value=" 3 " onclick="3"/></td>
<td><input type="button" value=" * " onclick="times()"/></td>
</tr>
<tr>
<td><input type="button" value=" 0 " onclick="0"/></td>
<td><input type="button" value=" . " onclick="."/></td>
<td><input type="button" value=" = " onclick="total()"/></td>
<td><input type="button" value=" / " onclick="divide()"/></td>
</tr>
</table>
</form>
</center>
</body>
I'm making a calculator. How do I make the input from the button display on the textarea? I have to make the numbers display on the text area like a normal calculator. I can't use jquery because we haven't learned it yet.
To add the numbers to the textarea you can use this code:
var button = document.querySelectorAll('input[type=button]');
for(var x=0; x<button.length; x++)
{
button[x].addEventListener('click', function(e) {
var a = document.getElementById('txt').value;
document.getElementById('txt').value = a + this.value;
});
}
If you want a list of all elements that match a selector, you can use document.querySelectorAll() and loop through the object list.
You will need to alter your html and delete all the wrong onclicks, you too should use the value attribute only for the actual value and not for code styling, as the output will include your spaces, too.
<center>
<h1>Online Calculator</h1>
<hr/>
<form name="frmCalculator" action="">
<table border="1" cellpadding="1" cellspacing="1" width="30%">
<tr>
<td colspan="4"><textarea style="width:100%" id="txt" name="txtResult"></textarea></td>
</tr>
<tr>
<td colspan="4"><input type="reset" style="width:100%"/></td>
</tr>
<tr>
<td><input type="button" value="7"/></td>
<td><input type="button" value="8"/></td>
<td><input type="button" value="9"/></td>
<td><input type="button" value="+" /></td>
</tr>
<tr>
<td><input type="button" value="4" /></td>
<td><input type="button" value="5" /></td>
<td><input type="button" value="6" /></td>
<td><input type="button" value="-" /></td>
</tr>
<tr>
<td><input type="button" value="1" /></td>
<td><input type="button" value="2"/></td>
<td><input type="button" value="3" /></td>
<td><input type="button" value="*" /></td>
</tr>
<tr>
<td><input type="button" value="0" /></td>
<td><input type="button" value="." /></td>
<td><input type="button" value="="/></td>
<td><input type="button" value="/" /></td>
</tr>
</table>
</form>
</center>
I didn't implement the calculating functions, but I hope this is enough for you to start with.
Simplistically, you can do:
<input type="button" value="7" onclick="this.form.txtResult.value = this.value">
However, you may want to add a listener to each button that is a number that does the same thing. The easiest way to do that is to add a class to the number buttons and give them all the same listener, so:
<input type="button" value="7" class="numberButton">
and use the load event to add the listeners:
window.onload = function() {
var buttons = document.querySelectorAll('.numberButton');
for (var i=0, iLen=buttons.length; i<iLen; i++) {
buttons[i].onclick = function(){
this.form.txtResult.value += this.value;
};
}
};
You can also add specific listeners for the other buttons.
PS. To get the buttons all the same size, use styles to set the width the same, don't use the value.

Categories

Resources