jQuery break out of table - javascript

I have a standard HTML formatted table, that dynamically generates the content, via Zend Framework. From which I have an issue altering the form internally PHP side. So I need to alter the tables appearance somehow. With that on the occasion I have an element show up in one of the rows and when this element shows up I want to break out of the table and then do something after it then start the table again.
Basically I want to inject the equivlant of
</tbody></table>/*other stuff*/<table><tbody> after the row containing the one element I seek which in this case is a label.
I tried $("label[for='theLable']").parents('tr').after('</tbody></table><br><table><tbody>') which appears to ignore the ending table parts add the br, and then does a complete open/close tag for table and tbody within the same table I am trying to break out of so inbetween tr tags basically it adds this new table
Whats the best way to approach this concept?
update with jsfiddle link
http://jsfiddle.net/cPWDh/

You can't really modify the HTML of the document the way you're thinking, since it's not a legitimate way to alter the DOM.
Instead, I would create a new table and .append the rows you want to move to it, which will automatically move them from their current location (instead of copying them):
$(document).ready(function() {
var $trow = $('label[for="specialLabel"]').closest('tr'),
$table = $trow.closest('table');
$('<table>').append( $trow.nextAll().andSelf() ).insertAfter($table);
});​
http://jsfiddle.net/cPWDh/1/

this approach won't work in js. What you could do if the table has not too many rows is this:
var nextTable = $("table").after("/*other stuff*/<table id="nextTable"></table>");
//now you loop over the lines of your original table that you want to have after the "break", and move them to the nextTable:
var before = true;
$("table tr").each(function(){
if ($(this).has("[for='theLable']")) {
before = false;
}
if (!before) {
nextTable.append($(this));
}
});

Related

How to find an element in a table without repeater

What's the best method to find the yellow-highlighted text in the above HTML?
Is there a way to find a text on the page in a specific tag?
I need to perform a click on this element, which inturn opens up the table 15112-1-table-ssrc_2210456055_recv
I tried by.xpath("//*[contains(text(),'ssrc_+\w+_recv')]"); but it didn't work
Assuming you know the ssrc_something_recv text beforehand:
var summary = element(by.xpath("//summary[starts-with(., 'ssrc_') and contains(., '_recv')]"));
summary.click();
Now, to locate the related table, you can use the following-sibling axis:
var table = summary.element(by.xpath("following-sibling::table"));

What's the fastest way of hiding and showing all the rows of a table in javascript?

I am building a filter for querying our html table (10k+ rows). My initial thought was to first hide all the rows, and then unhide the rows that match the specific query. If the filter is removed, then show all rows.
Is this a more optimal way of writing the hide/show all rows functions?
// optimize this!
this.hideAllRows = function() {
nodes = document.getElementById('table_body').children
for(var i=0, i_max=nodes.length; i<i_max; i++) {
nodes[i].style.display="none"
}
}
// optimize this!
this.showAllRows = function() {
nodes = document.getElementById('table_body').children
for(var i=0, i_max=nodes.length; i<i_max; i++) {
nodes[i].style.display=""
}
}
Thanks!
One solution would be to implement a pagination or "infinite" scroll feature. This would remove the need to render 10k dom elements simultaneously. You could render them in batches, as the user scrolls, or chunk them into pages.
Alternatively, you can try pulling the table out of the dom, hiding rows, then reinserting it. This will prevent unneccesary reflows/paints/etc.
As a rule of thumb using a pure javascript for loop is faster than using jQuery .each() but your basic selection using the .getElementById() and .children property is already well optimized.
However iterating through 10k+ elements in the browser is always going to be slow. Showing and hiding elements is best suited to record sets in the 100s not the 1000s.
Why not make an AJAX request that returns data (presumably from a database) already formated as <tr>...some <td>s here....</tr><tr>...some <td>s here....</tr>?
That way you can let your database do all the heavy lifting when it comes to filtering, they are optimized to do this. It keeps your code is simple, your bandwidth is reduced, and your DOM manipulation is kept to a minimum.
Whenever you want to apply a filter, you can make a $.ajax request.
function filter(criteria){
$.ajax({
url : myDataUrl,
type : "POST",
data : {criteria : criteria}
})
.success(function (data){
$("#table-body").html(data);
});
}

jquery if statement for div id

So I have an HTML table that populates based on a mysql query. It is contained within:
<div id="punchclock" class="timecard">
And I have the following jQuery script which calculates the totals of the times entered into the HTML table. However, it is repeating the "Total:" line of the script in the header (a separate div) and the table I want. Is there a way to ensure the code only outputs to the desired div?
$('table').each(function(){
var tr = {};
$(this).find('tr').each(function(){
var key = $(this).find('td.job_code').text();
var val1 = toSeconds($(this).find('td.hrs').text());
//var val = +$(this).find('td.hrs').text().split(':')[0];
if(tr[key]){
tr[key]+=val1;
}else{
tr[key]=val1;
}
});
$(this).append(function(){
var tfoot = $('<tfoot/>', {
html: addRows(tr)
});
return tfoot;
});
});
I believe the issue lies with the tfoot return statement as it is returning it to the header div and my table div. As always, any help is greatly appreciated. Thanks.
Select only the table in the div you have defined:
$('#punchclock table').each....
Your current code will run for every table on the page, and it sounds like you have multiple tables. By selecting #punchclock table, it only uses the tables inside #punchclock.
If you want to run this for only one table, it would be better to give that one table an id like <table id="schedule">, then get rid of your each loop, and select the table directly like $('table#schedule').
Also, this block looks suspect:
$(this).append(function(){
var tfoot = $('<tfoot/>', {
html: addRows(tr)
});
return tfoot;
});
I don't know what addRows does but it does not look necessary. Try this instead:
$(this).append($('<tfoot/>').append(tr));

Browser doesn't renders table element | jsFiddle example

My code makes a cross domain request to fetch the source of a webpage, using James Padolsey's "cross domain mod for jQuery": https://github.com/padolsey/jQuery-Plugins/tree/master/cross-domain-ajax;
Then it selects the first table and appends it to a existing div.
But the appended table doesn't get rendered properly. Can anyone take a look at this fiddle and tell me why?
http://jsfiddle.net/6ZgRf/
You're using jQuery.. so you can traverse it by turning it into a jQuery object
function stripViewResponse() {
// Select table element
var fetchedTable = $(antwort).find('table')[0]; // find first table
// append table
$('#new').append(fetchedTable);
}
http://jsfiddle.net/6ZgRf/1/
You can also try this
function stripViewResponse() {
// Select table element
var fetchedTable = $(antwort).find('table').eq(0);
// append table
$('#new').append(fetchedTable);
}

clone table row

How can i use javascript (i assume) to clone a table row like ive beautifully illustrated in the picture below?
You can hookup a live event to all the buttons. If you give them a class of clone for instance the following will work.
$('input.clone').live('click', function(){
//put jquery this context into a var
var $btn = $(this);
//use .closest() to navigate from the buttno to the closest row and clone it
var $clonedRow = $btn.closest('tr').clone();
//append the cloned row to end of the table
//clean ids if you need to
$clonedRow.find('*').andSelf().filter('[id]').each( function(){
//clear id or change to something else
this.id += '_clone';
});
//finally append new row to end of table
$btn.closest('tbody').append( $clonedRow );
});
Please Note:
If you have elements in the table row with id's you will need to do a .each through them and set them to a new value otherwise you will end up with duplicate id's in the dom which is not valid and can play havoc with jQuery selectors
You can do this like so
If you want a really simple solution, just use innerHTML:
var html = document.getElementById("the row").innerHTML;
var row = document.createElement('p');
row.innerHTML= html;
document.getElementById("table id").appendChild(row);
For what purpose do you want to use the data? I've done similar things previously on data input forms and generally I've found it to be beneficial to the users not to manipulate everything in Javascript but to hook to store the data on the server and interface with AJAX.
The issue is that as soon as you start letting users do this sort of complex table manipulation and they accidentally hit the back button you end up with a lot of disgruntled punters. Coding up transient storage on a database isn't that much harder than manipulating Javascript and in fact can be easier as you can break the operations down more easily. Debugging is simpler for that reason too (you always have inspect access to the current state of your table).
Lots of option for handling via AJAX - the simplest being to just use a place-holder division and feed the whole table structure in as needed.
A jQuery example:
$(document).ready(function(){
$('TABLE.recs').delegate('INPUT.clone','click',function(e){
e.preventDefault();
var s = $(this).parent().parent().clone().wrap('<div>').parent().html();
$('TABLE.recs TBODY TR:last').after(s);
});
});

Categories

Resources