How to get the index of a particular element - javascript

I got the following code from the designer:
<table class="items">
<thead>
<tr>
<th id="name">name</th>
<th id="category">category</th>
<th id="zip">zip</th>
<th id="city">city</th>
<th id="street">street</th>
<th id="latitude">latitude</th>
<th id="longitude">longitude</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>MyCompany</td>
<td>Company</td>
<td>18360</td>
<td>Stroudsburg</td>
<td>4 Scott Str.</td>
<td>40.9891</td>
<td>-75.1962</td>
</tr>
</tbody>
</table>
Using jQuery, how can I get the longitude and latitude values by taking into account the th elements with the specified id? The order of the columns might change later so direct indexing is not an option. However the id values will remain the same.

var latIndex = document.getElementById('latitude').cellIndex;
var longIndex = document.getElementById('longitude').cellIndex;
var row = document.querySelector(".items .odd");
var latitude = row.cells[latIndex];
var longiture = row.cells[longIndex];
latitude = latitude.textContent || latitude.innerText;
longitude = longitude.textContent || longitude.innerText;
Using ONLY raw JavaScript, guaranteed to be at least 8 times faster than jQuery (20 on more complex pages) ;)

You can use the .index() method to get the location of the latitude and longitude headers and then get that same location in the body.
// get column number for lat and long
var latIndex = $("#latitude").index();
var longIndex = $("#longitude").index();
// get rows that contain the actual data
var rows = $(".items .odd td");
// get the desired data from the same columns as titles
var latitude = rows.eq(latIndex).text();
var longitude = rows.eq(longIndex).text();
Demo here: http://jsfiddle.net/jfriend00/bCXbw/

You can use the .index() method:
var latIndex = $("#latitude").index(),
longIndex = $("#longitude").index();
// do something with the values from each row
$("tbody tr").each(function() {
var $tds = $(this).find("td"),
latValue = $tds.eq(latIndex).text(),
longValue = $tds.eq(longIndex).text();
console.log(latValue + ", " + longValue);
});​
Demo: http://jsfiddle.net/mjaVp/

Another way using index() with :nth-child()
var lat = jQuery("#latitude");
var lng = jQuery("#longitude");
var latInd = jQuery("table thead th").index( lat ) + 1;
var lngInd = jQuery("table thead th").index( lng ) + 1;
var lats = jQuery("table tbody tr td:nth-child(" + latInd + ")");
var lngs = jQuery("table tbody tr td:nth-child(" + lngInd + ")");
console.log(lats);
console.log(lngs);
fiddle

var lat = $('#latitude').index();
var long = $('#longitude').index();
console.log($('tr.odd td:eq('+lat+')').html()); //outputs 40.9891
console.log($('tr.odd td:eq('+long+')').html()) // outputs -75.1962
This assumes that the ordering of element is consistent, which looking at your code it should be.

Related

Why am I not getting the IDs from innerHTML?

I have HTML & javascript code where you can click a button to add a row to an existing table. I want to make sure that each row's dropdowns have the correct IDs in ascending order. The middle rows can get deleted, and I need to adjust the IDs.
function addRow(){
var table = document.getElementById('myTable');
//Get the number of rows in the table, and use (+1) value for the IDs later
var rowCount = table.tBodies[0].rows.length;
var tbodyRef = table.getElementsByTagName('tbody')[0];
// Insert a row at the end of table
var newRow = tbodyRef.insertRow();
// Insert a cell at the end of the row
var cell0 = newRow.insertCell(-1);
cell0.innerHTML = '<select id="firstDropdown' + (rowCount + 1) + '"></select>';
var cell1 = newRow.insertCell(-1);
cell1.innerHTML = '<select id="secondDropdown' + (rowCount + 1) + '"></select>';
var cell2 = newRow.insertCell(-1);
cell2.innerHTML = '<button onclick=deleteRow()>Delete</button>';
/*Here, I want to get the list of ID's of the firstDropdown of
each row (for debugging purposes). But this is not printing anything.
Why is this code below not printing the first dropdown's ids of each row? */
console.log("------------------------");
for(var i=0; i<table.tBodies[0].rows.length; i++){
console.log(table.tBodies[0].rows[i].cells[0].id);
}
}
function deleteRow(){
var td = event.target.parentNode;
var tr = td.parentNode;
tr.parentNode.removeChild(tr);
}
My HTML code is below:
<button onclick=addRow()>Add row</button>
<br>
<table id="myTable">
<thead>
<th>1st dropdown</th>
<th>2nd dropdown</th>
<th>Remove</th>
</thead>
<tbody>
<!--Rows will be added/deleted dynamically-->
</tbody>
</table>
I will need to update dropdowns' IDs later when rows are deleted.
I was hoping to do it the same way: table.tBodies[0].rows[i].cells[0].id = "firstDropdown" + (i+1); but I am not sure if this is even going to work now.

jQuery sum the values of table rows

hello i have this table
i want to get the total of each row in the total column
jQuery
//Monthly Marketing Cost Report
$.get('/dashboard/costs', function(data){
$.each(data,function(i,value){
var leads = $('#leads');
var budget_total_year = $('#full_year_cost');
var budget_total_month = $('#share_cost');
var budget_per_lead = $('#cost_per_lead');
leads.append('<th>' + value.olxTotal + '</th>');
budget_total_year.append('<th>' + value.budget_total_year + '</th>');
budget_total_month.append('<th>' + value.budget_total_month + '</th>');
budget_per_lead.append('<th>' + value.budget_per_lead + '</th>');
})
})
HTML
<tbody id="tableData-marketMonth">
<tr id="leads">
<th>Leads</th>
</tr>
<tr id="full_year_cost">
<th>Full Year Cost</th>
</tr>
<tr id="share_cost">
<th>{{date('F')}} Share of Cost</th>
</tr>
<tr id="cost_per_lead">
<th>Cost per Lead</th>
</tr>
</tbody>
i was going to calculate the total through php but i though it can be easier
using jQuery just putting the sum of each row at the end
Thank you very much
Create variables before the loop. add to the variables in the loop and then assign the sum at the end.
$.get('/dashboard/costs', function(data){
var sumLeads = 0;
var sumFullYearCost = 0;
var sumShareCost = 0;
var sumCostPerLead = 0;
var tr_leads = $('#leads');
var tr_budget_total_year = $('#full_year_cost');
var tr_budget_total_month = $('#share_cost');
var tr_budget_per_lead = $('#cost_per_lead');
$.each(data,function(i,value){
tr_leads.append('<th>' + value.olxTotal + '</th>');
tr_budget_total_year.append('<th>' + value.budget_total_year + '</th>');
tr_budget_total_month.append('<th>' + value.budget_total_month + '</th>');
tr_budget_per_lead.append('<th>' + value.budget_per_lead + '</th>');
sumLeads += value.olxTotal;
sumFullYearCost += value.budget_total_year;
sumShareCost += value.budget_total_month;
sumCostPerLead += value.budget_per_lead;
});
tr_leads.append('<th>' + sumLeads + '</th>');
tr_budget_total_year.append('<th>' + sumFullYearCost + '</th>');
tr_budget_total_month.append('<th>' + sumShareCost + '</th>');
tr_budget_per_lead.append('<th>' + sumCostPerLead + '</th>');
});
Example for leads row using Array.map and Array.reduce. Use jQuery to get the td elements.
var leads = $('#leads');
const total = leads.children('td').toArray().map(x=>Number(x.innerHTML)).reduce((sum, x) => sum + x)
leads.append(`<th>${total}</th>`);
Try something like this.
$('#tableData-marketMonth tr').each(function () {
var row = $(this);
var rowTotal = 0;
$(this).find('th').each(function () {
var th = $(this);
if ($.isNumeric(th.text())) {
rowTotal += parseFloat(th.text());
}
});
row.find('th:last').text(rowTotal);
});
NOTE: change 'th' to 'td' if you have td's. Looking at your jquery, it looks like you are appending th's.
You can use my written code to vote if you like it...
HTML
<table>
<thead>
<tr>
<th>MAX ATK</th>
<th>MAX DEF</th>
<th>MAX HP</th>
<th>Overall</th>
</tr>
</thead>
<tbody>
<tr>
<td class="combat">8170</td>
<td class="combat">6504</td>
<td class="combat">6050</td>
<td class="total-combat"></td>
</tr>
<tr>
<td class="combat">8500</td>
<td class="combat">10200</td>
<td class="combat">7650</td>
<td class="total-combat"></td>
</tr>
<tr>
<td class="combat">9185</td>
<td class="combat">7515</td>
<td class="combat">9185</td>
<td class="total-combat"></td>
</tr>
</tbody>
</table>
jquery
$(document).ready(function () {
//iterate through each row in the table
$('tr').each(function () {
//the value of sum needs to be reset for each row, so it has to be set inside the row loop
var sum = 0
//find the combat elements in the current row and sum it
$(this).find('.combat').each(function () {
var combat = $(this).text();
if (!isNaN(combat) && combat.length !== 0) {
sum += parseFloat(combat);
}
});
//set the value of currents rows sum to the total-combat element in the current row
$('.total-combat', this).html(sum);
});
});

jQuery select input within a td for all rows

I am trying to calculate the values with all the input fields within a table upon change.
Here is the sample HTML table targeted and also the jQuery code I am trying to use to get the values from all input fields in the table by iterating over the rows using foreach:
$('#mytable :input').change(function() {
var numrows = 1;
var rows;
$('#out').text('');
$('#mytable tr').each(function() {
var date = $(this).children('td:eq(1)');
var obj = $(this).children('td:eq(2):input').value;
var comma = $('#queryTable tbody tr').length != numrows ? "," : "]";
var row = "{\"" + date + "\";\"" + obj + "\"}" + comma + "\n";
//row += date * obj;
//row = numrows == 1 ? "["+row : row;
$('#out').append(row);
numrows++;
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="out">
Test
</div>
<table id="mytable" border="1">
<tr>
<th>Col1</th>
<th>Col2</th>
<th>Col3</th>
</tr>
<tr>
<td>value1</td>
<td>1</td>
<td>Label1:
<Input type="text"></Input>
</td>
</tr>
<tr>
<td>value2</td>
<td>3</td>
<td>Label2:
<Input type="text"></Input>
</td>
</tr>
<tr>
<td>value3</td>
<td>ttt</td>
<td>Label3:
<Input type="text"></Input>
</td>
</tr>
</table>
Fiddle sample code
i recomend you to use keyup instead of change because the change will not trigger till the input lost focus:
$('#mytable :input').keyup(function(){
var numrows = 1;
var rows;
$('#out').text('');
$('#mytable tr:not(:first-child)').each(function(){
var date = $(this).children().eq(1).text();
var obj = $(this).children().eq(2).children('input').val();
var comma = $('#queryTable tbody tr').length != numrows ? "," : "]";
var row = "{\""+date+"\";\""+obj+"\"}"+comma+"\n";
//row += date * obj;
//row = numrows == 1 ? "["+row : row;
$('#out').append(row);
numrows++;
});
});
here is your working jsfiddle
http://jsfiddle.net/ZZYD4/891/
btw i ignore the first row adding this to the selector :not(:first-child) because that is the header row

How can I insert a <tr> element into a dynamic table?

I hope someone has a clue for me. I am new to javascript and I am trying to build this structure with a dynamically generated table.
<table>
<tr>
<td>value1</td>
<td>value2</td>
<td>value3</td>
<td>value4</td>
</tr>
<tr>
<td>value5</td>
<td>value6</td>
<td>value7</td>
<td>value8</td>
</tr>
<tr>
<td>value9</td>
<td>value10</td>
<td>value11</td>
<td>value12</td>
</tr>
<tr>
<td>value13</td>
<td>value14</td>
<td>value15</td>
<td>value16</td>
</tr>
</table>
What I tried to do is to echo a <tr> after every 4th pair of <td>.
Like this:
var tbody_el = $("#somevalue_id"); //is the id of the table, which needs to be filled with `<tr>` and `<td>`.
var counter = 0;
$.each(TonsOfData.getValues(), function(index, somevalue) {
//var tr_el = $("<tr></tr>");
var td_checkbox_el = $("<td></td>");
var cbName = "cb_" + somevalue.displayName + "_name";
var cbId = "cb_" + somevalue.displayName + "_id";
var inputEl = $("<input type='checkbox' name='" + somevalue.displayName + "' id='" + cbId + "'/>");
inputEl.data("somevalueId", somevalue.id);
inputEl.attr("checked", "checked");
inputEl.change(valueChoicesClick);
var div_value_id = "div_value_" + somevalue.id + "_id";
var div_value_el = $("<div id='" + div_value_id + "' align='left'></div>");
var td_value = $("<td></td>");
td_checkbox_el.append(inputEl);
if(counter == 0 || (counter +1)%4 == 0){
echo "<tr>";
}
td_value.append(td_checkbox_el, "<br> Displayname: " + somevalue.displayName,"<br> Unit: "+ somevalue.unitstring," <br>",div_value_el);
if((counter +1)%4 == 0) {
echo "</tr>";
}
//tbody_el.append(tr_el);
}
);
Is this even possible?
Or am I going a totally wrong way?
Big thanks for any suggestions!!
EDIT:
I found a solution that worked for me. I doubt anyone will have the same issue, but I'd like to share it anyway.
I created a counter that gets incremented in the loop and gave the <td> parts a class-id.
if(counter<4){
td_value = $("<td class='select1'></td>");
}
if(counter>3 && counter <8){
td_value = $("<td class='select2'></td>");
}
if(counter>7 && counter <12){
td_value = $("<td class='select3'></td>");
}
if(counter>11 && counter <16){
td_value = $("<td class='select4'></td>");
}
if(counter>15 && counter <20){
td_value = $("<td class='select5'></td>");
}
After that I used the JQuery wrapAll()-function to add my <tr>. That did the trick.
$('#somevalue_id td.select1').wrapAll('<tr/>');
$('#somevalue_id td.select2').wrapAll('<tr/>');
$('#somevalue_id td.select3').wrapAll('<tr/>');
$('#somevalue_id td.select4').wrapAll('<tr/>');
$('#somevalue_id td.select5').wrapAll('<tr/>');
I know, it is not the most elegant solution but it works.
Thanks again to everyone that gave me hints, you helped me solve this!
You can use jquery and using .each for iterating and getting the fourth element in each iteration using .nth-child and inserting after using .insertAfter
Please find the example to mainuplate the table accordingly.
this is one way you can do it
<table class="test_table" id="test_table">
</table>
var tableEl = $(".test_table");
var noOfRows = 4;
var noOfColumns = 4;
//Empty the table in case there is anything already there
tableEl.each(function(){
var tableElObject = $(this);
for(i=0;i<noOfRows;i++)
{
rowStart = "<tr>";
for(j=0;j<noOfColumns;j++)
{
rowStart +="<td>"+"Test"+i+j+"</td>";
}
tableElObject.append(rowStart+"<tr/>");
}
});
http://jsfiddle.net/qg5hG/
if you want to create tables trs and tds dynamically this way can be better for you....
var table = document.createElement('table');
table.setAttribute('border','0');
table.setAttribute('cellspacing','5');
table.setAttribute('cellpadding','5');
table.setAttribute('width','100%');
var tr = table.insertRow(-1);// "-1"s meaning add tr to end of table if you want to add top of table you must use "0"
tr.id = 'Tr1 ID';
var td = tr.insertCell(-1);
td.innerHTML = 'Inside of TD 1';
var td = tr.insertCell(-1);
td.innerHTML = 'Inside of TD 2';
var tr = table.insertRow(-1);
var td = tr.insertCell(-1);
td.innerHTML = 'Inside of TD 1';
var td = tr.insertCell(-1);
td.innerHTML = 'Inside of TD 2';

How to access all the row data when sending this

Let's say I have something like this:
<table>
<tr>
<th>ID</th>
<th>Name</th>
<th>Lastname</th>
<th>Options</th>
</tr>
<tr>
<td>1</td>
<td>John</td>
<td>McDonalds</td>
<td><img src="delete.png"/></td>
</tr>
</table>
function delete(this)
{
//how to access all the data from this row (id,name,lastname)
}
I would recommend to separate HTML from Jquery or javascript and work with events:
Add a selector in your HTML like delete:
<td><img src="delete.png"/></td>
And then just select the row and the columns you want to work with using eq function.
$('.delete').click(function(e){
e.preventDefault(); //disallowing the link
var row = $(this).closest('tr');
var td = row.find('td');
var id = td.eq(0).text(); //first column
var lastName = td.eq(1).text(); //second column
var options = td.eq(2).text(); //third column
alert("id: " + id +"\n" + "lastName: " + lastName + "\n" + "Options: " + options);
});
http://jsfiddle.net/7c4E3/
Alternatively you can make use of this answer to create an array of data if you wish.
Is it possible to add classes on those columns? If it is, try this:
HTML:
<table>
<tr>
<th>ID</th>
<th>Name</th>
<th>Lastname</th>
<th>Options</th>
</tr>
<tr>
<td class="id">1</td>
<td class="name">John</td>
<td class="lastname">McDonalds</td>
<td><a class="deleteRow" href="#" onclick=""><img src="delete.png"/></a>
</td>
</tr>
</table>
jQuery:
$(".deleteRow").click(function (e) {
var thisrow = $(this).closest("tr");
var id = thisrow.find(".id").text();
var name = thisrow.find(".name").text();
var lastname = thisrow.find(".lastname").text();
alert("You selected " + id + ": " + name + " " + lastname);
});
Here's a FIDDLE
Then i suggest you to try with jQuery way:
Here .del is the class name of the delete button and you can find that by .eq() function which selects elements by their indexes.
$('.del').on('click', function(){
var theRow = $(this).closest('tr').find('td');
var id = theRow.eq(0).text();
var fName = theRow.eq(1).text();
var lName = theRow.eq(2).text();
console.log(id + ' ' + fName + ' '+ lName);
});

Categories

Resources