Loop through multiple TD, grab multiple values, fill array - javascript

I have two tables on the page.
Inside of my second table I am dynamically adding html from JS.
I am checking to see if the <tr> inside of the tbody are empty using:
var rowCount = $('#dynatable >tbody >tr').length;
If the row count is 0 I continue on with my javascript, if 1 or more <tr> exists I need to go through each <tr> and grab the two input values inside the <td>; for every <tr> available. Then need to collect the data into an array for server-side processing.
<table id="dynatable">
<thead>
<tr>
<th>Time</th>
<th>Description</th>
</tr>
</thead>
<tbody id="p_scents">
<tr><td class="ts_td"><input type="text" name="ts_value[]" class="timestamp_input"/></td><td><TEXTAREA NAME="ts_description[]" class="ts_desc" rows="3" cols="30" style="resize:none;" ></TEXTAREA></td></tr>
<tr><td class="ts_td"><input type="text" name="ts_value[]" class="timestamp_input"/></td><td><TEXTAREA NAME="ts_description[]" class="ts_desc" rows="3" cols="30" style="resize:none;" ></TEXTAREA></td></tr>
</tbody>
I have browsed similar questions but I cannot figure out a solution for my situation. I had a previous solution using simpleHTMLDOM + PHP but it's way too slow performance wise.
I was told to use JS or jquery and I am quite unfamiliar with both, any help is greatly appreciated.
How do I grab the values of multiple inputs from multiple <tr>'s inside a specific table and store the values in an array?

If your classes will be the same, you could do something like this with jQuery.
It put the values into arrays.
var values = $("input[class='timestamp_input']").map(function(){return $(this).val();}).get();
var textAreaValues = $("textarea[class='ts_desc']").map(function(){return $(this).val();}).get();
console.log(values);
console.log(textAreaValues);
JSFiddle demo here.

Related

Is there anyway to show serial number in a table? [duplicate]

This question already has an answer here:
How to display the index data in a *ngFor?
(1 answer)
Closed 1 year ago.
I'm currently new angular, so if there is any mistake in my implementation then please let me know,
This my HTML code from component.html file
<table id="table">
<tr>
<th>Sl.No.</th>
<th>Name</th>
<th>Email</th>
<th>Phone Number</th>
<th>Skill</th>
<th>Gender</th>
</tr>
<tr *ngFor = " let i of counter()">
<td></td> <!-- To print the serial number here -->
<td>{{nameFromLocalStorage}}</td>
<td>{{emailFromLocalStorage}}</td>
<td>{{phoneFromLocalStorage}}</td>
<td>{{skillFromLocalStorage}}</td>
<td>{{genderFromLocalStorage}}</td>
<td>
<button (click)="delete()" ><img src="./assets/icon/trash.png"></button>
</td>
</tr>
</table>
Here is code for counter() from component.ts file
counter() {
//TO DO
//Implementation is remaining,
return new Array(20);
}
The counter is supposed to return a value, the value is to be captured by the html file in the *ngFor directive and based on that it should create the required number of rows. Then I wanted to display the serial number in the first column of the table.
According to the code above I'm able to get 20 rows.
Note:- I have seen the solution in CSS and doesn't wish to implement until its the only option left.
My question is that how do I get the serial number there.
From my understanding i in the *ngFor directive should starts from zero so, is there anyway to directly display the value of i it self.
I'll be very glad if you can help me learn and correct my mistake.
Thank you in advance.
Yes you can loop it as simple dont know what your serial no is, if its from array then just use CounterArr.Serial_No.
<tr *ngFor = " let CounterArr of counter();let i = index;">
<td>{{i+1}}</td>
<td>{{CounterArr.nameFromLocalStorage}}</td>
<td>{{CounterArr.emailFromLocalStorage}}</td>
<td>{{CounterArr.phoneFromLocalStorage}}</td>
<td>{{CounterArr.skillFromLocalStorage}}</td>
<td>
<button (click)="delete()" ><img src="./assets/icon/trash.png"></button>
</td>
</tr>

Select and sort a column in a table using Javascript

I want to select a particular column of a table and sort it accordingly using Javascript (No frameworks or plugins). Could anyone help me regarding this?
<table>
<thead>
<tr>
<td>Col1</td>
<td>Col2</td>
<td>Col3</td>
<td>Col4</td>
</tr>
</thead>
<tbody>
<tr>
<td>Data11</td>
<td>Data23</td>
<td>Data53</td>
<td>Data45</td>
</tr>
<tr>
<td>Data81</td>
<td>Data42</td>
<td>Data33</td>
<td>Data4854</td>
</tr>
<tr>
<td>Data84681</td>
<td>Data452</td>
<td>Data354</td>
<td>Data448</td>
</tr>
<tr>
<td>Data1846</td>
<td>Data25635</td>
<td>Data3232</td>
<td>Data44378</td>
</tr>
</tbody>
</table>
function sortTableByColumn(tableId,columnNumber) { // (string,integer)
var tableElement=document.getElementById(tableId);
[].slice.call(tableElement.tBodies[0].rows).sort(function(a, b) {
return (
a.cells[columnNumber-1].textContent<b.cells[columnNumber-1].textContent?-1:
a.cells[columnNumber-1].textContent>b.cells[columnNumber-1].textContent?1:
0);
}).forEach(function(val, index) {
tableElement.tBodies[0].appendChild(val);
});
}
In your page, add id to the table tag:
<table id="myTable">
From javascript, use:
sortTableByColumn("myTable",3);
tBodies[0] is used because there can be many. In your example there is only one.
If we have var arr=[123,456,789], [].slice.call(arr) returns a copy of arr.
We're feeding it the html-rows-collection, found in tBodies[0] of tableElement.
Then, we sort that array with an inline function that compares two array elements, here: rows (<tr>).
Using cells[columnNumber] we access the <td>s, and textContent to access the text content. I've used columnNumber-1 so you can enter 3 for third column instead of 2, because the index of first element of an array (column 1) is 0...
The forEach goes through the elements of the array, which is by now in order, and appendChild row to the tBody. Because it already exist, it just moves it to the end: moving the lowest value to the end, then moving the second lowest to the (new) end, until it ends with the highest value, at the end.
I hope this is what you want. If so, enjoy!
Try using datatables you can get it from http://datatables.net its reallt easy to use. depends on jQuery
$("table").dataTable();
boom! and its done.

.each() function on affect current object

having some issues with my code below, first here is the HTML:
<table class="finance-table">
<tbody><tr>
<th></th>
<th>Deposit</th>
<th>Balance</th>
<th>Fees</th>
<th>Total Payable</th>
<th>Term</th>
<th>Fixed Rate</th>
<th>Representative APR</th>
<th>Monthly Pmt</th>
</tr>
<tr class="hp">
<td><strong>HP</strong></td>
<td id="td_finance_deposit">£11700.00</td>
<td id="td_finance_balance">£105300.00</td>
<td id="td_finance_fees">£298.00</td>
<td id="td_finance_total_inc_deposit">£146255.50</td>
<td id="td_finance_term">60 mths</td>
<td id="td_finance_rate">5.50%</td>
<td id="td_finance_apr">10.1%</td>
<td id="td_finance_monthly_payments">£2242.59 p/m* x 60 mths</td>
</tr>
</tbody></table>
There is about 10 of these tables [within the same document], all with the same id's and class's. I'm using an each loop to execute some code against each table found, however it only seems to be working on the first table and disregards the others.
Below is the jQuery, like I said works find on the first table, but ignores the rest!
<!-- Remove First and Final Payment from Showroom Finance Examples -->
<script>
$(".finance-table").each(function(key, value) {
// Display loading
var html = $(this);
// Remove the First Payment and Final Payment Column
$(this).find("#td_finance_first_payment, #td_finance_final_payment").remove();
$(this).find("th:contains('1st Pmt')").remove(); $(this).find("th:contains('Final Pmt')").remove();
// Get the Term and update the monthly payment
var term = $(this).find("#td_finance_term").html(); // .replace(/\D/g,'')
var payments = ($(this).find("#td_finance_monthly_payments").html()).split('x')[0];
($(this).find("#td_finance_monthly_payments")).html(payments + " x " + term);
})
</script>
Edit:
Please note, I can't change the HTML at all
You should first give a unique ID to each <td>, perhaps with your DB identifier for that record. You don't need it now but this will allow you to do other thing later if you need it.
Then change all the <td> ids to classes:
<td class="td_finance_fees">£298.00</td>
Finally change all your javascript accordingly to use class instead of IDs:
$(this).find(".td_finance_first_payment, .td_finance_final_payment").remove();
Using Attribute Equals Selector
Change your code from:
$(this).find("#td_finance_first_payment, #td_finance_final_payment").remove();
to:
$(this).find('td[id="td_finance_first_payment"], td[id="td_finance_final_payment"]').remove();
Do this type of change for all areas of #xxx to id="xxx"
What this does is find all tds with attribute id="xxx", rather than using #id identifier, this is forces jQuery to do a tree search.
Also your HTML does not match your code, (theres no td_finance_first_payment in your html, I assume you removed it?)
Edit: This solution is useful if you 100% cannot edit the html (comes from a source you have no control over, such as an API or internal software). Best solution would be to fix the ids!

Why does this Javascript only run once per page?

I have this Try-it-Yourself section to my website but for some reason when I am wanting to have more than one Try-it-Yourself section it will only work for the one at the top of the page. So if I had three of them on a page the top one would work in the way I want but the next two would do nothing.
I have the following HTML:
<div class="tryit">
<table>
<tr>
<td>Try It Yourself</td>
</tr>
<tr>
<td><textarea id="input" rows="10" cols="47"></textarea></td>
</tr>
<tr>
<td><input onclick="update();" type="button" value="Update"></td>
</tr>
<tr>
<td><iframe id="output" name="output" width="600" height="300" ></iframe></td>
</tr>
</table>
</div>
And the following Javascript:
function update()
{
var tryitoutput = document.getElementById('input').value;
window.frames['output'].document.documentElement.innerHTML = tryitoutput;
}
Thank you.
As others mentioned, this is happening because there can't be more than one HTML element with same value of ID attribute. In your case javascript only finds the first element, that's why it doesn't work on later Update buttons. The simplest approach would be to set different ID attribute values for different "Try it yourself" boxes:
Slightly modify your JS, see following jsFiddle example
function update(tryItIndex) {
var tryItOutput = document.getElementById('input-' + tryItIndex).value;
window.frames['output-' + tryItIndex].document.documentElement.innerHTML = tryItOutput;
}
That's because you are referring to the textarea and the output by id which means it will always just retrieve the first one. A quick fix would be having unique id's for these fields and send the names as parameters to the update function like update(inputId, outputId)

JQuery update table cell and add new table rows

A newbie question,really.
Suppose I have a html table like this:
<div id="div1">
<table id="table1" border="1">
<tr>
<th bgcolor="#eee"><strong>ID</strong></th>
<th bgcolor="#eee"><strong>Price</strong></th>
</tr>
<tr>
<td id='id1'>1111</td>
<td id='id2'>2222</td>
</tr>
</table>
</div>
Now I am using Jquery to get data in json format from server, like this:
id1,19.99
id2,29.99
id3,39.00
What I want to achieve is: Look at the data, if the id already exist in table, update the cell value. If id doesn't exist in the table, add a new row. How do I do that in JQuery? I just started to learn JQuery. Now I can use ajax call to get the data, but don't know how to update the table. Any help is appreciated.
To see if a cell exists, you must test the .length of its selector:
$('#'+str).length; // zero if there is no such ID
Or you can just update the contents of that cell with .text(), which will fail if the ID doesn't exist:
$('#'+str).text(newvalue);
To create a new row, you can .append() it to the table:
$('table tr#id_of_row').append('<td id="'+str+'">'+newvalue+'</td>');
You can get a cell by id like this
$('#'+id).length //length will be 0 if not found or 1 if found
Update the value using
$('#'+id).text(new_value);

Categories