I'm trying to load in an element created with jQuery to a table. The problem is, this dynamically-created element need to be inserted after another element (the <th>) so that the table retains a nice design. When using .after(), my element is inserted in to the table and the table design looks good, but the data I'm using appears in the opposite order than if I use .before() to insert. Why am I seeing opposite behavior with .before() / .after()?
Edit: .before() gives me the correct order of insertion for the interest rates, but it inserts the elements before the , so the table cols/rows do not line up. .After() gives me the opposite insertion for the interest rates, but the elements are added after that , so the the table retains its rows/cols.
Here's my code as my explanation probably isn't very clear:
<form id="form">
<label for="interestInput" id="interestRateLabel">Enter interest rate</label>
<input id="interestInput" name="interestRate" type="text">
Add another interest rate<br /><br />
<label for="loanAmtInput" id="loanAmtLabel">Enter loan amount</label>
<input id="loanAmtInput" name="loanAmt" type="text">
<button onclick="doCalculation(); return false;">Calculate!</button>
</form>
<div id="standard">
<h1>Standard Repayment</h1>
<table width="600px;" border="1" cellspacing="0" cellpadding="0">
<th scope="col"> </th>
<tr id="totalMonths">
<th scope="row">Total months</th>
</tr>
<tr id="paymentPerMonth">
<th scope="row">Payment/mo</th>
</tr>
<tr id="totalPayment">
<th scope="row">Total payment</th>
</tr>
</table>
</div>
<div id="extended">
<h1>Extended Repayment</h1>
<table width="600px;" border="1" cellspacing="0" cellpadding="0">
<th scope="col"> </th>
<tr id="totalMonths">
<th scope="row">Total months</th>
</tr>
<tr id="paymentPerMonth">
<th scope="row">Payment/mo</th>
</tr>
<tr id="totalPayment">
<th scope="row">Total payment</th>
</tr>
</table>
</div>
<div id="graduated">
<h1>Graduated Repayment</h1>
<table width="600px;" border="1" cellspacing="0" cellpadding="0">
<th scope="col"> </th>
<tr id="totalMonths">
<th scope="row">Total months</th>
</tr>
<tr id="paymentPerMonth">
<th scope="row">Payment/mo</th>
</tr>
<tr id="totalPayment">
<th scope="row">Total payment</th>
</tr>
</table>
</div>
And, here's the relevant JS:
var doCalculation = function() {
$("div#standard table tbody th.rates, div#standard table tbody tr#totalMonths td, div#standard table tbody tr#paymentPerMonth td").remove();
var loanAmount = document.getElementById("loanAmtInput");
$("input[name=interestRate]").each(function(i){
var num = parseInt( $(this).val(), 10 );
var totalMonths = num * 3;
var paymentPerMonth = num + (1/2);
var totalPaymet = num * 120;
console.log(i + "=" + num);
$("div#standard table tbody th[scope=col]").before("<th class=rates>" + num + "% interest rate</th>");
$("div#standard table tbody tr#totalMonths").append("<td>" + totalMonths + "</td>");
$("div#standard table tbody tr#paymentPerMonth").append("<td>" + paymentPerMonth + "</td>");
});
};
It goes in in opposite order because JQuery does each in turn - so in one case, it's running before() on each element, and in the other it's running after(). The way to get the thing you actually want is to start at the <th>, grab next(), and then run before() on that. If you don't have (or might not have) any elements after the <th>, then create a dummy element, insert it after() the <th>, insert the elements you want to insert before() the dummy element, and then delete the dummy element.
If I understand where your confusion is, it's because .before() and .after() work in opposite of each other.
From jQuery API docs:
.before() - Inserts content, specified by the parameter, before each
element in the set of matched elements.
.after() - Inserts content, specified by the parameter, after each
element in the set of matched elements.
Read more at http://api.jquery.com/
Related
I want to add listener to the html table column So that when I click the so called visualized table column, I want to perform something using js. consider this:
<table>
<thead>
<tr>
<th>name</th>
<th>lastname</th>
</tr>
</thead>
<tbody>
<tr>
<td>Guga</td>
<td>Nemsitsveridze</td>
</tr>
<tr>
<td>Giorgi</td>
<td>Beshidze</td>
</tr>
</tbody>
</table>
Now when I click the lastname cell (I mean the one of the following elements: <th>lastname</th>, <td>Nemsitsveridze</td>, <td>Beshidze</td>) I want to perform something using js.
The solution I was thinking about is to assign some kind of class attribute to each element of the lastname cell and add the same event listener to them independently, but I'm not sure if it is the only solution to this problem.
If anyone has an idea how to achieve this goal, please, answer the question.
Thanks in advance.
In order to execute something when a column is clicked, you can add one event listener to the whole table and then check which column was clicked, then execute some code.
Using window.event.target.cellIndex you can access the cell index.
Using window.event.target.parentNode.rowIndex you can access the row index.
document.getElementById('myTbl').addEventListener('click', function(event)
{
var col = window.event.target.cellIndex;
var row = window.event.target.parentNode.rowIndex;
if (col==1){
alert('Col index is: ' + col + '\nRow index is: ' + row);
}
});
table, td {
border: 1px solid black;
}
<table id="myTbl">
<thead>
<tr>
<th>name</th>
<th>lastname</th>
</tr>
</thead>
<tbody>
<tr>
<td>Guga</td>
<td>Nemsitsveridze</td>
</tr>
<tr>
<td>Giorgi</td>
<td>Beshidze</td>
</tr>
</tbody>
</table>
The table being made dynamically using Thymeleaf. Each row of the table has a img link attached to it. On the click of which I want to get the selected rows img link first , second and third cell.
Relevant Table Code
<table class="table" id="tblDocType" style="padding: 20px 10px;">
<thead class="thead-dark">
<tr>
<th scope="col"> <b> Document Type </b></th>
<th scope="col"> <b> Practice Area </b> </th>
<th scope="col"><b> Retention Policy </b></th>
<th scope="col"> <b> Effective Date<br> Required </b></th>
<th scope="col"> <b> Termination Date<br> Required </b></th>
<th scope="col"> <b> Action</b></th>
</tr>
</thead>
<tr th:each="doctype,iterStat : ${dlist}">
<td th:text = "${doctype?.doctypes}"></td>
<td th:text = "${doctype?.practiceAreaId}"></td>
<td th:text = "${doctype?.retention_policy}"></td>
<td th:text = "${doctype?.effectiveDateRequired}"></td>
<td th:text = "${doctype?.terminationDateRequired}"></td>
<td>
<a href="#" th:name="${doctype?.practiceAreaId}" th:id="${iterStat.index}" onclick="deleteTrigger(this.id)" style="color: blue;">
<span class="glyphicon glyphicon-trash"></span>
</a>
</td>
</tr>
</table>
I am trying to get the cell values using jquery.
Relevant jquery code
function deleteTrigger(id){
var value=$("#tblDocType").closest("tr").find('td:eq(0)').text();
console.log("value=",value);
var doctypesjson={
"doctypes": id,
"practiceAreaId": pracaticeareaidfrombutton
};
}
In the console the value is coming blank.
Please help me if you know what can be done for the problem. Thank you in advance
Presently, it appears that your code is looking for the first TR, then within that the first TD. However, this won’t do anything as your first TR only contains TH.
In calling your deleteTrigger() function, you should pass through the element that was clicked
deleteTrigger(this); // use this for your TR lookup.
However, since you’re using jQuery already, it may make your life easier to abandon the delete function altogether and use a listener;
$(“tr”).click(function(){
$(this).find(“td”).first() // this will get the first td of a clicked row
$(this).find(“td”).eq(1) // this will get second td etc...
})
I'm using html5 and jquery to set up a dynamic table, until then I can add the elements to the table without problems, but I can not retrieve the value of its columns. so I have the following questions:
How can I recover the table data by clicking the ROW?
Should I always use the data-name, id for example as in the first
line ?
$(document).on("change", "#TabClientesAdicionados", function(e) {
alert('?');
});
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<hr>
<table id="TabClientesAdicionados" class="table table-hover">
<thead>
<tr>
<th> ID </th>
<th> Name </th>
<th> Actions </th>
</tr>
</thead>
<tbody>
<tr>
<td data-id="Bruno">1</td>
<td data-nome="Bruno">Bruno</td>
<td>Details</td>
</tr>
<tr>
<td>2</td>
<td>Josep</td>
<td> Details </td>
</tr>
</tbody>
</table>
How can I recover the table data by clicking the ROW?
You can bind the click event to your TR elements and get the information.
Should I always use the data-name, id for example as in the first line?
Yes, because you don't want the parsed HTML to manipulate data. The data attributes are a better approach to keep related data (no HTML) to DOM elements.
Look at this code snippet
This approach binds the click event to TR elements
$('#TabClientesAdicionados tbody tr').click(function() {
var data = { name: '', id: '' };
$(this).children('td').each(function() {
var name = $(this).data('nome');
if (name) {
data.name = name;
}
var id = $(this).data('id');
if (id) {
data.id = id;
}
});
console.log(data);
});
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<hr>
<table id="TabClientesAdicionados" class="table table-hover">
<thead>
<tr>
<th> ID </th>
<th> Name </th>
<th> Actions </th>
</tr>
</thead>
<tbody>
<tr>
<td data-id="Bruno_1">1</td>
<td data-nome="Bruno">Bruno</td>
<td>Details</td>
</tr>
<tr>
<td>2</td>
<td>Josep</td>
<td> Details </td>
</tr>
</tbody>
</table>
I would do as the following snippet.
You need to bind the event to the row tr ant then get each of its children.
By adding a data attribute you could set a column name. This could also help if you eventually needed to extract the value of an specific cell.
Incidentally you could also add a second data attribute named like data-value or something similar- This in case you are worried that your parsed html content might cause you trouble with the values.
$(document).ready(function() {
$("#mytable").on('click', 'tr', onCellClick);
//Bind the event to the table row
function onCellClick() {
let row = $(this); //get the jquery Object for the row
let rowValues = {}; //An empty object to hold your data
let temp;
//extract the value of every cell in the row
//Doing it this way gives you flexibility on the amount of colums you have
row.find('td').each(function(item) {
temp = $(this);
rowValues[temp.data('column')] = temp.text();
//this could be changed to
//rowValues[temp.data('column')] = temp.data('value);
//if you desire to use a separate data-value property
});
console.log(rowValues);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table style="width:100%" id="mytable">
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Age</th>
</tr>
<tr>
<td data-column="name" data-value="Jill">Jill</td> <!-Adding value property-->
<td data-column="lastname">Smith</td>
<td data-column="age">50</td>
</tr>
<tr>
<td data-column="name">Eve</td>
<td data-column="lastname">Jackson</td>
<td data-column="age">94</td>
</tr>
</table>
I am making a form to add players into an event.
The form searches a db of players with search criteria specified by the user and then lists all matching players with an add button next to them.
I also have a table with all the table headers done and then a
<div id="PlayerAdded">
tag before the end of the table.
I have written a function to output the data for the next row to the table when a players "Add" button is clicked. My function says:
function add(){
document.getElementById("PlayerAdded").innerHTML += "<tr><td>success</td></tr>";
}
I expected this to add a row, but instead it adds just the word "success" above the table (Perhaps I was a little optimistic when I used the word success as my test string lol).
Can someone please tell me why it is not adding the code inside the div "PlayerAdded"?
If it helps, here is some of the HTML:
<table border='1px'>
<tr><th colspan='6'> <?php echo ($eName . " - " . $vn); ?></th></tr>
<tr><th>Player ID</th>
<th>Player Name</th>
<th>Place</th>
<th>Points</th>
<th>Cash</th>
<th>Ticket?</th></tr>
<div id="PlayerAdded"> </div>
<tr><td colspan='3'>Search <input type='text' id='newsearch'></input>
</table>
There were a couple of problems with your existing HTML - which therefore broke your DOM when the browser attempted to assemble things.
a <div> element – in a <table> – must be contained within either a <th> or <td> element; no other element is a valid child of a <tr> element, and the only valid children of a <table> element are <thead>, <tfoot>, <tbody> and <tr> elements.
neither your last <tr>, or its child <td>, element were closed – the browser will automatically close these elements when it encounters another <td> (since neither a <td>, nor a <tr>, can be directly nested within another <td>).
That said, I'd correct your HTML to the following:
<table>
<tbody>
<tr>
<th colspan='6'>« php response »</th>
</tr>
<tr>
<th>Player ID</th>
<th>Player Name</th>
<th>Place</th>
<th>Points</th>
<th>Cash</th>
<th>Ticket?</th>
</tr>
<tr>
<td colspan='3'>Search
<input type='text' id='newsearch' />
</td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
<button id="addNewRow">Add a new row</button>
And your JavaScript to the following:
function addNewRow() {
// creating the relevant elements to be added:
var row = document.createElement('tr'),
td = document.createElement('td');
// setting the text of the created-<td> element:
td.textContent = 'Success';
// setting the colSpan property (the colspan attribute):
td.colSpan = '6';
// adding a class-name to the created-<td>, to make it
// visually obvious which are the newly-added <td>
// elements:
td.classList.add('addedRow');
// appending the created-<td> to the created-<tr>:
row.appendChild(td);
// finding the last <tr> of the table, using
// document.querySelector() which will match
// only the first element that matches the
// supplied CSS selector (or null, if no
// element exists that matches):
var lastRow = document.querySelector('table tr:last-child');
// inserting the created-<tr> (and its descendant
// elements parentNode of the lastRow node before
// the lastRow node):
lastRow.parentNode.insertBefore(row, lastRow);
}
// using unobtrusive JavaScript to add the 'click'
// event-listener to the <button> element with the
// id of 'addNewRow':
document.getElementById('addNewRow').addEventListener('click', addNewRow);
function addNewRow() {
var row = document.createElement('tr'),
td = document.createElement('td');
td.textContent = 'Success';
td.colSpan = '6';
td.classList.add('addedRow');
row.appendChild(td);
var lastRow = document.querySelector('table tr:last-child');
lastRow.parentNode.insertBefore(row, lastRow);
}
document.getElementById('addNewRow').addEventListener('click', addNewRow);
table,
td,
th {
border: 1px solid #000;
min-height: 2em;
}
td.addedRow {
font-weight: bold;
text-align: center;
border-color: limegreen;
}
<table>
<tbody>
<tr>
<th colspan='6'>« php response »</th>
</tr>
<tr>
<th>Player ID</th>
<th>Player Name</th>
<th>Place</th>
<th>Points</th>
<th>Cash</th>
<th>Ticket?</th>
</tr>
<tr>
<td colspan='3'>Search
<input type='text' id='newsearch' />
</td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
<button id="addNewRow">Add a new row</button>
External JS Fiddle demo, for experimentation or development.
References:
document.createElement().
document.getElementById().
document.querySelector().
Element.classList.
EventTarget.addEventListener().
Node.appendChild().
Node.insertBefore().
Try doing as user #Barmar said:
<script type="text/javascript">
function add(){
var _tr = document.createElement("tr");
var _textNode = document.createTextNode("Success");
_tr.appendChild(_textNode);
var _child = document.getElementById("botTr");
var parentDiv = _child.parentNode;
parentDiv.insertBefore(_tr, botTr);
}
</script>
And then:
<table border='1px'>
<tr><th colspan='6'> <?php echo ($eName . " - " . $vn); ?> </th></tr>
<tr id="topTr"><th>Player ID</th>
<th>Player Name</th>
<th>Place</th>
<th>Points</th>
<th>Cash</th>
<th>Ticket?</th>
</tr>
<tr id="botTr"><td colspan='3'>Search <input type='text' id='newsearch' />
</table>
<input type="button" name="hitme" id="hitme" value="hitme" onclick="add();" />
i have a table that was created by Wijmo I want to change the content of it's footer
myfooter
<tfoot>
<tr role="row" class="wijmo-wijgrid-footerrow ui-state-default ui-state-highlight">
<td class="wijgridtd" role="columnfooter" scope="col" >
<div class="wijmo-wijgrid-innercell "> </div></td>
<td class="wijgridtd" role="columnfooter" scope="col" >
<div class="wijmo-wijgrid-innercell "> </div></td>
<td class="wijgridtd" role="columnfooter" scope="col" >
<div class="wijmo-wijgrid-innercell ">**TW: 12,100** </div> </td>
<tr>
</tfoot>
I want to change the TW:12,000 to a different content
You can get a reference to the table row using document.querySelector, assuming the element's attributes have unique values to select it by (otherwise use querySelectorAll and an index).
var row = document.querySelector('.wijmo-wijgrid-footerrow');
You can then use the row's cells collection to get the cells, and use cells.length to find the last cell.
var cells = row.cells;
var cell = cells[cells.length - 1];
Now you can use innerHTML or some other method to replace the content of the cell.
cell.innerHTML = "some new content";
You can also skip those intermediate variables if you want.
var cells = document.querySelector('.wijmo-wijgrid-footerrow').cells;
cells[cells.length - 1].innerHTML = "some new content";
See the section on tabular data in the HTML Living Standard for more information on manipulating tables.