jquery - for every row that contains string disabled button - javascript

table:
<table id=tblList>
<thead>
<th>Firstname</th>
<th>Lastname</th>
<th>Status</th>
<th>Action</th>
</thead>
<tbody>
<tr>
<td>Jane</td>
<td>Doe</td>
<td>Pending</td>
<td><button class="cancelThis">Cancel</button></td>
</tr>
<tr>
<td>John</td>
<td>Doe</td>
<td>Cancelled</td>
<td><button class="cancelThis">Cancel</button></td>
</tr>
</tbody>
</table>
and script
var search = 'Cancelled';
$('#tblAppointment tr td').filter(function () {
return $(this).text() == search;
}).parent('tr').css('color', 'red');
with code above, i've managed to changed the color of the row that contains "Cancelled" to red
and with this:
$('#tblAppointment tr td').filter(function () {
return $(this).text() == search;
}).find(".cancelThis").prop("disabled", true);
is not working.
should be: for every row that contains string "Cancelled" cancel button will be disabled. rows that doesn't contain string "Cancelled" will remain unaffected.
TIA.

You can just add the same logic as the one that is working, Add .parent('tr') before .find(".cancelThis").prop("disabled", true);
$('#tblAppointment tr td').filter(function() {
return $(this).text() == search;
}).parent('tr').find(".cancelThis").prop("disabled", true);
You can cut down you code a bit,
var search = 'Cancelled';
var t = $('#tblAppointment tr td').filter(function() {
return $(this).text() == search;
}).parent('tr');
t.css('color', 'red');
t.find(".cancelThis").prop("disabled", true);
Demo
var search = 'Cancelled';
$('#tblAppointment tr td').filter(function() {
return $(this).text() == search;
}).parent('tr').css('color', 'red');
$('#tblAppointment tr td').filter(function() {
return $(this).text() == search;
}).parent('tr').find(".cancelThis").prop("disabled", true);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id=tblAppointment>
<thead>
<th>Firstname</th>
<th>Lastname</th>
<th>Status</th>
<th>Action</th>
</thead>
<tbody>
<tr>
<td>Jane</td>
<td>Doe</td>
<td>Pending</td>
<td><button class="cancelThis">Cancel</button></td>
</tr>
<tr>
<td>John</td>
<td>Doe</td>
<td>Cancelled</td>
<td><button class="cancelThis">Cancel</button></td>
</tr>
</tbody>
</table>

Your initial query is getting a list of <td> elements. So when you call find on that, you're only searching inside the <td> (which doesn't have a .cancelThis) element. You'd have to do something like this:
$('#tblAppointment tr td').filter(function () {
return $(this).text() == search;
}).parent('tr').find(".cancelThis").prop("disabled", true);
However, I can think of one issue you might want to resolve. What if First or Last named is "Cancelled"? Your query would match that too. If you add a class to the status <td>, you can search for it specifically:
<table id='tblAppointment'>
<thead>
<th>Firstname</th>
<th>Lastname</th>
<th>Status</th>
<th>Action</th>
</thead>
<tbody>
<tr>
<td>Jane</td>
<td>Doe</td>
<td class='status'>Pending</td>
<td><button class="cancelThis">Cancel</button></td>
</tr>
<tr>
<td>John</td>
<td>Doe</td>
<td class='status'>Cancelled</td>
<td><button class="cancelThis">Cancel</button></td>
</tr>
</tbody>
</table>
$('#tblAppointment tr td.status').filter(function () {
return $(this).text() == search;
}).parent('tr').find(".cancelThis").prop("disabled", true);
This will only look at the text of the td.status elements, and not the other elements (like first and last name).

Related

Why I can't get tr elements

I work
HTML(The HTML part is generated via a JSON, this is just the template.) :
<table id="table-blog" class="order-table table table-hover">
<thead>
<tr>
<th>Title</th>
<th>Description</th>
<th>Tags</th>
<th>Url</th>
<th>Active</th>
</tr>
</thead>
<tbody>
<tr>
<td>Title</td>
<td>Description</td>
<td>Tags</td>
<td>Url</td>
<td><input type="checkbox"></td>
</tr>
<tr>
<td>Title</td>
<td>Description</td>
<td>Tags</td>
<td>Url</td>
<td><input type="checkbox"></td>
</tr>
<tr>
<td>Title</td>
<td>Description</td>
<td>Tags</td>
<td>Url</td>
<td><input type="checkbox"></td>
</tr>
</tbody>
</table>
Here the JS :
function syncBlog(blogs)
{
blogs = Object.values(blogs);
var tbody = $("#table-blog > tbody");
console.log($(tbody).children());
$(tbody).children().each(function(){
$(this).children('td:last-child').children("input").prop("checked", false);
});
if(blogs.length > 0)
{
blogs.forEach(blog =>
{
$(tbody).children().each(function(){
console.log($(this));
if($(this).children('td:first').text() == blog.title)
{
console.log(blogs);
$(this).children('td:last-child').children("input").prop("checked", true);
}
});
});
}
}
I don't why .children() returns nothing, however the table is filled before (by ajax call).
But if I try with native JS :
var tbody = document.querySelector("#table-blog > tbody");
console.log(tbody.children);
I will be able to see the HTMLCollection with all <tr>, but I can't use them and .length return me 0
Well,
Thank you all for your answers.
I was able to find the solution that now seems clear.
The DOM was not fully loaded before the execution of the function.
To solve the problem I made my AJAX call in synchronous:
Exemple:
$.ajax({
url:'Your url',
methode:'POST',//In my case
data:'Your data',
success:function(),
error:function(),
async:false,
});

Check if the element has text, if not add one

I have a simple table and I want to add specific text if an element is empty, so far my code looks like this:
$("table").each(function (index, tableID) {
$(tableID)
.find("thead tr th")
.each(function (index) {
index += 1;
$(tableID)
.find("tbody tr td:nth-child(" + index + ")")
.attr("data-title", $(this).text());
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<th>By Year</th>
<th>TEAM</th>
<th>GP</th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td>GSW</td>
<td>6.1</td>
</tr>
<tr>
<th>2016-17</th>
<td>GSW</td>
<td>6.1</td>
</tr>
<tr>
<th>2015-16</th>
<td>GSW</td>
<td>6.1</td>
</tr>
</tbody>
</table>
With this code am adding data-title and everything works fine, what am trying to achieve to add - when there is no data: so I modify my code:
$( "table" ).each( function( index, tableID ) {
$( tableID ).find( "thead tr th" ).each( function( index ) {
index += 1;
$( tableID ).find( "tbody tr td:nth-child(" + index + ")" ).attr( "data-title", $(this).text() );
if ($("tbody tr td:nth-child(" + index + ")" ).is(':empty')).append( "-" );
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<th>By Year</th>
<th>TEAM</th>
<th>GP</th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td>GSW</td>
<td>6.1</td>
</tr>
<tr>
<th>2016-17</th>
<td>GSW</td>
<td>6.1</td>
</tr>
<tr>
<th>2015-16</th>
<td>GSW</td>
<td>6.1</td>
</tr>
</tbody>
</table>
This part of code where am adding - when table element is empty doesn't work, can anybody try to help me with this?
Your if statement is not using valid syntax. You need the expression body after the if which contains the code to be executed. You cannot call a method from the if statement itself.
Try this:
$("table").each(function(_, table) {
$(table).find("thead tr th").each(function(i) {
let $th = $(this);
let $td = $(table).find("tbody tr td:nth-child(" + (i + 1) + ")");
$td.attr("data-title", $th.text());
if ($td.is(':empty')) {
$td.append("-");
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<th>By Year</th>
<th>TEAM</th>
<th>GP</th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td>GSW</td>
<td>6.1</td>
</tr>
<tr>
<th>2016-17</th>
<td>GSW</td>
<td>6.1</td>
</tr>
<tr>
<th>2015-16</th>
<td>GSW</td>
<td>6.1</td>
</tr>
</tbody>
</table>
However, it's worth noting that this code can be made more succinct with a single line of code:
$('tbody td:empty').text('-');
The code you're using to loop through the th/td and add the data attribute seems almost entirely redundant as the th value can be read at the point of use.
I simplified the code a little. I found it easier to make the header data-title values an array i could reference each iteration. The '-' for empty values was just a ternary expression tacked on to the end of the jQuery chain:
$(this).attr("data-title", h[i]).text($(this).text() || "-");
$("table").each(function() {
let h = [], i = 0
$("thead tr th").each(function() {
h.push($(this).text());
})
$(this).find("tbody tr>*").each(function() {
$(this).attr("data-title", h[i]).text($(this).text() || "-");
i++;
if (i >= h.length) i = 0
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<th>By Year</th>
<th>TEAM</th>
<th>GP</th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td>GSW</td>
<td>6.1</td>
</tr>
<tr>
<th>2016-17</th>
<td>GSW</td>
<td>6.1</td>
</tr>
<tr>
<th>2015-16</th>
<td>GSW</td>
<td>6.1</td>
</tr>
</tbody>
</table>

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

find child table selector from parent table - jQuery

I have a table structure like this. Fairly simple one.
<table id="myTable" class="table">
<thead>
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Email</th>
</tr>
</thead>
<tbody>
<tr>
<td>John</td>
<td>Doe</td>
<td>john#example.com</td>
</tr>
<tr>
<td>Mary</td>
<td>Moe</td>
<td>mary#example.com</td>
</tr>
<tr>
<td>July</td>
<td>Dooley</td>
<td>july#example.com</td>
</tr>
</tbody>
</table>
At runtime I am binding a new row to this table for a particular rowclick. This new row contains a new table.
Now on clicking the row again, I want to be able to remove the newly added row(the new table).
I am using bootstrap table.
Here is what I have tried so far.
$('#myTable').on('click-row.bs.table', function (e, row, $element) {
//if ($element.has('#newlyAddedTable').length) { ....// did not work
if ($('#myTable').has('#newlyAddedTable').length) { // this removes the table on any row click. Not what I intend to do
{
$("#newlyAddedTable").remove();
} else {
// some operation...
}
}
I want to be able to remove the newly added table on the row it was created.
Just more explanation based on the Answers below:
<tr> ----------> if i click this
<td>
<table id="newlyAddedTable"> ---------> this is added
</table>
</td>
</tr>
<tr> ----------> if i again click this or maybe any other row in the table
<td>
<table id="newlyAddedTable"> ---------> this is removed
</table>
</td>
</tr>
Update: from OP's comment below it sounds like the best way to implement the new table is to use a class selector and not an id selector. The code below has been updated accordingly. ***Where previously there was an id for newTable there is a class ---> #newTable ===> .newTable:
Just change:
$('#myTable').has('#newlyAddedTable').length
To:
$('.newlyAddedTable', $element).length //element === clicked row -- see demo
vvvvv DEMO vvvvv
$('#myTable').bootstrapTable().on('click-row.bs.table', function(e, row, $element) {
if( $('.newTable', $element).length ) {
$('.newTable', $element).remove();
} else {
$('td:first', $element)
.append( '<table class="newTable"><tr><td>NEW TABLE</td></tr></table>' );
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.7.0/bootstrap-table.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.7.0/bootstrap-table.min.css" rel="stylesheet"/>
<table id="myTable" class="table">
<thead>
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Email</th>
</tr>
</thead>
<tbody>
<tr>
<td>John</td>
<td>Doe</td>
<td>john#example.com</td>
</tr>
<tr>
<td>Mary</td>
<td>Moe</td>
<td>mary#example.com</td>
</tr>
<tr>
<td>July</td>
<td>Dooley</td>
<td>july#example.com</td>
</tr>
</tbody>
</table>
Try replacing your remove code with this:
$(document).on("click", "#newlyAddedTable", function(){
$(this).remove();
});
The code above registers a click listener on the document. The second parameter filters those events for those with the target #newlyAddedTable. This way you don't have to register a new click handler every time you insert a row (as in #VimalanJayaGanesh's solution).
P.S. If you are adding HTML that looks like this:
<tr>
<td>
<table id="newlyAddedTable">
</table>
</td>
</tr>
Then you are probably actually wanting to remove the parent tr (not the table with the id). There are two ways to fix this.
You can change the selector that filters click events and so have the tr handle the click rather than the table element in my example code:
$(document).on("click", "tr:has(#newlyAddedTable)", function(){
You can leave the selector as is but grab the parent tr from the table and remove that changing the remove line above to:
$(this).parents("tr").first().remove()
or
$(this).parent().parent().remove()
As I don't have your complete code / fiddler, here is a possible solution.
Are you looking for something like this?
$('#add').on('click', function()
{
var newRow = '<tr CLASS="newrow"><td colspan="3"><table><tr><td>Test</td><td>User</td><td>test#example.com</td></table></td></tr>'
$('#myTableBody').append(newRow);
Remove()
});
function Remove()
{
$('.newrow').off('click').on('click', function()
{
$(this).remove();
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table id="myTable" class="table">
<thead>
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Email</th>
</tr>
</thead>
<tbody id="myTableBody">
<tr>
<td>John</td>
<td>Doe</td>
<td>john#example.com</td>
</tr>
<tr>
<td>Mary</td>
<td>Moe</td>
<td>mary#example.com</td>
</tr>
<tr>
<td>July</td>
<td>Dooley</td>
<td>july#example.com</td>
</tr>
</tbody>
</table>
<button type='button' id='add'>Add</button>
Note:
The following line indicates that,
$('.newrow').off('click').on('click', function()
the click event will be binded to the new row only once.
The reason for adding 'off('click') is, when you are dynamically adding rows (with common class 'newrow') to the table, the events will be binded several times. To avoid that, remove the previously binded click event and add a new one.

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

Categories

Resources