How to move/reorder an html table row - javascript

The idea is to move a particular table row to a different location
HTML
<table id="grid1" class="table table-zebra">
<tbody>
<tr>
<td>Cont 1 tr 1</td>
</tr>
<tr>
<td>Cont 2 tr 2</td>
</tr>
<tr>
<td>Cont 3 tr 3</td>
</tr>
<tr>
<td>Cont 4 tr 4</td>
</tr>
<tr>
<td>Cont 5 tr 5</td>
</tr>
<tr>
<td>Cont 6 tr 6</td>
</tr>
<tr>
<td>Cont 6 tr 6</td>
</tr>
<tr>
<td>Cont 7 tr 7</td>
</tr>
<tr>
<td>Cont 8 tr 8</td>
</tr>
<tr>
<td>Cont 9 tr 9</td>
</tr>
<tr>
<td>Cont 10 tr 10</td>
</tr>
<tr>
<td>Cont 11 tr 11</td>
</tr>
<tr>
<td>Cont 12 tr 12</td>
</tr>
<tr>
<td>Cont 13 tr 13</td>
</tr>
<tr>
<td>Cont 14 tr 14</td>
</tr>
</tbody>
</table>
That is the basic table, now, how do I can I move the TR 11 in a away that it will be under TR 4, I'm sorry that I don't post any JS but I have no idea how to do it... I was looking at this JSbin which is nice but can't use it..

Move the 11th tr to under the 4th:
$("tbody tr:nth-child(11)").insertAfter("tbody tr:nth-child(4)");
Working demo
If you prefer vanilla, you need the selectors the other way around.
document.querySelector("tbody tr:nth-child(4)").insertAdjacentElement("afterend", document.querySelector("tbody tr:nth-child(11)"));

In the context of an HTML table with rows that look like this:
<tr class="form-grid-view-row">
<td>
<a class="up" href="#">⇑</a>
</td>
<td>
<a class="down" href="#">⇓</a>
</td>
<td>
<span id="index1" class="form-label">1</span>
</td>
<td>
<span id="span1" class="form-label">Value 1</span>
</td>
</tr>
And this script:
$('.up,.down').click(function () {
var row = $(this).parents('tr:first');
if ($(this).is('.up')) {
row.insertBefore(row.prev());
} else {
row.insertAfter(row.next());
}
});
$('.up,.down').click(function () {
This is selecting every DOM element with the class "up" and every element with the class "down", e.g. $('.up,.down').click(function () {. The function sets up a click handler for each element.
var row = $(this).parents('tr:first');
$(this) refers to the DOM element which is the target of the click handler (one of the "up" or "down" elements which was selected above). .parents() looks for tr:first, the first <tr> element starting with <a> and travelling up the DOM. It'll end up selecting the entire row.
if ($(this).is('.up')) {
This is checking to see whether or not the element selected has the class "up" or not.
row.insertBefore(row.prev());
This takes the row that was clicked, and moves it right above the upper-most sibling of the row that was clicked.
The jQuery methods used (insertBefore, prev, is, parents, etc.) are described in greater detail in the jQuery documentation.

You can do it by using JQuery Library.
// selecting tbody is bad instead you need to give an id or class to this tag and select according to this
var fourth = $( "tbody tr:nth-child(4)" ),
eleventh = $( "tbody tr:nth-child(11)" );
$( "tbody tr:nth-child(11)" ).insertAfter(fourth);

In order to move dynamically your elements you can add an event to all tbody children. What I basically do is select one element on first click then I move it after second element clicked.
$(document).on("ready", function () {
var $tbody = $("#grid");
var selected = null;
$tbody.children().on("click", function () {
if (selected == null)
selected = this;
else
{
$(selected).insertAfter(this);
selected = null;
}
});
});
It move after an element but is just an idea, you can customize it.
Your html should be like this.
<table>
<tbody id="grid">
<tr> <td> 1 </td> </tr>
<tr> <td> 2 </td> </tr>
<tr> <td> 3 </td> </tr>
<tr> <td> 4 </td> </tr>
</tbody>
</table>

Related

Pass dynamically created html table row innertext id via row click event

I have a htmltable that is dynamically created. I have made the rows clickable.
I need to pass the row innertext id to the script that fires when the row is clicked.
htmltable:
<table style="width:100%;">
<tr>
<th>id</th>
<th>name</th>
<th>other info</th>
</tr>
<tr>
<td class='table_row_click'>11</td>
<td class='table_row_click'>item 2</td>
<td class='table_row_click'>lmfao</td>
</tr>
<tr>
<td class='table_row_click'>22</td>
<td class='table_row_click'>item 2</td>
<td class='table_row_click'>lol</td>
</tr>
</table>
Click event:
$(document).ready(function ($) {
$(".table_row_click").click(function (e) {
//I need to use the clicked row ID here for something
});
});
$(e.target).closest('tr').find('td').first().text();
You can navigate up to the parent tr, find the td elemements, get the first one, and get its text.
Using closest('tr') will work if the class is on the td or tr level, as closest() can match on itself.

Hide a tr only if td contains no content AFTER a specific html tag

Is it possible to examine the content within a tr, AFTER an html element (br) to see if any exists? If there is no content after the br element, I'd like to hide the parent td. Please note that the html code is system generated and I cannot edit it.
I'm just not sure where to begin with this. Any help is greatly appreciated.
<table class="tabledefault">
<tbody>
<tr>
<td id="customfields">
<table class="tabledefault">
<tbody>
<tr><!-- this TR should be hidden -->
<td id="CAT_Custom_451068"><strong>Laser Tag</strong>
<br>
</td>
</tr>
<tr>
<td id="CAT_Custom_451069"><strong>Arcade</strong>
<br>Selected
</td>
</tr>
<tr>
<td id="CAT_Custom_450908"><strong>Bounce House (45 minutes) $100</strong>
<br>False
</td>
</tr>
<tr>
<td id="CAT_Custom_451307"><strong>Party Room Rental (per hour) $75</strong>
<br>True</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
Try using .each() , nextSibling , nodeValue , String.prototype.match() , .closest()
$("table tr td br").each(function(i, el) {
// if `br` next sibling does not contain alphanumeric characters,
// hide parent `tr` element
if (el.nextSibling.nodeType === 3
&& el.nextSibling.nodeValue.match(/\w+/) === null
|| $(el).next(":empty").length) {
$(this).closest("tr").hide()
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<table class="tabledefault">
<tbody>
<tr>
<td id="customfields">
<table class="tabledefault">
<tbody>
<tr><!-- this TR should be hidden -->
<td id="CAT_Custom_451068"><strong>Laser Tag</strong>
<br><span></span>
</td>
</tr>
<tr>
<td id="CAT_Custom_451069"><strong>Arcade</strong>
<br>Selected
</td>
</tr>
<tr>
<td id="CAT_Custom_450908"><strong>Bounce House (45 minutes) $100</strong>
<br>False
</td>
</tr>
<tr>
<td id="CAT_Custom_451307"><strong>Party Room Rental (per hour) $75</strong>
<br>True</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
Yes, you just get the trs, then find out if the first <br> element inside the first <td> has any following element siblings (I'm making an assumption there, that you don't want those hidden), or any following text node siblings that aren't blank. jQuery's contents is handy for that, as it includes text nodes. I'd probably loop through them backward:
$("#customfields .tabledefault tr").each(function(index) {
var $tr = $(this);
$tr.find("td:first").contents().get().reverse().some(function(node) {
if (node.nodeName.toUpperCase() === "BR") {
// Hide it, and we're done looping
$tr.hide();
return true;
}
if (node.nodeType != 3 || $.trim(node.nodeValue)) {
// Don't hide it, and we're done looping
return true;
}
});
});
I expect that can be optimized, but you get the idea.
Live Example:
var counter = 3;
tick();
function tick() {
$("#countdown").text(counter--);
if (counter < 0) {
hideIt();
} else {
setTimeout(tick, 500);
}
}
function hideIt() {
$("#customfields .tabledefault tr").each(function(index) {
var $tr = $(this);
$tr.find("td:first").contents().get().reverse().some(function(node) {
if (node.nodeName.toUpperCase() === "BR") {
// Hide it, and we're done looping
$tr.hide();
return true;
}
if (node.nodeType != 3 || $.trim(node.nodeValue)) {
// Don't hide it, and we're done looping
return true;
}
});
});
}
<table class="tabledefault">
<tbody>
<tr>
<td id="customfields">
<table class="tabledefault">
<tbody>
<tr>
<!-- this TR should be hidden -->
<td id="CAT_Custom_451068"><strong>Laser Tag</strong>
<br>
</td>
</tr>
<tr>
<td id="CAT_Custom_451069"><strong>Arcade</strong>
<br>Selected
</td>
</tr>
<tr>
<td id="CAT_Custom_450908"><strong>Bounce House (45 minutes) $100</strong>
<br>False
</td>
</tr>
<tr>
<td id="CAT_Custom_451307"><strong>Party Room Rental (per hour) $75</strong>
<br>True</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="countdown"> </div>

How to hide tr items when td is 0 in jquery?

I want to hide all of the <tr> where td's text is 0. How can I do that? I have to mention that in reality i have more than 600 rows. But the example below is a demo. THX
<table id ="list2">
<tbody>
<tr>
<td>2</td>
<td>213</td>
<td id ="hideRow">0</td>
<tr>
<tr>
<td>vb</td>
<td>asf</td>
<td id ="hideRow">0</td>
<tr>
<tr>
<td>cxvb</td>
<td>xcvb</td>
<td id ="hideRow">2</td>
<tr>
<tr>
<td>cas</td>
<td>asdf</td>
<td id ="hideRow">45</td>
<tr>
</tbody>
</table>
This is my try :| . The event is loaded by onclick event
$('#list2').find("tr td #hideRow").each(function(){
var txt2 = $(this).text();
if (txt2 =="0"){
$('#list2').find("tr").each(function(){
$(this).hide();
});
}
})
First of all do not use id for duplicate names. Try doing it like following.
<table id ="list2">
<tbody>
<tr>
<td>2</td>
<td>213</td>
<td class="hideRow">0</td>
<tr>
<tr>
<td>vb</td>
<td>asf</td>
<td class="hideRow">0</td>
<tr>
<tr>
<td>cxvb</td>
<td>xcvb</td>
<td class="hideRow">2</td>
<tr>
<tr>
<td>cas</td>
<td>asdf</td>
<td class="hideRow">45</td>
<tr>
</tbody>
</table>
$('#list2').find(".hideRow").each(function(){
var txt2 = $(this).text();
if (txt2 =="0"){
$(this).parent().hide();
}
})
IDs on elements need to be unique, you can't have multiple <td id="hideRow"> elements and expect things to play nicely all of the time. I'd suggest changing it to a class. Then, select all elements:
var elems = $('span.hideRow');
Filter to those whose text is 0:
elems = elems.filter(function() {
return $(this).text() === "0";
});
Get their parent <tr> element:
elems = elems.closest('tr');
Then, finally, hide them:
elems.hide();
That can, obviously, all be done in one line:
$('span.hideRow').filter(function() {return $(this).text() === "0";}).closest('tr').hide();

how to merge 2 rows together WITH 2 rows in html table?

I am not so good in English, to express myself, so I show it with examples to you!
Here is my HTML table with code:
<table border="1">
<tr id="tr1_1">
<td rowspan="2">1</td>
<td>tr1.1 td2</td>
<td>tr1.1 td3</td>
<td rowspan="2">
up/
down
</td>
</tr>
<tr id="tr1_2">
<td>tr1.2 td2</td>
<td>td1.2 td3</td>
</tr>
<tr id="tr2_1">
<td rowspan="2">2</td>
<td>tr2.1 td2</td>
<td>tr2.1 td3</td>
<td rowspan="2">
up/
down
</td>
</tr>
<tr id="tr2_2">
<td>tr2.2 td2</td>
<td>td2.2 td3</td>
</tr>
</table>
(You can see the result here)
For example, if I click on the second two rows' "up" link, the result should be this:
<table border="1">
<tr id="tr2_1">
<td rowspan="2">2</td>
<td>tr2.1 td2</td>
<td>tr2.1 td3</td>
<td rowspan="2">
up/
down
</td>
</tr>
<tr id="tr2_2">
<td>tr2.2 td2</td>
<td>td2.2 td3</td>
</tr>
<tr id="tr1_1">
<td rowspan="2">1</td>
<td>tr1.1 td2</td>
<td>tr1.1 td3</td>
<td rowspan="2">
up/
down
</td>
</tr>
<tr id="tr1_2">
<td>tr1.2 td2</td>
<td>td1.2 td3</td>
</tr>
</table>
(You can see the final result here)
So how could I do this? I know the prev() and before() methods in javascript, but it merge only 1 row with 1 row, but I want to merge 2 rows WITH 2 rows!
I hope, someone can help me! Thank you!
Try this jQuery code :
$('.up').click(function() {
tr = $('tr[id^="'+$(this).closest('tr').attr('id').slice(0, 3)+'"]')
tr.insertBefore(tr.eq(0).prev().prev())
return false;
})
$('.down').click(function() {
tr = $('tr[id^="'+$(this).closest('tr').attr('id').slice(0, 3)+'"]')
tr.insertAfter(tr.eq(1).next().next())
return false;
})
And have a look to your fiddle edited : http://jsfiddle.net/lulu3030/UQz8u/6/
Just some explanations :
closest('tr') method find the nearest parent which has a tr tag
slice(0, 3) get the first 3 characters of a string
=> variable tr selects all elements which has the same 3 first id characters
insertBefore and insertAfter methods allows to move selected elements
Could be done like that too:
DEMO
$(function () {
$('.up, .down').on('click', function () {
var $tr = $(this).closest('tr'),
$flag = $('<tr/>').insertBefore($tr),
$rows = $tr.add($tr.next('tr')).detach()
methods = $(this).is('.up') ? ['insertBefore', 'prevAll'] : ['insertAfter', 'nextAll'];
if ($flag[methods[1]]('tr').eq(1).length) {
$rows[methods[0]]($flag[methods[1]]('tr').eq(1));
$flag.remove();
} else $flag.replaceWith($rows);
});
});

How to avoid duplicate code (toggle when page loaded)?

See the code below, If you click on the sub-title row it then will hide the rows with it. It work well.
On the second sub-title row (<tr class="sub-title default-hide">) - I want this to toggle/hidden by default when the page loaded.. How to do this without writing duplicate code like below?
$(".sub-title").on("click",function() {
tr = $(this).find('span').hasClass("arrow2");
trSpan = $(this).find('span');
$(this).nextUntil(".sub-title").each(function() {
if (!$(this).hasClass('head-order')) {
$(this).toggle();
if (tr) {
trSpan.removeClass('arrow2').addClass('arrow1');
} else {
trSpan.removeClass('arrow1').addClass('arrow2');
}
}
});
});
HTML
<table border="1">
<tbody>
<tr class="head">
<td> title </td>
</tr>
<tr class="sub-title">
<td>Sub Title 1 <span class="arrow2"> </span></td>
</tr>
<tr> <td>Item 1</td> </tr>
<tr> <td>Item 2</td> </tr>
<tr> <td>Item 3</td> </tr>
<tr class="sub-title default-hide">
<td>Sub Title 2 <span class="arrow2"></span></td>
</tr>
<tr> <td>Item 4</td> </tr>
<tr> <td>Item 5</td> </tr>
<tr> <td>Item 6</td> </tr>
</tbody>
</table>
I created a jsFiddle example with the information you provided.
I edited the code a bit, using a default arrow-class and just adding the class close to it, to define the new style, which should make the code a little shorter.
$(".sub-title").on("click",function() {
var trSpan = $(this).find('span');
trSpan.toggleClass('closed');
$(this).nextUntil(".sub-title").each(function() {
if (!$(this).hasClass('head-order')) {
$(this).toggle();
}
});
});
To make the "default-hidden" - element closed on pageload, all I do is to trigger a click-event on it after binding the click-Handler.
$('.default-hide').trigger('click');
See the fiddle for a working example
Create a named function and call it a couple times:
var toggleArrow = function(el) {
tr = $(el).find('span').hasClass("arrow2");
trSpan = $(el).find('span');
$(el).nextUntil(".sub-title").each(function() {
if (!$(el).hasClass('head-order')) {
$(el).toggle();
if (tr) {
trSpan.removeClass('arrow2').addClass('arrow1');
} else {
trSpan.removeClass('arrow1').addClass('arrow2');
}
}
});
};
$(".sub-title").on("click", function(){ toggleArrow(this); });
$(".default-hide").each(function(i, el){ toggleArrow(this); });
You can trigger the click event manually for the default-hide rows.
Like this
$('.default-hide').trigger('click');

Categories

Resources