I have following Code/Structure, what I am trying to do is to hide a div if a custom attribute matches. The problem at the moment is that I can't get the custom attribute as demonstrated in this code:
var elementToHide = 'file_type';
jQuery('#search-img-ctrl').each(function() {
var locationli = jQuery(this).find('li').attr(elementToHide);
alert(locationli);
alert(elementToHide); // I can't get the custom attribute
if (locationli != elementToHide) {
jQuery(this).find('.search-img-box').hide();
} else {
jQuery(this).find('.search-img-box').show();
}
});
And following is my HTML Structure.
<div id="search-img-ctrl" class="search-img-ctrl">
<div class="sampages" style="display: block;">
<div class="search-img-box sampageitems">
<a href="image_detail.php">
<img id="imageimage_array" width="277" height="206" src="upload/2014-05-02-14-05-512014-04-08-14-04-40000560_d.png" alt="">
</a>
<br>
<ul>
<li> Name </li>
<li>upload/2014-05-02-14-05-512014-04-08-14-04-40000560_d.png</li>
<li>identity </li>
<li>Modify</li>
<li latitude="null">Latitude</li>
<li>null</li>
<li longitude="null">Longitude</li>
<li>null</li>
<li model="null">model</li>
<li>null</li>
<li file_type="png">model</li>
<li>png</li>
<li> Image Size </li>
<li>11Kb</li>
</ul>
</div>
</div>
Ideally under html5 you should suffix your custom attributes with data- prefix. However, in your code to find the li that has specific attribute, use:
var locationli = jQuery(this).find('li[' + elementToHide + ']');
Here is a JSFiddle demonstrating this: http://jsfiddle.net/wANxV/
The main wrapper have id and class same value. This is not a good.
Put a numer or other after your id value (id="search-img-ctrl-1" etc) , then do each cycle on class not on id
JQuery.each('.search-img-ctrl');
Put attributes in your markup with 'data' prefix (as Satpal said) and other thig you can use directly the selector
var locationli = jQuery(this).find("li["+elementToHide+"]");
This code reads the attribute of the first found element, but it does not filter on it:
var locationli = jQuery(this).find('li').attr(elementToHide);
A filter might look something like this:
var locationli = jQuery(this).find('li')
.filter(function(){
return $(this).attr(elementToHide);
});
But obviously closure's method is much shorter. And keypaul is right, using data- prefix is the right way to store your own metadata on elements.
the answers to use li[' + elementToHide + '] are good ones, but to help you understand what you are experiencing
let's break down this line of code:
var locationli = jQuery(this).find('li').attr(elementToHide);
as you know, jQuery(this).find('li') returns all of the decendants of this which are li's, and in your example, there are 14 of these.
What does .attr() return when applied to a set of 14 elements?
I guess it could return an array, a concatenation, who knows?, but the writers of jQuery decided to just return the attribute corresponding to the first element in the set. In this case, you are calling .attr(elementToHide) on <li>Name</li>. This element does not have the "file_type" attribute, therefore, you get an empty string in return.
Here's a quick fiddle to illustrate: http://jsfiddle.net/pmn4/B9bqK/
to solve your problem, use either the techniques described by #keypaul and #closure or use jQuery's filter method
Related
This code returns all elements li in html code.
For example:
<li data="2" class="produkt_w_koszyku"><b>Audi A6</b> <span class="cena_w_koszyku">199000 zł</span><span style="float: right; margin-right: 30px;" class="deleteitembasket"><i class="fas fa-times"></i></span></li><li data="3" class="produkt_w_koszyku"><b>BMW i8</b> <span class="cena_w_koszyku">122 zł</span><span style="float: right; margin-right: 30px;" class="deleteitembasket"><i class="fas fa-times"></i></span></li>
I would like him to return the value of the datas attribute to me. so: 2, 3. How can I change this?
var $ul = $(this).parents('ul');
localStorage.setItem('item_id', $ul.html());
You are wanting to loop through the li elements and pull the value of an data attribute out. The comments above provide what you need, but to summarize:
// you may need a more specific selector, but this works for your html snippet
const dataAttrs = $("li").map(function(){
return $(this).attr('data');
}).get().join(',');
// display your data
console.log(dataAttrs);
Also, it best to follow the standard wisdom on data-* attributes, and rather than using simply data doing something such as data-id, data-data, or whatever. See https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes.
$("li.produkt_w_koszyku").map(function(){ return this.getAttribute('data'); }).get().join(',')
Select all the elements, map the parts that you want into an array and join them on comma. You can use getAttribute() to get the attribute off of the DOM Element.
You need to prepend your data holding items with data- so like data-data, data-class, data-... as below
<article
id="electriccars"
data-columns="3"
data-index-number="12314"
data-parent="cars">
...
</article>
Reading the values of these attributes out in JavaScript is also very simple. You could use getAttribute() with their full HTML name to read them, but the standard defines a simpler way: a DOMStringMap you can read out via a dataset property.
To get a data attribute through the dataset object, get the property by the part of the attribute name after data- (note that dashes are converted to camelCase).
var article = document.getElementById('electriccars');
article.dataset.columns // "3"
article.dataset.indexNumber // "12314"
article.dataset.parent // "cars"
I know questions with similar titles have been asked before and I seen the answers.
I have a ul element in HTMl:
<ul class="collection with-header"></ul>
In this element li elements are added dynamically through JavaScript:
$('.collection').append('<li class="collection-item">'+'Hello'+'</li>');
Now,for each li element,I want to add a number to it's class attribute to identify every li element uniquely so that I can assign different id attributes to them.For that I wrote:
var j = 1;
$('.collection').append('<li class="collection-item"'+j+'>'+ 'Hello'+'</li>');
$('.collection-item'+j).attr("id",list[i].username);
j++;
When I try to fetch id of li elements by hover event:
$('.collection-item').hover(
function(){
var idd = $(this).attr('id');
console.log(idd);
}
);
Undefined is printed in the console.
What is wrong in this implementation?
EDIT:
The value of list[i].username is working fine,it's value is coming from another file and it's not causing any trouble.
As far as I can see, your placement of i within that string results in i being outside the html className attribute, infact not inside any html attribute at all. Your code:
$('.collection').append('<li class="collection-item"'+j+'>'+ 'Hello'+'</li>');
would result in this final markup:
<li class = "collection-item"0>Hello</li>
<li class = "collection-item"1>Hello</li>
The zero has no HTML signficance and is out of place.
#sphinx's comment is the correct answer, but it is "not being fired" because his code results in each list item having a unique class name with its number at the end like so:
<li class = ".collection-item0">Hello</li>
<li class = ".collection-item1">Hello</li>
when you add the on hover action, you select these elements by the class ".collection-item", not a unique class.
Your solution would look like this:
$('.collection').append('<li class="collection-item '+j+'">'+ 'Hello'+'</li>');
$('.collection-item.'+j).attr("id",list[i].username);
and with this, in your final markup, each list item will have two classes - a shared "collection-item" class, and a numerical value like so:
<li class="collection-item 0"></li>
<li class="collection-item 1"></li>
now you can select each list item (in this example list item 4) by two classes with the selector $(".collection-item.4") as well as apply an action to all collection items with the selector $(".collection-item").
I find this code somewhat ugly looking and I'm not sure if I would be happy with it myself in terms of structure if it were mine, but here is a jsfiddle as a proof of concept :
https://jsfiddle.net/0wqeouxo/ (click on each list item and it will alert its id)
I think you could get more mileage out of jquery's functionality in that loop rather than defining classes inline.
Use this instead
var j = 1;
$('.collection').append('<li class="collection-item'+j+'">'+ 'Hello'+'</li>');
$('.collection-item'+j).attr("id",list[i].username);
j++;
There is a syntax error in your code, please use the above code.
For hover to work, do this
$('.collection-item'+j).hover(
function(){
var idd = $(this).attr('id');
console.log(idd);
}
);
As jQuery operates asynchronously, when you try to set the id, the element is might not be in the dom yet. You could set the id before appending the element, for example:
$('<li class="collection-item '+j+'">'+ 'Hello'+'</li>')
.attr("id",list[i].username)
.appendTo('.collection');
It a dynamically append element .so you could use on().and change the selector like this .[class^="collection-item"] It will match same class name element contain with some other name in the class
$(document).on('hover' ,'li[class^="collection-item"]',function(){
var idd = $(this).attr('id');
console.log(idd);
});
So I currently have a list like so on my page
<li class="head">
<b>Introduction</b>
<ul>
<li class="sub">somethingsomething</li>
</ul>
</li>
This list is being used with sortable, so the user can decide on the order, and I am passing this information to a grails controller for use in application logic. So, I am trying to read it in, and place the text contained in the "head" and "sub" classes in 2 different arrays. However, when I use a jquery selector to obtain the head elements, and obtain the text attribute of the element, it contains the inside list as well.
$('#divname').find("ul > li.head").each(function()
{
var current = $(this);
console.log(current.text());
});
results in Introductionsomethingsomething
Is there any way to only obtain the 'Introduction' text from the list, and ignore the text in the nested <ul> and <li.sub>? Due to it being nested, I am unable to figure out how to use jQuery's :not() selector
You can find the b tag using jquery tagname selector.Like this:
var current = $(this).find('b');
console.log(current.text());
Working Demo
May be this is solution:
<script>
$('#divname').find("ul > li.head").each(function()
{
var current = $(this).find("b");
console.log(current.text());
});
</script>
I have a page with many dynamically creted div's as seen below:
<div class="open"></div>
<div class="open"></div>
<div class="open"></div>
<div class="open"></div>
I'm looking for a way to get get a position of an element (eg. If the element is the first instance of, assign id="1" if element is the second instance of, assign id="2".
I'm currently using the following jquery, but am stuck, as Im not sure where to go from here.
$(document).ready(function () {
var numDialogs = $('.open').length;
});
Any suggestions?
Just use:
$('div.open').prop('id', function(i){
return 'openElement' + (i + 1);
});
JS Fiddle demo.
I've deliberately added a prefix string because while numerical ids are valid under HTML5, they remain invalid under HTML4, and are difficult to select using CSS selectors.
References:
prop().
Mark, you can target the element and then add an attribute like so:
$('.open').attr('id', numDialogs);
This will give it all 4's in this case, but I'll leave you to wrestle with the actual logic to implement the right numbers. Good luck.
How do I turn this:
<a class="link">
<p class="paragraph">This is some text</p>
<p class="paragraph">This is some more text</p>
<p class="paragraph">And some more</p>
</a>
into this:
<a class="link">
This is some text This is some more text And some more
</a>
with jQuery. I tried using append and merge but I just can't figure it out.
Since the text method returns the text content of an element and it's descendants, you can just use that:
var link = $("a.link");
link.text(link.text());
From the docs:
Get the combined text contents of each element in the set of matched
elements, including their descendants.
Here's a working example.
Update (see comments)
In the case that this needs to apply to multiple .link elements, you can use each:
$("a.link").each(function() {
$(this).text($(this).text());
});
This will work:
$("a.link").text(function(i,text){
return text;
});
And yet another way (not tested):
// you can optionally filter to
// only p elements too with
// .children("p")
$("a.link").children().contents().unwrap();
Here's another variation of the second:
$("a.link p").contents().unwrap();
Edit: Just a note for clarity:
All of these solutions work on multiple elements. The first solution is a relatively uncommon syntax that can be used on most jQuery setter functions. It runs the callback on each matched element and sets the value of the property/attribute to the value returned from the callback.
try this
$(document).ready(function(){
var concatText = "";
$("p.paragraph").each(function(){
concatText = concatText + " " + $(this).text()
});
$("a.link").html(concatText);
});