How to push top table rows to the bottom - HTML and JavaScript - javascript

I want to push certain rows to bottom of table, how can it be achieved in plain JavaScript?
In the table below, I want to push the 1st and 2nd rows to bottom:
<table>
<tr><td>ABCD</td></tr>
<tr><td>XYZ</td></tr>
<tr><td>adfs</td></tr>
<tr><td>asd</td></tr>
<tr><td>asdasd</td></tr>
</table>

Just do something like this:
Say you have table like so:
<table id='table'>
<tr id='row1><td>....</td></tr>
<tr id='row2><td>....</td></tr>
<tr id='row3><td>....</td></tr>
<tr id='row4><td>....</td></tr>
</table>
And an array with the new order like this:
NewOrder[1] = 3;
NewOrder[2] = 4;
NewOrder[3] = 2;
Then, do some something like this (not tested, so you may need to tweak the code, but this is the idea):
for ( i=1; i<=NewOrder.length; i++ ) {
$('row'+i).appendTo( '#table' );
}
This way, they are moved to the end of the table in order.
So you will have 3 moved to the end, then 4 behind it, then 2 behind that, etc. After they have ALL been appended to the end of the table, the first one will become the first row, and the rest will be in the correct order behind it.
Make the table style='display:none;' and then do $('#table').show(); at startup.
Edit Again: You could do a div around the entire body content, like
<body>
<div id='everything' style='display:none;'>
....
</div>
</body>
So that the entire page will be hidden (just blank white) for the fraction of a second it takes to load and order the table.
Then you would use:
$(function(){
$('#everything').show();
}
To show the entire page all at once as soon as the DOM is ready. It will take a fraction of a second longer for the page to load, but it will all load at once, so there won't be any flash of missing tables, etc. As long as EVERYTHING is in #everything, it will just look like the page loaded - should be transparent to the viewer.

Append the first child of the table body to the table body.
Twice.
tablebodyreference.appendChild(tablebodyreference.firstChild);
tablebodyreference.appendChild(tablebodyreference.firstChild);
A tablebody element can only have trs as children.

Related

Can't change class when using getElementsByClass

I've been going around in circles on this one. I have a PHP output that generates a series of DIV elements, and each has a class of L1, L2, L3, etc. These classes have a CSS that's basically blank so they display by default.
The problem is trying to change the class of each DIV to hide it, based on a simple onclick function. I'm using document.getElementsByClass to get (for example) just the DIV CLASS="L1" elements. But when I try to change the class, either with setAttribute('class', 'L1hide') or with className = "L1hide", nothing happens.
I know the HTML/CSS portion works, since I altered the PHP to generate "L1hide" instead of just "L1" and saw that the DIV CLASS="L1hide" elements were indeed hidden.
Is it because I'm trying to both grab the class and change the class at the same time? All the examples I see use getElementById, but this isn't practical for me since ID must be unique. I have zero, one, or more L1/L2/etc. class elements.
Here are some HTML code output by PHP:
<div class="L1"><h3>Owner</h3>
<table>
<tr><td>Jim Smith</td></tr>
</table>
</div>
<div class="L1"><h3>Executives</h3>
<table>
<tr><td>Harry Atkins</td></tr>
<tr><td>Galen Singh</td></tr>
</table>
</div>
<div class="L2"><h3>Managers</h3>
<table>
<tr><td>Andy Jones</td></tr>
<tr><td>Mary Thompson</td></tr>
<tr><td>Bill Murphy</td></tr>
</table>
</div>
And here is some javascript. This should change the image and hide the L1's. The image change DOES work (first 4 lines), but the style won't change (last 2 lines) despite my burnt offerings:
managmentImage.onclick = function() {
if (managmentLevel == "TOP1.png") {
document.getElementById("managementImage").setAttribute("src", "TOP0.png");
managmentLevel = "TOP0.png";
document.getElementsByClassName("L1").className = "L1hide";
divL1 = "L1hide";
} else { ...
Note: There is basically duplicate "else" code to change the image back, and to re-display the L1's. I only provided the first half of the "if" statement since the solution would also apply to the remaining "else" portion.
getElementsByClass is returning an array-like collection of nodes; those don't have className, individual nodes do.
You can't iterate it normally, because it is a live collection: if you change the class of the first element, the array shortens by one, so you will only process half of the nodes if you iterate from start to end. Iterating from end to start fixes this issue.
var elements = document.getElementsByClassName("L1");
console.log(elements);
var i = elements.length;
while (i--) {
elements[i].className = "L1hide";
}
.L1hide {
display: none;
}
<div class="L1"><h3>Owner</h3>
<table>
<tr><td>Jim Smith</td></tr>
</table>
</div>
<div class="L1"><h3>Executives</h3>
<table>
<tr><td>Harry Atkins</td></tr>
<tr><td>Galen Singh</td></tr>
</table>
</div>
<div class="L2"><h3>Managers</h3>
<table>
<tr><td>Andy Jones</td></tr>
<tr><td>Mary Thompson</td></tr>
<tr><td>Bill Murphy</td></tr>
</table>
</div>
getElementByClassName() returns an array.
You must iterate on it and then change the property.

Rendering dynamic Enyo Repeaters

I need to make a data table for an enyo project I am working on that will ultimately display the result of an Ajax call.
This (Blatantly stolen from ryanjduffy here)seems to be a good starting point, but when I try to call setData() from a button event (rather than in the constructor) as I have here I get the following error:
InvalidCharacterError: String contains an invalid character # http://enyojs.com/enyo-2.1/enyo/source/dom/Control.js:681
I looked at the Control.js code and it seems that it tries to create a new node, but the this.tag property is set to null and things break.
I feel like I am missing something really simple, but I just can't see the problem yet...
Can someone tell me what I am doing wrong?
Thanks!
EDIT 1:
Apparently calling render() is not needed. Here is the original working version with render() commented out. Everything looks great. However, if I try to remove render() from the version that requires a button click, the repeater starts creating div's above the table instead of tr td's inside the table...
EDIT 2:
Basically, from what I can tell, the Repeater inside of a table will lose it's parent once the table is rendered (or something like that). The result is the Repeater will start rendering its new items outside of the original table and because a td tag without a table makes no sense, it just renders a div.
The solution I have come up with is to give the Repeater itself a table tag so its children always wind up in the right spot. This adds the challenge of needing to recreate the header line each time, but it is not that big of a deal. I have a working example if anyone is interested.
I'm sure you're not looking for a solution any longer but since I was mentioned in the post, I thought I'd let you know what I figured out. In short, my code shouldn't have worked but since browsers are forgiving, it did ... sort of.
When the code run at create time, it renders something like this:
<table>
<tr> <!-- header row --> </tr>
<div> <!-- repeater tag -->
<tr> <!-- repeater row --> </tr>
</div>
</table>
The browser looks at that and says, "Hey, dummy! No <div>s in a <table>" and kicks it out but leaves the <tr>s.
In your example, since you're delaying the render of the rows, Enyo renders:
<table>
<tr> <!-- header row --> </tr>
<div></div>
</table>
And the browser ejects the <div> and you're left with an empty table. When you later set the data, those rows are rendered into the div. Unfortunately, since you're rendering <tr> and <td>, those aren't valid outside a table so you just get text.
I found a couple solutions. The simplest was to set the tag of the Repeater to be TBODY which is allowed inside a table. The slightly more involved solution was to make the DataTable inherit from Repeater and set the header row to be chrome so they're not removed when updating the data.
Option #2 Fiddle
enyo.kind({
name:"DataTable",
tag: "table",
kind: "Repeater",
published:{
map:0,
data:0
},
handlers: {
onSetupItem: "setupItem"
},
components:[
{name:"row", kind:"DataRow"}
],
create:function() {
this.inherited(arguments);
this.mapChanged = this.dataChanged = enyo.bind(this, "refresh");
this.refresh();
},
refresh:function() {
if(this.map && this.data) {
this.buildHeader();
this.setCount(this.data.length);
}
},
buildHeader:function() {
if(this.$.header) {
this.$.header.destroyClientControls();
} else {
this.createComponent({name:"header", tag:"tr", isChrome: true});
}
for(var i=0;i<this.map.length;i++) {
this.$.header.createComponent({content:this.map[i].header, tag:"th"});
}
this.$.header.render();
},
setupItem:function(source, event) {
for(var i=0;i<this.map.length;i++) {
event.item.$.row.createComponent({content:this.data[event.index][this.map[i].field]});
}
event.item.render();
return true;
}
});

How to adjust the height of table inside a table

I have a web page whose layout is constructed using a Table
<table id="page-head">
<tr style="vertical-align: top">
<td class="s-part">
<table class="s-table" style="height: 131px; ">
<tr class="s-head"><td></td></tr>
<tr class="s-body"><td></td></tr>
</table>
</td>
<td class="main-part">
<div><!-- The Main Part --></div>
</td>
</tr>
</table>
<!-- Menu -->
<table id="page-foot"> . . . </table>
The Main Part contains the content of the page
-> in Page-Head, it contains logo and site links
-> in Page-Foot, it contains the actual content of the page.
The screen is below:
Page screenshot
I faced a problem: The s-part is a table and I had to resize it to match the height of the main-part. So I used this jQuery script
var adjustSideBar = function () {
var e = $("#page-head");
if ($(".s-table", e).outerHeight() < $(".main-part", e).outerHeight()) {
$(".s-table", e).css({ "height": $(".main-part", e).outerHeight() - 5 });
}
var e = $("#page-foot");
if ($(".s-table", e).outerHeight() < $(".main-part", e).outerHeight()) {
$(".s-table", e).css({ "height": $(".main-part", e).outerHeight() - 5 });
}
}
So it automatically adjusted as shown in (1) and (3) from the above Screen Shot
Now the problem is, When I use dynamic content like jQuery PlugIn and Toggling the div elements in page-foot -> main-part, the s-part is not resizing. Again I called the adjustSideBar() function whenever I Toggle the content in the page. But it resulted as below:
Before Toggling, 2. After Toggling & 3. Again Toggling of "Sec 1":
Toggling Screenshot
Note: the gray bar is an Expander constructed using a jQuery PlugIn.
The function call is done from here:
$("div[id^='sec']").click(function (e) {
$(".e-content", this).slideToggle();
// this to toggle the content of the Sec #
adjustSideBar();
});
Can I know what to do now guys, to resize the inner table s-part such that both s-part and main part of same heights?
If you want I can give additional codes that are involved also. But I think they are not concerned here. [ Additionally, I use PHP for server side programming for if there is something I can do with it too ]
Thank you in advance.
PS: I am not allowed to post images as of now. So I'm just Hyperlinking them.
First up, I should discourage using tables for layout.
For the answer, you should use the callback for slideToggle to call the sidebar adjustment after the animation instead of calling it right after the slideToggle function like so:
$("div[id^='sec']").click(function (e) {
$(".e-content", this).slideToggle(500, adjustSideBar);
}
Even like this it will first animate and adjust the background only after the toggle has finished. I am not certain this will fix your problem completely, but something you can work on.
I suggest using http://jsfiddle.net/ or similar to make a test case so your problem can be tested easier.

jQuery break out of table

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));
}
});

How do I auto-scroll to a specific table row?

I have an html page with a header, a table containing 100 items and a footer.
When there is a search, I highlight the row containing the data.
However, if the highlighted row is row 75, the user has to scroll down to find it.
How can I automatically scroll to that row?
I did see scrollTo() but see it only takes axis points.
Any suggestions?
Thanks.
(Using cgi in C, html, css and javascript/jquery)
You should be able to use scrollIntoView(). (It's on the DOM elements directly.)
Be aware that there are some layout situations where scrolling something on the page can cause IE6 and 7 to decide that random other stuff needs to be scrolled too.
try this:
<script>
function ScrollToElement(theElement){
var selectedPosX = 0;
var selectedPosY = 0;
while(theElement != null){
selectedPosX += theElement.offsetLeft;
selectedPosY += theElement.offsetTop;
theElement = theElement.offsetParent;
}
window.scrollTo(selectedPosX,selectedPosY);
}
</script>
<body onload="ScrollToElement(document.formName.elementName)">
I think you can do something like this:
Use this line where ever you like,
<a id="bookmark"></a>
and when you start your page, call it like this:
http://mypage.com/setting.php#bookmark
That worked for me without showing the anchor.
Check again for using bookmark in html
EDITED:
Check: JavaScript - Jump to anchor

Categories

Resources