How to collect text from lines of a table? - javascript

I'm creating a userscript that collects and displays text from the following table using javascript / jQuery:
<table id="table-cours">
<tbody>
<tr>
<td class="calendar-time"> time1 </td>
<td>
<div class = popup-calendar-event> popup content 1 </div>
<div class = "link-event"> event 1 </div>
</td>
</tr>
<tr>
<td class="calendar-time"> time2 </td>
<td>
<div class = popup-calendar-event> popup content 2 </div>
<div class = "link-event"> event 2 </div>
</td>
</tr>
<tr>
<td class="calendar-time"> time3 </td>
<td>
<div class = popup-calendar-event> popup content 3 </div>
<div class = "link-event"> event 3 </div>
</td>
</tr>
</tbody>
</table>
I want to collect all the text contained in this table except that which is contained within the div.popup-calendar-event elements.
My objective is to display it like this:
time 1 : event 1
time 2 : event 2
time 3 : event 3
The problem is that the number of lines of the table can change, here I put 3 lines but they can be 1 or 10 or any other number.
I tried many ways like using the not() method, or a for() loop with an array of "tr" elements but it never works.

$('tr').each(function(data) {
var calTime = $(this).find('.calendar-time')[0].innerHTML;
var linkEvent = $(this).find('.link-event')[0].innerHTML;
$("#result").append('<li><b>' + calTime + '</b> : ' + linkEvent + '</li>');
console.log('<li><b>' + calTime + '</b> : ' + linkEvent + '</li>');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table id="table-cours">
<tbody>
<tr>
<td class="calendar-time">time1</td>
<td>
<div class=p opup-calendar-event>popup content 1</div>
<div class="link-event">event 1</div>
</td>
</tr>
<tr>
<td class="calendar-time">time2</td>
<td>
<div class=p opup-calendar-event>popup content 2</div>
<div class="link-event">event 2</div>
</td>
</tr>
<tr>
<td class="calendar-time">time3</td>
<td>
<div class=p opup-calendar-event>popup content 3</div>
<div class="link-event">event 3</div>
</td>
</tr>
</tbody>
</table>
<ul id="result"></ul>

You can use something like this to parse table content and obtain an array of objects
var data = $('#table-cours > body > tr').map(function($i, $r) {
var $row = $(this);
return {
title: $row.find('.calendar-time').text(),
event: $row.find('.link-event').text()
};
}).get();
After that you can use data array for whatever you need.

You can try something like
$(".calendar-time").each(function () {
console.log($(this).html() + '-' + $(this).next('td').find('.link-event').html());
});
fiddle demo-http://jsfiddle.net/bL644p7b/

$(function(){
$("#table-cours .popup-calendar-event").each(function(iter, item){
$(".result").append("<div> time "+(iter+1) +" "+ $(this).text() +"</div>");
});
});
You just each a each method to iterate. The first argument is the iterator.
http://jsfiddle.net/qufgyh3c/

var rows = $('#table-cours > tr');
var map = {};
rows.each(function(row){
var key = $(row).find('td.calendar-time');
var value = $(row).find('td > div.link-event');
map[key]=value;
});

$(document).ready(function() {
$(".calendar-time").each(function() {
var output = "";
output += $(this).text() + " : ";
output += $(this).next().find(".link-event").text();
$(".output").append(output);
});
});
JSFiddle: https://jsfiddle.net/cq772j9s/

I would do:
$.each($('#table-cours tr'), function (i, val) {
$('#results ul').append('<li><strong>' + $(val).find('td.calendar-time').text() + '</strong>:' + $(val).find('.link-event').text() + '</li>');
});
example fiddle here

Related

How can i get two input field values based on onclick function

I have a div in that div I have two input fields and update button like this:
<button type = "button" id = "add-botton" >Add Element </button>
<div id = "trace-div1" class = "trace">
<h4><span>Trace 1</span></h4>
<form>
<table>
<tbody>
<tr>
<td><label>X Axis: </label></td>
<td><input type="text" name="t_x_axis" class = "t_x_axis" id="x_axis_t1" size="50">
</td>
</tr>
<tr>
<td><label>Y Axis: </label></td>
<td><input type="text" name="t_y_axis" class = "t_y_axis" id="y_axis_t1" size="50"></td>
<td><button type = "button" name = "update-button-trace" class = "update-trace" id =
"update-botton-trace1" onclick="updatebtn(this)">Update </button></td>
</tr>
</tbody>
</table>
</form>
</div>
<script>
$(document).ready(function(){
$('#add-botton').click(function(){
var $div = $('div[id^="trace-div"]:last');
var num = parseInt( $div.prop("id").match(/\d+/g), 10 ) +1;
var $trace1div = $div.clone(true).prop('id', 'trace-div'+num );
$trace1div.find('span').text('Trace ' + num);
$trace1div.find("input[name='t_x_axis']").attr("id", "x_axis_t"+num).val("");
$trace1div.find("input[name='t_y_axis']").attr("id", "y_axis_t"+num).val("");
$trace1div.find("button[name='update-button-trace']").attr("id", "update-button -
trace"+num);
$div.after( $trace1div);
});
});
function updatebtn(el){
var id = $(el).attr('id');
}
}
</script>
Here I am cloning my div multiple times with diff.id's ,my problem is when I click update button i need those respective two input values.
I tried like this but here I am getting all input value like if I have add 3 divs those respective all values coming here each div has 2 input fields :
<script>
function updatebtn(el){
var id = $(el).attr('id');
$('input[type=text]:visible').each(function(){
console.log($(this).val());
})
})
</script>
Thanks
You need to use DOM traversal to find the input elements related to the button which was clicked. The simplest way to do that, given that you're already using jQuery, would be to use a delegated event handler for the dynamic button elements along with closest() and find().
It's also worth noting that your use of id attributes within the dynamic content is creating a lot more problems than it solves. I'd strongly suggest you remove them all and use common classes on all elements. That way you don't have the headache of having to manually update all the incremental ids when adding new content.
Try this:
jQuery(function($) {
var $traceContainer = $('#traces');
$('#add-button').click(function() {
var $div = $traceContainer.find('.trace:last').clone()
$div.find("input[name='t_x_axis']").val("");
$div.find("input[name='t_y_axis']").val("");
$traceContainer.append($div);
$div.find('span').text('Trace ' + ($div.index() + 1));
});
$traceContainer.on('click', '.update-trace', function() {
var $container = $(this).closest('table');
var xAxis = $container.find('input[name="t_x_axis"]').val();
var yAxis = $container.find('input[name="t_y_axis"]').val();
console.log(xAxis, yAxis);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button type="button" id="add-button">Add Element</button>
<div id="traces">
<div class="trace">
<h4><span>Trace 1</span></h4>
<form>
<table>
<tbody>
<tr>
<td><label>X Axis:</label></td>
<td><input type="text" name="t_x_axis" class="t_x_axis" size="50">
</td>
</tr>
<tr>
<td><label>Y Axis:</label></td>
<td><input type="text" name="t_y_axis" class="t_y_axis" size="50"></td>
<td><button type="button" name="update-button-trace" class="update-trace">Update </button></td>
</tr>
</tbody>
</table>
</form>
</div>
</div>
Finally, note that I added a div container around each .trace to make appending them and retrieving their index simpler. Also note that the form within each .trace seems redundant and can probably be removed.
You can use find value as $div.find('.t_y_axis').val()
$(document).ready(function(){
$('#add-botton').click(function(){
var $div = $('div[id^="trace-div"]:last');
var num = parseInt( $div.prop("id").match(/\d+/g), 10 ) +1;
var $trace1div = $div.clone(true).prop('id', 'trace-div'+num );
$trace1div.find('span').text('Trace ' + num);
$trace1div.find("input[name='t_x_axis']").attr("id", "x_axis_t"+num).val("");
$trace1div.find("input[name='t_y_axis']").attr("id", "y_axis_t"+num).val("");
$trace1div.find("button[name='update-button-trace']").attr("id", "update-button-trace"+num);
$div.after( $trace1div);
console.log( 'last t_y_axis => ' , $div.find('.t_y_axis').val());
console.log( 'last t_x_axis => ' , $div.find('.t_x_axis').val());
});
});
function updatebtn(el){
var id = $(el).attr('id');
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button type = "button" id = "add-botton" >Add Element </button>
<div id = "trace-div1" class = "trace">
<h4><span>Trace 1</span></h4>
<form>
<table>
<tbody>
<tr>
<td><label>X Axis: </label></td>
<td><input type="text" name="t_x_axis" class = "t_x_axis" id="x_axis_t1" size="50">
</td>
</tr>
<tr>
<td><label>Y Axis: </label></td>
<td><input type="text" name="t_y_axis" class = "t_y_axis" id="y_axis_t1" size="50"></td>
<td><button type = "button" name = "update-button-trace" class = "update-trace" id =
"update-botton-trace1" onclick="updatebtn(this)">Update </button></td>
</tr>
</tbody>
</table>
</form>
</div>
try using the following function.since both the input text boxes have their id you can use the same to get the value of the inputs.
Hope it helps!
function updatebtn(el) {
var x1 = document.getElementById('x_axis_t1');
var y1 = document.getElementById('y_axis_t1');
alert('x-axis is ',x1.value, ' and y-axis is', y1.value)
}
you need to develop your updatebtn().
function updatebtn(el){
var element = $(el),
parent_table = element.parentsUntil('table');
x_axis = parent_table.find('.t_x_axis').val();
y_axis = parent_table.find('.t_y_axis').val();
}

HTML table with editable fields accessed in javascript.

I am trying to build a table that will allow users to change the value of a cell(s) and then "submit" that data
to a JavaScript (only please) method that turns the tables data into a json dataset.
I started by trying to updated the value of just one field. QTY in this case. I am able to loop over the table and get the static values, but I am not able to catch the user input value.
question: What is a JavaScript only (if possible) way to capture user change(able) values from a table?
function updateQTY() {
//getData from table
//gets table
var lines = "";
var oTable = document.getElementById('items');
//gets rows of table
var rowLength = oTable.rows.length;
var line = "";
//loops through rows, skips firts row/header
for (i = 1; i < rowLength; i++) {
//gets cells of current row
var oCells = oTable.rows.item(i).cells;
var qty = oCells.item(2).innerHTML;
//alert("qty: " + wty);
qty = qty.substr(oCells.item(2).innerHTML.indexOf('value=') + 7);
qty = qty.substr(0, qty.indexOf('" class='));
//alert(qty);
line = line +
'{ "item": "' + oCells.item(0).innerHTML + '",' +
' "discription": "' + oCells.item(1).innerHTML + '",' +
' "qty": "' + qty + '"},'
}
//alert(line);
var jsonData = JSON.parse('[' + line + '{"quickwayto":"dealwith,leftbyloop"}]');
alert("lines: " + JSON.stringify(jsonData));
}
<form action='#'>
<table class='mdl-data-table mdl-js-data-table' id='items'>
<thead>
<tr>
<th>item</th>
<th>discription</th>
<th>QTY</th>
</tr>
</thead>
<tbody>
<tr>
<td class='mdl-data-table__cell--non-numeric'> widget_1 </td>
<td class='mdl-data-table__cell--non-numeric'>it's fun</td>
<td>
<div class='mdl-textfield mdl-js-textfield'><input type='text' name='qty1' id='value1' value='5' class='mdl-textfield__input'></div>
</td>
</tr>
<tr>
<td class='mdl-data-table__cell--non-numeric'> widget_2 </td>
<td class='mdl-data-table__cell--non-numeric'>it's super fun</td>
<td>
<div class='mdl-textfield mdl-js-textfield'><input type='text' name='qty2' id='value2' value='5' class='mdl-textfield__input'></div>
</td>
</tr>
</tbody>
</table>
<div>
<input type='button' value='update' onclick='updateQTY()' class='mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect'>
</div>
</form>
THANK YOU
Instead of selecting the entire td element, retrieve only what you really need using querySelector (or use jQuery if possible). Find the input element and access the value, it's a lot easier than doing all of that unecessary parsing of the inner html of the entire cell.
function updateQTY() {
//getData from table
//gets table
var lines = "";
var oTable = document.getElementById('items');
//gets rows of table
var rowLength = oTable.rows.length;
var line = "";
//loops through rows, skips firts row/header
for (i = 1; i < rowLength; i++) {
//gets cells of current row
var oCells = oTable.rows.item(i).cells;
var qty = oCells.item(2).querySelector(".mdl-textfield__input").value;
line = line +
'{ "item": "' + oCells.item(0).innerHTML + '",' +
' "discription": "' + oCells.item(1).innerHTML + '",' +
' "qty": "' + qty + '"},'
}
//alert(line);
var jsonData = JSON.parse('[' + line + '{"quickwayto":"dealwith,leftbyloop"}]');
alert("lines: " + JSON.stringify(jsonData));
}
<form action='#'>
<table class='mdl-data-table mdl-js-data-table' id='items'>
<thead>
<tr>
<th>item</th>
<th>discription</th>
<th>QTY</th>
</tr>
</thead>
<tbody>
<tr>
<td class='mdl-data-table__cell--non-numeric'> widget_1 </td>
<td class='mdl-data-table__cell--non-numeric'>it's fun</td>
<td>
<div class='mdl-textfield mdl-js-textfield'><input type='text' name='qty1' id='value1' value='5' class='mdl-textfield__input'></div>
</td>
</tr>
<tr>
<td class='mdl-data-table__cell--non-numeric'> widget_2 </td>
<td class='mdl-data-table__cell--non-numeric'>it's super fun</td>
<td>
<div class='mdl-textfield mdl-js-textfield'><input type='text' name='qty2' id='value2' value='5' class='mdl-textfield__input'></div>
</td>
</tr>
</tbody>
</table>
<div>
<input type='button' value='update' onclick='updateQTY()' class='mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect'>
</div>
</form>
You need to use document.getElementById('value2').value instead of .innerHTML.indexOf('value=')
You're making yourself a lot of work here. You have a table. All you need to do is convert that to JSON. I would suggest you look at the library below that does that in around one line of native java-script.
http://www.developerdan.com/table-to-json/

Trying to sum from a jquery selector and update an element

I need to sum some text elements and update an input text, following is the far I could go:
This would be a correct example. I want to sum the text from within the <span> if the the <tr> contains the class ui-state-error
HTML
<table>
<tr id="rp-10-1-1" class="ui-state-error" style="width:50px; height:50px;">
<td><span id="pr-10-1-1">100</span><td>
</tr>
<tr id="rp-10-1-2" class="ui-state-highlight" style="width:50px; height:50px;">
<td><span id="pr-10-1-2">200</span><td>
</tr>
<tr id="rp-10-1-3" class="ui-state-error" style="width:50px; height:50px;">
<td><span id="pr-10-1-3">300</span><td>
</tr>
</tr>
</table>
<input type="text" id="sumhere">
JAVASCRIPT
$( 'tr[id^="rp-"]' ).click(
function() {
$('tr[id^="rp-"]').each(function(data, val) {
var rps = $(this).attr("id").split("-");
if ($("#pr-" + rps[1] + '-' + rps[2] + '-' + rps[3]).hasClass("ui-state-error")) {
console.log($("#pr-" + rps[1] + "-" + rps[2] + "-" + rps[3]).text());
}
});
}
);
tr would td are not recognized as a valid html. If you wish to extract just the total of the span elements, you may do the following :
var total = 0;
$('span[id^=hp]').each(function() // selects span starting with id=hp
{
total += parseInt($(this).text());
});
$("#sumhere").val(total);
Based on your updated HTML :
var total = 0;
$('tr[id^=rp-10-1] span').each(function() // selects span withing the tr element starting with id=rp-10-1
{
if(!isNaN(parseInt($(this).text()))) // condition for safety check while converting text to interger.
total += parseInt($(this).text());
});
$("#sumhere").val(total);
Example : https://jsfiddle.net/DinoMyte/7nhx26a2/3/
Demo: https://jsfiddle.net/zzaj1jye/
HTML:
<tr id="rp-10-1-1">
<span id="hp-10-1-1" class="ui-state-error">10</span>
<span id="hp-10-1-2" class="ui-state-error">20</span>
<span id="hp-10-1-3" class="ui-state-error">30</span>
</tr>
<input type="text" id="sumhere">
JS:
$(function() {
var total = 0;
$('span').each(function() {
if ( $(this).hasClass('ui-state-error') ) {
total += parseInt($(this).text());
}
});
$("#sumhere").val(total);
});

JQuery For each loop with HTML table data

So I have an HTML table that looks like the following.
<div class="timecard">
<h3>tommytest</h3>
<table class="misc_items timecard_list" border="0" cellpadding="2" cellspacing="0" style="margin:0 auto;">
<tbody>
<tr class="display_row odd">
<td align="left" class="job_code" style="color:#000099">2400-Orchard</td>
<td align="right">9:47am</td>
<td align="right">5/19/2014</td>
<td align="right" class="hrs">01:00</td>
</tr>
<tr class="display_odd row">
<td align="left" class="job_code" style="color:#000099">1200-Duffy's</td>
<td align="right">12:37am</td>
<td align="right">5/17/2014</td>
<td align="right" class="hrs">2:00</td>
</tr>
</tbody>
</table>
</div>
<div class="timecard">
<h3>testtest</h3>
<table class="misc_items timecard_list" border="0" cellpadding="2" cellspacing="0" style="margin:0 auto;">
<tbody>
<tr class="display_row odd">
<td align="left" class="job_code" style="color:#000099">2400-Orchard</td>
<td align="right">9:47am</td>
<td align="right">5/19/2014</td>
<td align="right" class="hrs">01:00</td>
</tr>
<tr class="display_odd row">
<td align="left" class="job_code" style="color:#000099">1200-Duffy's</td>
<td align="right">12:37am</td>
<td align="right">5/17/2014</td>
<td align="right" class="hrs">2:00</td>
</tr>
</tbody>
</table>
</div>
<div id="total"></div>
Then I have a jquery script that takes the total "job_code" hours and adds them up for each individual one. However, right now the script combines "tommytest" and "testtest" job codes together. I'm trying to get it to calculate each one individually and print it underneath each's respected table. Any ideas are greatly appreciated.
$(document).ready(function () {
var timeString = $(this).next('td.hrs').text();
var components = timeString.split(':');
var seconds = components[1] ? parseInt(components[1], 10) : 0;
var hrs = parseInt(components[0], 10) + seconds / 60;
total += hrs;
var temp = [];
$('.job_code').each(function (index, element) {
var text = $(this).text();
if (text != 'Out') {
temp.push(text);
}
});
// remove duplicates
var job_code = [];
$.each(temp, function (index, element) {
if ($.inArray(element, job_code) === -1) job_code.push(element);
});
var sum = {};
$.each(job_code, function (index, element) {
var total = 0;
$('.job_code:contains(' + element + ')').each(function (key, value) {
var timeString = $(this).siblings('td.hrs').text();
var components = timeString.split(':');
var seconds = components[1] ? parseInt(components[1], 10) : 0;
var hrs = parseInt(components[0], 10) + seconds / 60;
total += hrs;
sum[index] = {
'job_code': element,
'total': total
};
});
});
console.log(sum);
$.each(sum, function (index, element) {
$('#total').append('<p>Total for ' + element.job_code + ': ' + element.total + '</p>');
});
});
Link to jsFiddle: http://jsfiddle.net/Ha546/2/
If at all possible I'd like this to be dynamic as there will be more than just these two tables. Thanks ahead of time for the help.
When you query for the TD tags, $(this).next('td.hrs') you are not being specific enough about which table you want the TD tags from. If you are more specific, for example, adding an id to the tables,
<table id="tommytest">...</table>
<table id="testtest">...</table>
then you can query by table like so:
var tdsFromTommytest = $(this).next('#tommytest td.hrs')
var tdsFromTesttest = $(this).next('#testtest td.hrs')
Now that you have the two separate TD lists, you can process how you want. That, I think is the crux of your problem. But hopefully that helps you enough to see how you'd update a separate total tag under each table.
You could do this for tommyTest and subsequently for testtest :
Add id to the individual table
<table id="tommyTest">
And in javascript create different method for calculating the value :
$('#tommyTest').find('.job_code').each(function (index, element) {
var text = $(this).text();
if (text != 'Out') {
temp.push(text);
}
});

How to transform HTML table to list with JQuery?

How would I transform a table
<table>
<tr>
<td>Name</td>
<td>Price</td>
</tr>
<tr>
<td>Name</td>
<td>Price</td>
</tr>
</table>
to a list of paragraphs with jQuery
<ul>
<li>
<p>Name</p>
<p>Price</p>
</li>
<li>
<p>Name</p>
<p>Price</p>
</li>
</ul>
<p><a id="products-show-list">Toggle list view</a></p>
<script type="text/javascript">
$("#products-show-list").click(function(){...});
</script>
function convertToList(element) {
var list = $("<ul/>");
$(element).find("tr").each(function() {
var p = $(this).children().map(function() {
return "<p>" + $(this).html() + "</p>";
});
list.append("<li>" + $.makeArray(p).join("") + "</li>");
});
$(element).replaceWith(list);
}
You could try:
function convertToList() {
var list = $("<ul></ul>");
$("table tr").each(function() {
var children = $(this).children();
list.append("<li><p>" + children[0].text() + "</p><p>" + children[1] + "</p></li>");
}
$("table").replaceWith(list);
}
This still has some work left, but this is what I got to work so far:
<script>
$(function(){
t2l("uglytable");
});
function t2l(divname)
{
var ulist = $("<ul></ul>");
var table = "div." + divname + " table";
var tr = "div." + divname + " table tr";
$(tr).each(function(){
var child = $(this).children();
ulist.append("<li>" + child.text() + "</li>");
});
$(table).replaceWith(ulist);
}
</script>
<div class="uglytable">
<table border="1">
<tr>
<td>lakers</td>
</tr>
<tr>
<td>dodgers</td>
</tr>
<tr>
<td>angels</td>
</tr>
<tr>
<td>chargers</td>
</tr>
</table>
</div>
I can see this being useful in SharePoint which likes to use a bunch of nested tables to render a simple list which is more efficient using , ...

Categories