Apply CSS on matching text - javascript

I am trying to apply a class where text matches with sibling elements.
My certain condition is:
I have a table with multiple rows based on data that I get through database.
One of the td elements has my defined class.
Now I wanted to apply a class only on those td elements where the text of this element matches with another one.
So It would be like, td's whose html/text is equal has that class.
I tried:
$('#table tbody>tr').find('td[class^="customtd"]').each(function() {
if($(this).html().trim() == $(this).siblings('td').html().trim()) {
$(this).addClass('active');
}else {
$(this).removeClass('active');
}
});

You'd have to iterate each sibling td (or use filter), check for a text match, then add the class:
$('#table tbody>tr').find('td[class^="customtd"]').each(function() {
var text = $(this).text();
$(this).siblings("td").filter(function() {
return $(this).text() == text;
}).addClass("active");
});

You have to set the value you are searching for and then loop through all table data. If you find a match, add the certain class.
Furthermore you should cache variables in jQuery and avoid using each() function since its performance is really bad compared to for loops.
//cache the element you are searching for
var search = $('.customtd').html().trim();
//cache the whole table so we can use a for loop
var table = $('#table tbody>tr>td');
//use for loop for more performance
for (var i = 0; i < table.length; i++) {
if(table.eq(i).html().trim() == search) {
table.eq(i).addClass('active');
}else {
table.eq(i).removeClass('active');
}
}
Here is a working example:
http://jsfiddle.net/jnh2heuh/2/

Related

How to select an element with specific css value in javascript

I want to select an element if it has a css as display block then do this function. If the element has the css as display block then remove ('hide') class from the header class.. This is what I want to do.. Any help?
Well, there are two solutions depending on what you want:
Solution 1
Looping through all elements and removing hide class from the current element if it has display block value in its style.
var elements = document.getElementsByTagName("*");
for(let i = 0; i < elements.length; i++) {
if(elements[i].style.display == "block") {
elements[i].classList.remove("hide");
}
}
Solution 2
Getting the reference of the element via HTML id.
var element = document.getElementById("YourElementID");
if(element.style.display == "block") {
element.classList.remove("hide");
}
You can define an id like this in your HTML file:
<div id="YourElementID">Div</div>
I am assuming that you want to determine if the element has the "hide" class by checking its display style. you don't need to do that, you can easily check its class list by using the following code:
element.classList.contains("hide");
There are several ways of collecting all the elements with display: block and i am not sure, which one performs best - or whether it performs good at all.
If you want all the Element instances of the page, which have a computed style of display: block you can do something like:
var $els = Array.from(document.body.querySelectorAll('*')).filter(function($el) {
return getComputedStyle($el).display === 'block';
});
Or ES6:
const $els = Array.from(document.body.querySelectorAll('*')).filter($el => getComputedStyle($el).display === 'block');
If you want the Element instances which have display: block literally set in the style-attribute, you have to do something like this:
var $els = Array.from(document.body.querySelectorAll('*')).filter(function($el) {
return $el.style.display === 'block';
});
I think it would perform better, if the selector in querySelectorAll() would be a little more specific.
Another option would be to use the TreeWalker API, but then you have to do a mutation, because you have to iterate over all the elements and push them to an array:
var $els = [];
walker = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT);
while (walker.nextNode()) {
if (getComputedStyle(walker.currentNode).display === 'block') {
$els.push(walker.currentNode);
}
}
Once you have all your elements, you can do something with them.
A little bit more information would be helpful, especially what exactly you want to achieve, once you have the elements, because then i could also provide more help. Maybe provide a code example?

jquery array of nodes

I have a table with 2 columns. One column with a checkbox and another one with plain text. I would like to generate an object array with the the check state and the text. I can go tr after tr with this:
$('#divInfCambios .frozen-bdiv tr').each(function(i)
{ ... }
How can access to td[1], check the state, and recover the text of td[2]?
I got the check state with:
$(this).find('input[type="checkbox"]').prop('checked')
I need now how to access node 2 (td[1]) and grab the text.
//run through each row
$('#divInfCambios .frozen-bdiv tr').each(function (i, row) {
var getInputByName = $(this).find('input[name="selection"]');
if (getInputByName.is(':checked') ){
}
// assuming you layout of the elements
var tds = $(this).find('td');
var getTdText = tds.eq(1).text();
});

Get div id's of all divs with a specific class

I am trying to get div ids of all div elements having a specific CSS class.
I am able to get [object HTMLDivElement] by using getElementByClass but I haven't been able to get id from this object.
Basically, entirely I want to do is
get div ids of all div elements that have a specific CSS class,
get data-title of all div elements,
match data-title of these div elements with a string,
make display:none of all non-matching div elements.
Here is what I have tried:
function FilterFiles(filterItem) {
var elements = document.getElementsByClassName("listItem");
for (var i = 0; i < elements.length; i++) {
alert(elements[i].id);
// get div id of divs with data-title !=(not equal) filterItem
// make display:none of matching divs
}
}
Here is the Fiddle with actual HTML http://jsfiddle.net/6bo1rjrt/1/.
var temp = new Array();
var title = new Array();
function FilterFiles(filterItem) {
$('.listItem').each(function ()
{
temp.push($(this).attr("id")); //get id of each div to array
alert($(this).attr("id"));
title.push($(this).attr("data-title")); //get title of each div to array
if($(this).attr("data-title") != filterItem) //check non matching div
{
$(this).hide(); //hide div
}
});
}
first u loop throught all div with specific class with each, then check it's "data-title".
You can use attribute-not-equal-selector for that. also you need to give ids to div elements:
function FilterFiles(filterItem) {
var ids= $('.listItem[data-title!="'+filterItem+'"]').map(function(){
return this.id;
}).get()
}
Working Demo
For hiding elements that do not have data-title value equal to:
$('.listItem[data-title!="'+filterItem+'"]').hide()
Using Jquery, you can do the following:
var arr = [];
$('.listItem').each(function(){
arr.push($(this).attr('id'));
});
Using jQuery .each():
var arr = [];
$('.listItem').each(function(){
arr.push(this.id);
});
Using jQuery .map()
var arr = $('.listItem').map(function() { return this.id; }).get();
I modified your fiddle example. see this updated fiddle
$("#filter").click(function () {
var filterItem = "A03-5(KAB製ヒーター付エアサスオペシート)_20140515154904.xlsx";
FilterFiles(filterItem);
});
function FilterFiles(filterItem) {
var elements = $("div.listItem");
elements.each(function(){
var el=$(this);
if(el.data("title")!=filterItem)
el.hide();
else
el.show();
});
/*for (var i = 0; i < elements.length; i++) {
alert(elements[i].id);
// get div id of divs with data-title !=(not equal) filterItem
// make display:none of matching divs
}*/
}

How to give a unique id for each cell when adding custom columns?

I wrote following code to add a custom column to my table. but i want to add a unique id to each cell in those columns. the format should be a(column no)(cell no>)
ex :- for the column no 4 :- a41, a42, a43, ........
So please can anyone tell me how to do that. Thank You!
$(document).ready(function ()
{
var myform = $('#myform'),
iter = 4;
$('#btnAddCol').click(function () {
myform.find('tr').each(function(){
var trow = $(this);
var colName = $("#txtText").val();
if (colName!="")
{
if(trow.index() === 0){
//trow.append('<td>'+iter+'</td>');
$(this).find('td').eq(5).after('<td>'+colName+iter+'</td>');
}else{
//trow.append('<td><input type="text" name="al'+iter+'"/></td>');
$(this).find('td').eq(5).after('<td><input type="text" id="a'+iter+'" name="a'+iter+'"/></td>');
}
}
});
iter += 1;
});
});
You seem to have code that's modifying the contents of the table (adding cells), which argues fairly strongly against adding an id to every cell, or at least one based on its row/column position, as you have to change them when you add cells to the table.
But if you really want to do that, after your modifications, run a nested loop and assign the ids using the indexes passed into each, overwriting any previous id they may have had:
myform.find("tr").each(function(row) {
$(this).find("td").each(function(col) {
this.id = "a" + row + col;
});
});
(Note that this assumes no nested tables.)
try this
if(trow.index() === 0){
//trow.append('<td>'+iter+'</td>');
$(this).find('td').eq(5).after('<td id="a'+column_no+cell_no+'">'+colName+iter+'</td>');
}else{
//trow.append('<td><input type="text" name="al'+iter+'"/></td>');
$(this).find('td').eq(5).after('<td id="a'+column_no+cell_no+'"><input type="text" id="a'+iter+'" name="a'+iter+'"/></td>');
}
you just have to define and iterate the column_no and cell_no variable
When all other cells are numbered consistently (for example using a data-attribute with value rXcX), you could use something like:
function addColumn(){
$('table tr').each(
function(i, row) {
var nwcell = $('<td>'), previdx;
$(row).append(nwcell);
previdx = nwcell.prev('td').attr('data-cellindex');
nwcell.attr('data-cellindex',
previdx.substr(0,previdx.indexOf('c')+1)
+ (+previdx.substr(-previdx.indexOf('c'))+1));
});
}
Worked out in this jsFiddle

confusion in jquery parents selector with hasClass function

var allChecked = $('.inboxCheckbox:checked');
if(allChecked.length > 0){
var messageIds = new Array();
var parentRow = null;
allChecked.each(
function(){
parentRow = $(this).parents('tr');
if(!(parentRow.hasClass('gradeA'))){
parentRow.addClass('gradeA');
increaseUnreadMessage();
}
parentRow = null;
messageIds.push($(this).val());
}
);
}else{
showInsMessage('<b class="redTxt">Please Select At Least One Message</b>');
}
i have multiple rows with once checkbox in each row... i was trying to add class gradeA to each row if checkbox is checked.... i do not want to call addClass if it already has class gradeA.... when i select multiple rows then it adds class to only one row. does that mean
lets say i have three rows with checkbox in each row and i select each checkbox when i run
$(':checked').each(
$(this).parents('tr')
)does it select all the rows with checked boxes or only the specfic parent row.... my assuption was it only gives the specific parent row..... if it gives specific row then it should work .. but once i add a class to parent row and move to another row then parentRow.hasClass('gradeA') return true... i am confused now if it checks all the row with checkboxes then is there any way to select specific parent row......
Thanks for reading
Would be nice to see the markup, are there more tables nested?
However,
parentRow = $(this).closest('tr');
should be a better choice.
API says that .parents() method search through all ancestors of the elements.
.parent() travels only a single level up the DOM tree.
If your checkbox is a direct child (not a deep descendant) of 'tr' then you can try
parentRow = $(this).parent('tr');
Your code should work. I suspect that the problem is happening because your function increaseUnreadMessage() is throwing an error, which is causing the rest of the each() loop to be skipped.
But, to answer your specific question: yes, you can select all rows (<td>s) that contain checked checkboxes. Using jquery's :has selector, like this:
var allCheckedRows = $('tr:has(.inboxCheckbox:checked)');
from there, of course, you can just use addClass() to apply your classname to all of them:
allCheckedRows.addClass('gradeA');
of course, you've got other things going on in your each() loop, so you probably can't throw out the each() entirely. As I said above, your code works... but something like this might be cleaner, and easier to understand.
var messageIds = new Array();
var allCheckedRows = $('tr:has(.inboxCheckbox:checked)');
allCheckedRows.addClass('gradeA');
allCheckedRows.find('.inboxCheckbox').each( function() {
var cb = $(this);
increaseUnreadMessage();
messageIds.push( cb.val() );
});
if( messageIds.length === 0 ) {
showInsMessage('<b class="redTxt">Please Select At Least One Message</b>');
}
BTW, I think you can do it more jQuerish style :
var messageIds = [];
$('tr.youTrs').toggleClass('gradeA', function () {
var checkbox = $(this).find('.inboxCheckbox');
if (checkbox.is(':checked')){
messageIds.push(checkbox.val());
return true;
}
else{
showInsMessage('<b class="redTxt">Please Select At Least One Message</b>');
return false;
}
});

Categories

Resources