add class to parent element if conditions are true - javascript

I am trying to apply a class to a child's parent element if the conditions are true but cannot seem to get it to work. In short, I want to check a table for a cell that is the number "0" and hide its parent row.
I have created a basic jsfiddle of what I have done: http://jsfiddle.net/immbudden/YbZPE/3/
And the snippet of jquery that I have put together:
if ($('#the_table>table>td:contains("0")').length === 1) {
$(this).parent("tr").addClass("hidden");
}
I am still learning jQuery and javascript and this is probably something small, but I can't seem to put my finger on it!
Any help would be much obliged, thanks in advance!

$('td', '#the_table > table').each(function() {
if ($(this).text() === '0') {
$(this).parents("tr").addClass("hidden");
}
});
FIDDLE

Use your browser's developer tools! Or Get Firebug.
With that page loaded, try this in the javscript console:
$('#the_table>table>td:contains("0")')
If that gives you
[ ]
then it's not finding any elements. Then you can try breaking it down, for example, see if this works:
$('#the_table>table>td')
And keep taking out and adding bits of that expression until it produces true or false as you require.

you can do it like this,
$('#the_table table td').filter( function (index) {
return $(this).text() == '0';
}).parent("tr").addClass("hidden");
http://jsfiddle.net/YbZPE/5/

First you have to get teh cell, if you want the first use eq(0):
$cell = jQuery('#the_table tr td:eq(0)');
then you have to put the class on the parent row:
$cell.parent("tr").addClass("hidden");
The following code will do it.
jQuery('#the_table tr td:eq(0)').parent("tr").addClass("hidden");

Related

How to bind to 'inview' event on multiple elements

I'm playing around with Velocity.js and jquery.inview, and I want all the titles on my page to slideDownIn when they come into view. This code works fine for the first title:
$('.movies-title').bind('inview', function(event, isInView, visiblePartX, visiblePartY) {
if (isInView) {
// element is now visible in the viewport
if (visiblePartY == 'top') {
// top part of element is visible
} else if (visiblePartY == 'bottom') {
// bottom part of element is visible
} else {
// whole part of element is visible
$(this).velocity("transition.slideDownIn", 500);
}
} else {
// element has gone out of viewport
$(this).velocity("reverse");
}
});
If I copy and paste the above several times and replace .movies-title with the classes of the other titles, it works as I want it to.
However, that seems like a lot of extra code. I tried changing $('.movies-title') to $(.movies-title, .tv-title, .books-title) but then the animation only works for the last element in the list. I also tried adding a new class called .title to all of the titles and changing .movie-title to .title but that didn't work either.
What am I doing wrong? How can I condense the code?
The best solution is to use a single class on each of these elements since they have something so in common. You might just add title as a class type and apply it to that class.
<div class="title movie-title"></div>
I know you mentioned this in your question, but I can't see why this wouldn't work.
Try using delegate instead of bind for multiples. Also make a unified class for all of them (I just used title)
so like this -
$('body').delegate('.title','inview', function(event, isInView, visiblePartX, visiblePartY) {
Edit - sorry linked wrong fiddle initially
see fiddle http://jsfiddle.net/d1g7sLxq/3/

Can someone help me apply the js 'this' keyword to an iterated jq select expression

Here's my latest version of this code. The 1st line iterates through the rows of a table skipping over the 1st row. For each row I test to see if the (class='dim') state of one of 8 tag elements (index j) on that row matches the corresponding !'dim' state of a set of 8 filters that the user can toggle. The idea is to set any rows where the 'active' filter / 'dim' tag states line up, to the 'hide' class, so they can disappear from the table that the user sees. The CSS for disappearing it is: .hide {display:none;}
It's that last 'if' statement that's killing me. I've tried dozens of versions but I always get some form of syntax error, undefined variable, etc. In that line of code here I've removed my latest set of +, ', " characters to better show clearly what I'm trying to do.
I don't just want something that works to replace this code. And I'm not interested in the shortest trickiest way to do it. I'd like to see some simple obvious code that I could easily understand a year from now so I can solve problems like this myself. Thanks in advance.
var thisRow = $('tbody tr:gt(0)').each(function() {
for (var i=0,j=4;i<8;i++,j++) {
if (!$('.butt').eq(i).hasClass('dim')) {
if (thisRow.nth-child(j)).hasClass('dim')) $(this).addClass('hide');
else $(this).removeClass('hide');
}
}
}
Above this line is the question as I first asked it. Below this is the complete function in case anyone else might find this useful. Thanks to Mr. Pavlikov for the lesson!
function filterTbl() { //Hide rows that don't satisfy all active filters
var butts=$('.butt'); //Each filter button has class 'butt'
$('tbody tr:gt(0)').each(function() { //iterate each table row except the 1st
var thisRow = $(this); //the row being examined
var chilluns = thisRow.children(); //all td's in the row being examined
for (var i=0,j=4;i<8;i++,j++) {
if (!butts.eq(i).hasClass('dim')) { //If this filter is active
//and If the corresponding tag is not active (is 'dimmed'), then hide this row
if (chilluns.eq(j).hasClass('dim')) thisRow.addClass('hide');
else thisRow.removeClass('hide'); //else unhide this row
}
}
});
}
First of all you should be getting thisRow variable like this (not like you are currently doing)
$('tbody tr:gt(0)').each(function() {
var thisRow = $(this);
}
And what does nth-child stand for? Use nth-child selector correctly or use siblings at least if you are willing to compare one row with other rows. I didn't quite understand what are you trying to do, but hope this helps.
And some usefull tips. You do not need to find $('.butt') EVERY TIME in the loop, just find it once before your each loop:
var butts = $('.butt');
So now you will be able to replace
$('.butt').eq(i)
with
butts.eq(i)
This is significant speedup.
Also if n-th child you are trying to find is something that is inside thisRow, find children and do .eq() on them.

Text not changing in jQuery

I seem to be doing something wrong in the following code: http://jsfiddle.net/yunowork/qKj6b/1/
When you click next, the text within the span .hiddentext should be displayed in the span .showtext on top and correspond to the right Race (Rn). For example when R3 is highlighted the content of that .hiddentext "Race 3Oregon 14:30" should be displayed within the span .showtext.
This is the line where I make a mistake:
$('.showtext').text($('.hiddentext').first('td:first').text());
What am I doing wrong here?
Let's start simple:
Your problem:
$('.showtext').text($('.hiddentext').first('td:first').text());
you are saing, that, grab all .hiddentext, choose the first that has a td ... witch is not what you have in code, you have, td that contains hiddentext... so, the other way around.
What you want to do is simply get the current NEXT td and grab the hiddentext, so, just change to:
$('.showtext').text($nextCol.find('.hiddentext').text());
Now, can you see that the <br/> is not correctly rendered? That's because you are setting the text property, and you should set the html property.
the final code should be something like:
$('.showtext').html($nextCol.find('.hiddentext').html());
live example: http://jsfiddle.net/qKj6b/8/
Your code:
every time you need to have placeholders to provide some data to a context, please, DO NOT USE HTML TAGS to hold such values and hide them... make the use of the data- attribute, witch is a HTML5 complience, and works very well in any browser even if it does not have not HTML5 support, like IE6.
your table definition (td) that currently is:
<td class="visible" id="r2">
<span class="hiddentext">Race 2<br />Santa Fe 12:00</span>
<strong>R2</strong>
</td>
should be something like:
<td class="visible" id="r2" data-text="Race 2<br />Santa Fe 12:00">
R2
</td>
witch is way easier to read, and from your javascript code, you can easily get this as:
var hiddenText = $nextCol.data("text");
Your code (part 2):
This one is quite simple to know
Every time you are repeating yourself, you're doing it wrong
You have the methods for Next and Prev almost exactly as each other, so, you are repeating everything, for this, you should refactor your code and just use one simple method, this way, any future change only happens in one place, and one place only.
$(".next").click(function(e){
e.preventDefault();
var $nextCol = $('.highlighted').next('td');
MoveCursor($nextCol, 'next');
});
$(".previous").click(function(e){
e.preventDefault();
var $prevCol = $('.highlighted').prev('td');
MoveCursor($prevCol, 'prev');
});
function MoveCursor(col, side) {
var maxCol = 8;
if((side === 'next' && col.length != 0) ||
(side == 'prev' && col.length != 0 && col.index() >= maxCol)) {
$('.highlighted').removeClass("highlighted");
col.addClass("highlighted");
// show current title
$('.showtext').html(col.data('text'));
if (col.hasClass("invisible")) {
col.removeClass("invisible");
col.addClass("visible");
var $toRem;
if(side == 'prev')
$toRem = col.next('td').next('td').next('td').next('td').next('td').next('td');
else
$toRem = $nextCol.prev('td').prev('td').prev('td').prev('td').prev('td').prev('td');
$toRem.removeClass("visible");
$toRem.addClass("invisible");
}
}
}
Live Example: http://jsfiddle.net/qKj6b/22/
It should be
$('.showtext').html($('.highlighted .hiddentext').html());
Similar for the prev link...
or even better, thanks to #balexandre:
$('.showtext').html($nextCol.find('.hiddentext').html());
$('.showtext').html($prevCol.find('.hiddentext').html());
Fiddle
Update to match #balexandre hint: Fiddle 2
Do the following:
var $currCol = $('.highlighted'); //to get the current column
$('.race strong').text($currCol.closest('.highlighted').first('td:first').text());
.hiddentext class selects all the spans and the first() will always return you the first td.
Just make sure you select .hiddentext from the currently highlighted column and you are good to go.
$('.showtext').text($('.highlighted .hiddentext').first('td:first').text());
Try this (Same for both)
$('.showtext').html($currCol.find('span.hiddentext').html());
Working Example.

Using javascript to check if a HTML table cell is empty?

Is these some simple JS code that allows me to check whether a cell is empty.
I am trying to code a function that is called using "onmouseover=func()"; I just cant seem to get the JS code right. Any ideas?
What im ideally trying to work toward is a code that can detemine whether a cell is empty and if so, place a simple value in, like "Cell Empty".
I know it probably sounds simple but i could use a little help.
Thanks for any ideas.
It depends a little on what will be in there initially. In my experience, tables behave strangely if a cell contains only whitespace, and so a common workaround is to put a in there to stop it collapsing. Anyway, here's how you'd check:
function elementIsEmpty(el) {
return (/^(\s| )*$/.test(el.innerHTML);
}
function replaceCell(td) {
if (elementIsEmpty(td)) {
td.innerHTML = 'Cell Empty';
}
}
<td onmouseover="replaceCell(this)"></td>
... though a better way would be to apply the behaviours through Javascript event handlers.
If you're using jQuery, use the html() method on the element. Given this markup:
<td id="my_cell"></td>
This code will do it:
if ($('#my_cell').html() == '') {
$('#my_cell').html('Cell Empty');
}
Withouth jQuery (like in the old good times):
function func(e){
var target = window.event ? window.event.srcElement : e ? e.target : null;
if (target.innerHTML === ''){
target.innerHTML = 'Cell Empty!';
}
}

Toggle effect problem when using for-loop in IE7

I'm a webdesigner that's trying to get the hang of JavaScript and jQuery, and I want to learn how to write shorter, more concise code - to avoid being ridiculed by the developers at work ;)
I have this snippet:
// toggle divs when checkbox is checked
$('.product-optional-checkbox1').click(function () {
$('.product-optional-toggle1').toggle('fast');
});
$('.product-optional-checkbox2').click(function () {
$('.product-optional-toggle2').toggle('fast');
});
$('.product-optional-checkbox3').click(function () {
$('.product-optional-toggle3').toggle('fast');
});
// hide divs
$('.product-optional-toggle1').hide();
$('.product-optional-toggle2').hide();
$('.product-optional-toggle3').hide();
...that I want to reduce using a for-loop, like this:
for( var i = 1; i < 4; ++i ) {
$('.product-optional-checkbox' + i).click(function () {
$(this).parent('div').find('div').toggle('fast');
});
$('.product-optional-toggle' + i).css({ display: 'none'});
};
It works fine in FF, however in IE7 it toggles twice. Anyone know who to solve a problem like this?
It's hard to say without seeing the HTML structure but maybe going to the parent then descendants is finding multiple divs?
In your example, you could replace:
$(this).parent('div').find('div').toggle('fast');
With code more similar to the original examples:
$('.product-optional-toggle' + i).toggle('fast');
However, it would be much better to ditch all the numbers and just use a class of .product-optional-checkbox. This way you can add a click function to all elements of that class in one go and avoid the loop:
$('.product-optional-checkbox').click(function () {
// do stuff using $(this)
});
Given that your click events seem to be tied to checkboxes (based on the class names you have in your example), why not actually provide code to handle click events for those checkboxes? For example:
<div id='my_group_of_checkboxes'>
<input type="checkbox" id="checkbox1">
<input type="checkbox" id="checkbox2">
...
</div>
And your jQuery code is then stripped down to three lines:
$('#my_group_of_checkboxes :checkbox').click(function(){
$(this).parent('div').hide('fast');
});
You also seem to need to hide the <div> elements related to each checkbox:
$('div[class^="product-optional"]').hide();
Although ID selectors would be a better option here and, depending on their position within your page, you may even be able to get away with something like:
$('#my_container_div_id div').hide();
If you can post some of your HTML, that might help provide more accurate answers as well.

Categories

Resources