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

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

Related

Hide elements without knowing complete id

I have a table like below
<table id="categoriesTable">
<tr id=row_id1_dynamicdata>
<td>...</td>
<td>..</td>
</tr>
<tr id=row_id2_dynamicdata>
<td>...</td>
<td>..</td>
</tr>
<tr id=row_id3_dynamicdata>
<td>...</td>
<td>..</td>
</tr>
<tr id=row_id4_dynamicdata>
<td>...</td>
<td>..</td>
</tr>
</table>
I want to hide all rows except row whose id contains id4. I won't have full id.
I came up with below jQuery code, but as I don't have full id, it doesn't work.
var idValue = document.getElementById(someElement);
$('#categoreisTable').find('tr').not($('#row_' +idValue)).hide();
How to filter with only half the id?
You can use the "Attribute starts with" selector to find the rows which don't match the one with the specified idValue. For example:
$('#someElement').on('change', function() {
var idValue = this.value;
$('#categoriesTable')
.find('tr')
.show() // not needed if you only want to hide
.not('[id^="row_id' + idValue + '_"]')
.hide();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="categoriesTable">
<tr id=row_id1_dynamicdata>
<td>.1..</td>
<td>..</td>
</tr>
<tr id=row_id2_dynamicdata>
<td>.2..</td>
<td>..</td>
</tr>
<tr id=row_id3_dynamicdata>
<td>.3..</td>
<td>..</td>
</tr>
<tr id=row_id4_dynamicdata>
<td>.4..</td>
<td>..</td>
</tr>
</table>
<input type="text" id="someElement" />
You can use querySelectorall on the tr element and then run a loop to only show rows that include id4 in their id.
Run the snippet below:
var idValue = document.querySelectorAll('tr');
for (i = 0; i < idValue.length; i++) {
if (idValue[i].id.includes("id4")) {
idValue[i].style.display = "block";
} else {
idValue[i].style.display = "none"
}
}
<table id="categoriesTable">
<tr id=row_id1_dynamicdata>
<td>row1</td>
<td>..</td>
</tr>
<tr id=row_id2_dynamicdata>
<td>row2</td>
<td>..</td>
</tr>
<tr id=row_id3_dynamicdata>
<td>row3</td>
<td>..</td>
</tr>
<tr id=row_id4_dynamicdata>
<td>row 4</td>
<td>..</td>
</tr>
<tr id=anotherrow_id4_dynamicdata>
<td>another row with id4</td>
<td>..</td>
</tr>
</table>
You can use document.getElementsByTagName to get all id contain id4.
Then, just to hide them.
let ElementArray = Array.prototype.filter.call(document.getElementsByTagName('tr'), element => element.id.match('id4'));
let idArray = ElementArray.forEach(element => document.getElementById(element.id).style.display="none");
You can simply use:
$('#categoriesTable tr').not('[id^="row_id4_"]').hide();

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

jQuery - Select current table row values

When someone clicks on the Download button in my table, I want to pass the date values from that particular row to a function. Currently I can only pass the date values from the first table row.
This is the selector I'm using:
$(this).parent().find('#period-start');
Which always returns:
[<td id=​"period-start">​5/1/2013​</td>]
I've tried combinations of the parent, child, find and closest selectors, but haven't been able to stumble across the correct one to grab the date values from the current row. Thanks.
Table
<table id="tblStatements" class="table">
<thead>
<tr>
<th>Period Starting</th>
<th>Period Ending</th>
<th>Download</th>
</tr>
</thead>
<tbody>
<tr>
<td id='period-start'>5/1/2013</td>
<td id='period-end'>5/31/2013</td>
<td><button type='submit'>Download</button></td>
</tr>
<tr>
<td id='period-start'>4/1/2013</td>
<td id='period-end'>4/30/2013</td>
<td><button type='submit'>Download</button></td>
</tr>
<tr>
<td id='period-start'>3/1/2013</td>
<td id='period-end'>3/31/2013</td>
<td><button type='submit'>Download</button></td>
</tr>
</tbody>
</table>
ID's are always supposed to be unique in HTML. So, you might try out this, w/o using an ID:
// Get the first td
var periodStart = $(this).closest('tr').children('td:eq(0)').text();
// Get the second td
var periodEnd = $(this).closest('tr').children('td:eq(1)').text();
FIDDLE DEMO
Use this - don't use duplicate ID's though, use class instead
$(this).closest('tr').find('#period-start');
or -
$(this).closest('td').siblings('#period-start');
try this
$(this).parent().siblings('#period-start');
Make sure all your ids is unique..your HTML is invalid.... change it to class and try this
$(this).parent().siblings('.period-start');
You should not use more then one element with the same id use class insidead.
<tr>
<td class='period-start'>5/1/2013</td>
<td class='period-end'>5/31/2013</td>
<td><button type='submit'>Download</button></td>
</tr>
<tr>
<td class='period-start'>4/1/2013</td>
<td class='period-end'>4/30/2013</td>
<td><button type='submit'>Download</button></td>
</tr>
<tr>
<td class='period-start'>3/1/2013</td>
<td class='period-end'>3/31/2013</td>
<td><button type='submit'>Download</button></td>
</tr>
and use this code to select proper element
$(this).parents('tr').find('.period-start');
try this
$.trim($(this).closest('tr').find('[id="period-start"]').html());//this gives start date

Manipulating <td>'s within different <tr>'s

I'm wondering if the following can be done.
I have a list of 'expenses' that I'm displaying in a table. 4 columns - amount, date, where, and what.
I was thinking I'd like to make each clickable via jQuery which would expand that particular expense, inline, to show a more detailed description.
What I'm trying to do is, on click, replace the contents of the 'tr' with a single 'td' that would contain the extended info. Problem is that 'td' only expands to about a quarter of the table. Is there any way of making it extend to the whole row, while maintaining the widths of the other 'td's in the other rows?
Here's what I would do. Working Demo.
<table id="expenses">
<thead>
<tr>
<td>Amount</td>
<td>Date</td>
<td>Where</td>
<td>What</td>
</tr>
</thead>
<tbody>
<tr class='expense' id='expense-1'>
<td>$5.99</td>
<td>4/2/2009</td>
<td>Taco Bell</td>
<td>Chalupa</td>
</tr>
<tr class='details' id='details-1'>
<td colspan='4'>
It was yummy and delicious
</td>
</tr>
<tr class='expense' id='expense-2'>
<td>$4.99</td>
<td>4/3/2009</td>
<td>Burger King</td>
<td>Whopper</td>
</tr>
<tr class='details' id='details-2'>
<td colspan='4'>
The king of burgers, indeed!
</td>
</tr>
<tr class='expense' id='expense-3'>
<td>$25.99</td>
<td>4/6/2009</td>
<td>Olive Garden</td>
<td>Chicken Alfredo</td>
</tr>
<tr class='details' id='details-3'>
<td colspan='4'>
I love me some italian food!
</td>
</tr>
</tbody>
</table>
With styles like these:
#expenses tr.expense {
cursor: pointer;
}
#expenses tr.details {
display: none;
}
And then have Javascript that looks like this:
$(function() {
$('tr.expense', '#expenses').click(function() {
var id = $(this).attr('id').split('-').pop();
var details = $('#details-'+id);
if(details.is(':visible')) {
details.hide();
} else {
details.show();
}
});
});
That should do it.
<td colspan="4"> ?

Categories

Resources