I have a few input fields that I'm trying to add a class to their parent container if they are not empty.
Here's the CoffeeScript:
$(".inputA, .inputB").parent().addClass(->
if !$(this).is(":empty")
"input-set"
)
This is successfully appending "input-set" to the parent class, but in all cases, not just empty input fields.
:(
Use jQuery.filter()
$(".inputA, .inputB").filter(function(){
return this.value !='';
}).parent().addClass("input-set");
Less function calls than using $.each
:empty will select elements that don't have children. Therefore, using it to conditionally select the parents of certain elements doesn't make any sense.
ref: https://developer.mozilla.org/en-US/docs/Web/CSS/:empty
If you're looking to add the class to the parents of inputs that haven't been populated then you could use something like:
$(".inputA, .inputB").each(function(){
if (this.value !== "") {
$(this).parent().addClass('input-set');
}
});
First, input elements are by definition empty..
Read the :empty documentation at http://api.jquery.com/empty-selector/
Second you are testing the parent elements and not the input ones.. (and since they are parents, meaning they are not empty they all fit the bill..)
Related
I'm trying to select element by data attribute defined with jquery (it's not visible in DOM), therefore I cannot use $('.foo:data(id)')
example: if user clicks element I add data property to it as following
$(this).data('id', '1');
now I would like to find element which has
data-id == 1
how can I select this element by data-id?
Use filter()
$('.foo').filter(function(){
return $(this).data('id') === `1`
}).doSomething()
You could use the attribute selector [attribute=...].
In your case, this would be
$('[data-id=1]')
But keep in mind, if you change the data of an element with .data(), the change isn't reflected in the dom attribute, so you can't use this (or additionally change the dom attribute).
The other way would be to select every candidate and then filter for each element, which has a matching data value.
$('.foo').filter(function(){
return $(this).data('id') == 1;
});
I have a simple structure like:
HTML
<ul id="costsDropdown">
<li data-position="bla bla"></li>
</ul>
and I want to change each "data-position" attribute of my list Elements.
My first Jquery Shot was this here:
$("#costsDropdown ul").each(function() {
$("li").attr("data-position", "TEST-VALUE123");
});
but it doesnt work, I think my selector are wrong...
could anyone give me a hint please?
Thanks for any help!
Greetz
Your selectors are a bit off
$("#costsDropdown ul").each
That is trying to select the child ul of the container #costsDropdown (which is the ID of the ul) - what you want is:
$("#costsDropdown li").each(function() {
$(this).attr("data-position", "TEST-VALUE123");
});
ID's are unique - no need to double up the selector with an ID and the type of element it is.
Note that I used $(this), not $("li"), inside the each callback. $("li") selects all li elements, anywhere on the page; we just want a jQuery wrapper for the one specific one we're handling inside the each.
In fact, the each is completely unnecessary because of the set-based nature of jQuery; if you use the .attr setter, it sets the attribute on all elements in the set:
$("#costsDropdown li").attr("data-position", "TEST-VALUE123");
That will set the value on all of the li elements inside #costsDropdown.
If you need to set separate individual values on the individual li elements, you still don't need each (though it's fine if you want to use it); you can use the version of attr that accepts a callback that it uses to find out what value to set:
$("#costsDropdown li").attr("data-position", function(index) {
return "Test value " + index;
});
That will set "Test value 0" on the first li, "Test value 1" on the second, etc. And like the each example above, if you need to, you can use this within the callback to refer to the li for that call (possibly using $(this) to wrap it if you need a jQuery wrapper).
$("#costsDropdown ul") matches no elements, it has to be $("#costsDropdown") (#costsDropdown is the ul).
And even that is unnecessary. Go
$("li[data-position]").attr("data-position", "TEST-VALUE123");
instead.
I'm using the jQuery .append() function to input content into HTML elements via their id like so;
function returnGameDetailed(data) {
$('#game-synopsis').append(data.results.deck);
}
For some of the data.results I need to append them to multiple elements, is there a correct method to do this?
In the documentation I can only see a method for multiple inputs to the same element, not reversed.
Here's what i've attempted;
$('#game-title').$('#purchase-amazon').append(data.results.name);
and
$('#game-title', '#purchase-amazon').append(data.results.name);
You were almost right. The correct way is here:
$('#game-title, #purchase-amazon').append(data.results.name);
However, I'd recommend you to use classes instead:
$('.elements-to-insert').append(data.results.name);
<div class="elements-to-insert" id="game-title"></div>
<div class="elements-to-insert" id="purchase-amazon"></div>
Give both elements a class and then append to that class
$('.className').append(data.results.name);
The elements having the className will get appended with the html
This is interesting.
HTML:
<label name="foo"></label>
<span name="foo"></span>
Javascript:
var foo = $('[name="foo"]');
if (foo.is("span")) {
foo.html('haha');
}
Both the label and span will have the same HTML text. However, if you delete the <span>, than the label will not have its HTML altered. Any reason why, and any way to properly differentiate between them? This is also true if you change if(foo.is("span")) to if(foo.is("label"))
When you use
var foo = $('[name="foo"]');
a collection of elements matching the selector will be returned. To select individual element form it, iterate over it. Using is on a jQuery object will return true if any element in matched set satisfies the condition.
.is()
Check the current matched set of elements against a selector, element, or jQuery object and return true if at least one of these elements matches the given arguments.
Use .each():
$('[name="foo"]').each(function() {
if ($(this).is("span")) {
$(this).html('haha');
}
});
The above code is just for the Demo purpose, the following code is equivalent of the above.
$('span[name="foo"]').html('haha');
Agree with Tushar, just use
$('span[name="foo"]')
instead of
$('[name="foo"]')
How would I go about adding multiple child elements to a parent?
This is what I would like to achieve :
<div id = "myDiv">
<div id = "child1"></div>
<div id = "child2"></div>
</div>
This would, however, make child2 a child of child1:
$("#myDiv").append("div").attr("id", "child1").append("div").attr("id","child2")
Is there any way of adding two children with different attributes using dot notation?
EDIT: How about also appending a child to child1?
$("#myDiv").append("<div id='child1'>").append("<div id='child2'>")
And another
$('#myDiv').append($('<div>', { id: 'child1' })).append($('<div>', { id: 'child2' }))
$("#myDiv").append("div").attr("id", "child1").append("div").attr("id","child2");
Appends "div" text to myDiv, then changes the id attribute of the div formerly known as "myDiv" to "child1" then appends more text and changes the id again.
Change form of your statements:
$("<div>").attr("id", "child3").add($("<div>").attr("id", "child4")).appendTo("#myDiv");
With this, jQuery creates a properly formed div, assigns and id attribute to it, then adds another div with and id. Note that the second addition with .add() is properly formed due to the $ inside there and the id attribute added before it gets added to the first one, then they both get appended.
NOTE: you can also use the pattern above or do simple string for the child of child1 as:
$("<div id='child1A'/><div id='child1B'/>").appendTo("#child1");
Worth noting this only hits the DOM once which is desired and you can build up the string to append more as well - still only hitting the DOM once with that append.
You could clone() #myDiv to a variable, loop up to the number of child elements needed, change the attribute and then appendTo #myDiv. I know right, kinda complex.
Perhaps you're better off using append two times. (In two separate lines, no chaining)
Oh wait, you could use add (Here's a fiddle : http://jsfiddle.net/w4qnk/)
$elemts = $()
$elemts = $elemts.add($('<div/>', { 'id': 'child1'}))
$elemts = $elemts.add($('<div/>', { 'id': 'child2'}))
$("#myDiv").append($elemts)