jQuery: Target all elements with val less than 1 - javascript

I have multiple elements in the dom with a class of .blockbadge if the value of any .block-badge is 0 then I want to add a class to that element in order to style it differently.
My JS adds the class to all of these elements if anyone of them equal 0. How do I make it only affect those elements which equal zero?
HTML
<span class="block-badge">1</span>
<span class="block-badge">0</span> // this element should have the class 'zero' added
<span class="block-badge">4</span>
JS
var blockBadgeVal = $('.block-badge').val();
if (blockBadgeVal < 0) {
$('.block-badge').addClass('zero');
}

The code in the OP will not work because $('.block-badge').html() will return the html of the first element with class block-badge so in this case return string 1, you should parse the returned value then compare it with the 0.
You could use filter() method instead.
Description: Reduce the set of matched elements to those that match the selector or pass the function's test.
$('.block-badge').filter(function(){
return parseInt($(this).text())==0;
}).addClass('zero');
Hope this helps.
$('.block-badge').filter(function(){
return parseInt($(this).text())==0;
}).addClass('zero');
.zero{
color: red;
font-weight: bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="block-badge">1</span>
<span class="block-badge">0</span>
<span class="block-badge">4</span>

Like this
$('.block-badge').each(function(){
if(parseInt($(this).html()) ===0){
$(this).addClass('zero');
}
});

You could use the jQuery :contains selector for that specific markup
$('.block-badge:contains(0)').addClass('zero');
it won't work if any other elements contains a zero, like 10, 101 etc. so if you need only 0, use a filter
FIDDLE

Try using .text(function(index, originalText) {}) where this is current element within collection , originalHtml is current textContent
$(document).ready(function() {
$(".block-badge").text(function(index, originalText) {
if (originalText <= 0) {
$(this).addClass("zero");
}
return originalText
});
});
jsfiddle https://jsfiddle.net/s2g3zpwr/3/

Related

Wildcards in jQuery attribute's name selector?

How can I select all elements which contain data attributes starting with "data-my-" in the following code? I'm not going to add wildcards to attribute value, It's attribute's name.
<p data-my-data="aa">foo</p>
<p data-my-info="bb">bar</p>
What I tried and failed:
$("[data-my-*]").addClass("myClass");
You can't write a selector with a wildcard for attribute names. There isn't a syntax for that in the standard, and neither in jQuery.
There isn't a very efficient way to get just the elements you want without looping through every element in the DOM. It's best that you have some other way of narrowing down your selection to elements that are most likely to have these namespaced data attributes, and examine just these elements, to reduce overhead. For example, if we assume only p elements have these attributes (of course, you may need to change this to suit your page):
$("p").each(function() {
const data = $(this).data();
for (const i in data) {
if (i.indexOf("my") === 0) {
$(this).addClass("myClass");
break;
}
}
});
.myClass {
color: #f00;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p data-my-data="aa">foo</p>
<p data-my-info="bb">bar</p>
<p>baz</p>
there is no wildcarding for attribute names.so u can get result like below
$( "p" ).each(function( i ) {
element=this;
$.each(this.attributes, function() {
if(this.name.indexOf('data-my-') != -1) $(element).addClass("myClass");
});
});
Just a slightly shorter, but otherwise very similar version to #BoltClock's.
Note: using ES6 syntax.
$('p')
.filter((_, el) => Object.keys($(el).data()).find(dataKey => dataKey.indexOf('my') === 0))
.addClass('myClass');
.myClass { color: red; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p data-my-data="aa">foo</p>
<p data-my-info="bb">bar</p>
<p>baz</p>

Check if any childnodes exist using jquery / javascript

I have a DOM structure with div, p and span tags. I want to count the 'p' tags with children nodes and that without any children. I read a solution in this forum, but it doesn't work for me: How to check if element has any children in Javascript?.
Fiddle demo
$('#test').blur(function(){
var test= $('.check p').filter(function (){
if ($(this).childNodes.length > 0)
return this
});
alert(test.lenght)
})
it should be
$('#test').blur(function(){
var test= $('.check p').filter(function (){
return this.childNodes.length > 0; // as HMR pointed out in the comments if you are looking for child elements then $(this).children().length will do
})
alert(test.length)
})
Demo: Fiddle
Did you try this?
$('p:empty')
Should select all your empty p tags.
$('p').not(':empty')
Should select all your non empty p tags.
Here: http://jsfiddle.net/QN3aM/9/
$('#test').blur(function () {
var test = $('.check p').filter(function () {
return ($(this).children().length)
});
alert(test.length);
})
You just need to return true within filter, 0 is a falsey value and anything else will be truthy. also you spelt length wrong.
childNodes is a property of an element. as you were converting the element into a jquery object, you'd have to use the jquery method children()

jQuery: how can I move character before letters

I have a html code that cannot be altered directly.
<span class="class1 class2 class3 "> First name*: </span>
I need to move the * at the begining or the text. The end result should be this:
<span class="class1 class2 class3 "> *First name: </span>
I also need to make the * to be red (I need to add a class only for this character).
Any ideas?
I'd suggest:
$('span.class1.class2.class3').text(function(i, t){
/* i is in the index of the current element among those returned,
t is the text of the current element.
We return the new text, which is an asterisk, followed by the original text,
with the asterisk removed (using replace to replace the asterisk with an empty string):
*/
return '*' + t.replace(/\*/,'');
});
JS Fiddle demo.
If, however, you need a more generic approach (for example if you have multiple elements with the same/similar selectors):
// selects all the span elements, and filters:
$('span').filter(function(){
// discards the elements that *don't* have '*:' in their text:
return $(this).text().indexOf('*:') > -1;
// iterates over those elements (as above):
}).text(function(i, t) {
return '*' + t.replace(/\*/,'');
});
JS Fiddle demo.
In order to 'make it red,' you'd have to manipulate the HTML, rather than just the text, of the element:
$('span').filter(function(){
return $(this).text().indexOf('*:') > -1;
// Using 'html()' to set the HTML of the 'span' element:
}).html(function(i, h) {
// creating a span and prepending to the current element
return '<span class="required">*</span>' + h.replace(/\*/,'');
});
Coupled with the CSS:
.required {
color: red;
}
JS Fiddle demo.
Further, for simplicity, given that you want to target the * with a class-name (and therefore wrap it in an element-node), you could avoid the string-manipulation and simply float:
$('span').html(function(i,h){
// simply wrapping the `*` in a span (using html() again):
return h.replace(/(\*)/,'<span class="required">*</span>');
});
With the CSS:
.required {
float: left;
color: red;
}
JS Fiddle demo.
References:
filter().
html().
text().
If the problem is the very specific scenario you gave,
$(".class1.class2.class3").each(function() {
var inner = $(this).html();
$(this).html("*" + inner.replace("*",""));
}
var span = $('span.class1.class2.class3');
var new_text = span.text().replace(/\*/, '').replace(/^(\s*)/, '\1<span style="color:red;">*</span>');
span.html(new_text);
Demo

Why does jQuery, outputs same rel each time?

so basically here is my script:
http://jsfiddle.net/JJFap/42/
Code -
jQuery(document).ready(function() {
var rel = new Array();
var count = 0;
jQuery(".setting").each(function() {
rel[count] = [];
if(jQuery("span").attr("rel")) {
rel[count].push(jQuery("span").attr("rel"));
}
console.log(count);
count++;
});
jQuery("body").text(rel);
console.log(rel);
});​
and
<div class="setting">
<span rel="Variable">Variable</span>
<span rel="Item">Item</span>
<span rel="Something">Something</span>
</div>
<div>
<span rel="Smth">Smth</span>
<span>Sec</span>
</div>
<div class="setting">
<span>Second</span>
<span rel="first">First</span>
<span rel="Third">Third</span>
</div>
​my question, is why does it display Variable, variable?
I would like it to display Variable, First, but I'm not able to do.
Basically what I would like to achieve is create new array, in which insert each div.setting span elements with rel attribute array.
So basically in this example it should output -
Array (
Array[0] => "Variable","Item","Something";
Array[1] => "first","Third";
)
Hope you understood what I meant :)
EDIT:
In my other example I tried to add jQuery("span").each(function() ... inside first each function, but it outputted two full arrays of all span elements with rel. I can't have different classes / ids for each div element, since all will have same class.
jQuery('span') is going to find ALL spans in your page, and then pull out the rel attribute of the first one. Since you don't provide a context for that span search, you'll always get the same #1 span in the document.
You should be using this:
jQuery('span',this).each(function() {
rel[count] = [];
if (jQuery(this).attr("rel")) {
rel[count].push(jQuery(this).attr("rel"));
}
console.log(count);
count++;
})
instead of this:
rel[count] = [];
if(jQuery("span").attr("rel")) {
rel[count].push(jQuery("span").attr("rel"));
}
console.log(count);
count++;
http://jsfiddle.net/mblase75/JJFap/52/
The trick is to use a second .each to loop over all the span tags inside each <div class="setting"> -- your original code was using jQuery("span"), which would just grab the first span tag in the document every time.
In addition to what has been said, you can also get rid of the count and one push() when using jQuery.fn.map() as well as getting rid of the if when adding [rel] to the selector:
jQuery(document).ready(function() {
var rel = [];
jQuery(".setting").each(function() {
rel.push(jQuery(this).find('span[rel]').map(function() {
return this.getAttribute('rel');
}).get());
});
jQuery("body").text(rel);
console.log(rel);
});
Within the .each() method, you have this code a couple times: jQuery("span").attr("rel"). That code simply looks for ALL span tags on the page. When you stick it inside the .push() method, it's just going to push the value for the rel attribute of the first jQuery object in the collection. Instead, you want to do something like $(this).find('span'). This will cause it to look for any span tags that are descendants of the current .setting element that the .each() method is iterating over.

Recursion of .children() to search for id attribute

I'm new to jQuery, familiar with PHP & CSS. I have nested, dynamically generated div's which I wish to send (the id's) to a server-side script to update numbers for. I want to check everything in the .content class. Only div's with id's should be sent for processing; however I'm having trouble making a recursive children() check...this is the best (non-recursively) I could do:
$(".content").children().each(function() {
if ($(this).attr('id').length == 0) {
$(this).children().each(function() {
if ($(this).attr('id').length == 0) {
$(this).children().each(function() {
if ($(this).attr('id').length == 0) {
$(this).children().each(function() {
alert($(this).attr('id'));
});
}
});
}
});
}
});
and it just alert()'s the id's of everything at the level where they should be. There must be a better way to do this...thank you in advance for any advice.
-Justin
Try:
var ids = $('.content div[id]').map(function() {
return this.id;
}).get();
.content div[id] will select you all div descendants (at any level) of .content with non-empty ID attributes. The [id] part is an example of the Has Attribute selector.
I have used .map. to extract the IDs of the matches, and .get() to convert the resulting object into a basic array.
Try it here: http://jsfiddle.net/M96yK/
You can do:
$(".content div[id]");
This will return a jQuery object that contains all div's which have id's specified

Categories