I have a group of images, each of the image have data-type="type,type", so in order to make my life easier I intend to grab the data-type, and make them into an array (wrapped each of them in span) and append them to an "category" element.
$('li.grid-item').each(function () {
// grab a reference to the current li
var $el = $(this);
// get the url from its data-class attribute
var arr = $el.find('img').data('type').split(',');
$.each(arr, function (index, value) {
$el.find('.category').append('<span>' + value + '</span>');
$el.addClass(value);
});
});
<li class="grid-item">
<figure>
<img src="img/sticker/still/sticker_30.png" alt="sticker" title="You know I'm good" data-type="others/" data-price="9 bahts" data-alt="img/sticker/ani/sticker_30.gif" />
</figure>
<a href="#">
<span class="download ala_carte">CONTINUE</span>
</a>
<div class="category"></div>
</li>
It work fine but duplicated 20 of each value, please help. How to remove those duplicated array value? Please help, thanks in advance.
I think it's better to collect all existing types first in on array (and only add new values to it, if there weren't already existing). Afterwards, you could add span elements for each type. And you should only have one "category" container to list all types.
Update
Your function is executed to often (more than 20 times), because you are calling it everytime your $grid.imagesLoaded() makes progress. Call it when you are "done".
Try replacing
$grid.imagesLoaded().progress()
with
$grid.imagesLoaded().done()
to call your function only once after all images are loaded. Additionally you could empty the category container before re-filling it.
Related
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);
});
I have an element with an array id id="x[]" that vary depending on the number of elements that I have on a database. It's basically a x button to delete a certain table row in the database.
<div align="center" id="x[]" class="x">
<img src="x 2.png" alt=""></div>
Problem is, I don't know how to pass this id into the jQuery selector. I want to change the form action to delete the row and create an hidden input to get the paramater I need from another field with an array id id="codsinmov[]" with the same index as x[]. What I have so far is:
$(document).ready(function(){
for(var i=0; i<x.length; i++) {
$('#x[i]').click(function(){
var $hiddenInput = $('<input/>',{type:'hidden',id:codsinmovesse, name:codsinmovesse});
$hiddenInput.val($('#codsinmov[i]').val());
$hiddenInput.appendTo('#tabelaeditavel');
$('#form').get(0).setAttribute('action', 'deletemoviment.php');
$('#form').submit();
});
}
});
But it doesn't work.. So, any ideas? Sorry, I'm a beginner at jQuery. Thank you very much!
you can use
$("div[id^='x['").click(function(){
// write code here })
So this will execute on click of those ids of div which start from x.
So as per my understanding You need not to use for loop here rather use 'this' keyword and do what you want.
I hope it will help you.
If you want to add an eventListener to ALL elements you can simply do it like that
var $myButtons = $('.buttons');
That way the whole list of Elements are stored behind the variable $myButtons.
Now you can proceed as following:
$myButtons.on("click", function(event){
console.log(this); // this will print out the clicked element
});
This way every element with the class .buttons is clickable and accessable.
If you want to dynamically select a single element with jquery depending on some value you have to exclude your [i] from the string
for example like that $('element:nth-child('+[i]+')');
I'm new to jQuery and am trying to create jQuery UI buttons dynamically and them to a list. I can create one list item but no more are appended after it. What am I doing wrong?
$('#buttonList').append('<li><button>'+ username + '</button>')
.button()
.data('type', userType)
.click(function(e) { alert($(this).data('type')); })
.append('<button>Edit</button></li>');
<div>
<ul id="buttonList">
</ul>
</div>
This only creates one list item with two buttons (although the second button seems to be encased in the first one, but I can probably figure that issue out). How do I get it to create multiple list items with their own unique 'data' values (i.e. I can't do a find() on a particular button class and give it data values as all buttons would then have the same data)?
I suggest to exchange the position of what you are appending and where you are appending to. This way, you retain the appended object, and should be able to work with it as a standard jQuery selector. From your code i commented out the .button() and the .append() lines, because i'm not sure what you want to do with them. Should you need help adding those lines, just drop a comment to my answer ;)
Oh, i almost forgot: i use var i to simulate different contents for username and userType data.
A JSFiddle for you is here: http://jsfiddle.net/cRjh9/1/
Example code (html part):
<div>
<p id="addButton">add button</p>
<ul id="buttonList">
</ul>
</div>
Example code (js part):
var i = 0;
$('#addButton').on('click', function()
{
$('<li><button class="itemButton">'+ 'username' + i + '</button></li>').appendTo('#buttonList')
//.button()
.find('.itemButton')
.data('type', 'userType'+i)
.click(function(e) { alert($(this).data('type'));
})
//.append('<button>Edit</button></li>')
;
i++;
});
You need complete tags when you wrap any html in a method argument. You can't treat the DOM like a text editor and append a start tag, append some more tags and then append the end tag.
Anything insterted into the DOM has to be complete and valid html.
You are also not understanding the context of what is returned from append(). It is not the element(s) within the arguments it is the element collection you are appending to. You are calling button() on the whole <UL>.
I suggest you get a better understanding of jQuery before trying to chain so many methods together
Just a very simplistic approach that you can modify - FIDDLE.
I haven't added the data attributes, nor the click function (I'm not really sure I like the
inline "click" functions - I generally do them in jQuery and try to figure out how to make
the code efficient. Probably not very rational, but I'm often so).
JS
var names = ['Washington', 'Adams', 'Jefferson', 'Lincoln', 'Roosevelt'];
for( r=0; r < names.length; r++ )
{
$('#buttonList').append('<li><button>'+ names[r] + '</button></li>');
}
$('#buttonList').append('<li><button>Edit</button></li>');
Could you please lend a hand as I am having some trouble getting the text of a heading and the source of an image element in order to create a list of the item clicked. But I will explain better with some code:
Firstly I have a div element that goes like this:
<div class="main_page_entry">
<div class="main_item_desc">
<img class="main_item_pic" src="blah.jpg" />
<h6>Item Title</h6>
<span class="icon"> <img src="icon.png" /></span><br />
<span class="address">Some address</span>
<p class="item_desc">More blahs and links for description </p>
</div>
<div class="item_controls">
...
<a href="#" class="add_to_list">
<img src="add_icon.gif" />Add to List
</a>
...
</div>
</div>
It consists with a big div containing two smaller. What I want to do is the following: When I click on 'Add to List' link, I would like to get just the text inside and the main_item_pic source in order to create a list item with those two.
So here is my written code so far:
$('a.add_to_list').live('click', function() {
var name = $(this).closest('h6').text();
var source = $(this).closest('.main_item_pic').src;
$('<li class="hide list_entry"><span class="entry_title">'+
name+'</span><button class="remove_entry"></button>'+
'<img class="list_entry" src="'+source+'" /></li>')
.appendTo('#favs_list ul')
.show('slow');
});
Obviously this doesn't work! I've tried different solutions that I read around here like:
var name = $(this).closest('h6').html();
var source = $(this).closest('.main_item_pic').attr('src');
but oh well...no luck so far. Any ideas? Thanks in advance!
Try going back to the top and coming down again along the right DOM branch:
var src = $(this).closest('.main_page_entry') // Back to the top
.find('.main_item_desc .main_item_pic') // And down again.
.attr('src');
The closest method goes up the DOM tree through your ancestors:
Get the first ancestor element that matches the selector, beginning at the current element and progressing up through the DOM tree.
So it won't cross over to any of the sibling branches. Then, once you're at the appropriate ancestor, you use find to come back down, find is just like $() but uses the specified element rather than document as the root:
Get the descendants of each element in the current set of matched elements, filtered by a selector, jQuery object, or element.
The closest method only finds the closest ancestor that matches the selector you pass it. Because the h6 and img you are looking for are not ancestors of the element you are calling it on, it won't find them. What you need is to find the closest element that contains both the element you are searching from and the elements you are trying to find, and use it as an intermediate step in the search:
var name = $(this).closest('.main_page_entry').find('h6').text();
var source = $(this).closest('.main_page_entry').find('.main_item_pic').attr('src');
First off, if this content isn't added dynamically or in a live manner (in other words, if the content is loaded with the original HTML load) then you do not have to use the .live() function.
Also, why are you using .closest()? Couldn't you just do:
<img class="main_item_pic" ref='pic1' src="blah.jpg" />
<a ref='pic1' href="#" class="add_to_list">
<img src="add_icon.gif" />Add to List
</a>
$('a.add_to_list').click(function(){
var ref = $(this).attr('ref');
var src = $("img[ref='" + ref + "']").attr('src');
var name = $('h6 a').text();
});
The method closest() looks for ancestors. Your h6 and img are not ancestors of your link.
Also, I guess you don't want $('h6').html() but $('h6 a').html()
I have the the following DOM structure which I want to sort according to the data-created attribute.
<a id="comment-34" href="#"/>
<li data-created="12342342" />
<a id="comment-35" href="#"/>
<li data-created="89342342" />
<a id="comment-36" href="#"/>
<li data-created="45363342" />
I CANNOT (for various reasons) wrap the <a> and <li> in an outer <div>. I want to do javascript sorting. All the jQuery sorting plugins can do the sorting if I just had the <li>. E.g. using the tinysort jQuery plugin ( http://tinysort.sjeiti.com/ ) I can do
$('li').tsort({order:'desc', attr:'data-created'});
However what happens after the sort is that <a> are no longer associated with their original siblings. I also evaluated https://github.com/jamespadolsey/jQuery-Plugins/tree/master/sortElements/ but it may suffer from the same problem.
Any way to do this? Again, I cannot wrap the <a> and <li> in an outer <div>. I also don't want to dynamically wrap a <div> so that I can use tsort.
Any clean solutions :-) ?
Something like this should work for you:
var elms = [];
$('a').each(function() { //create the array of a and li
var pair = {
aTag: $(this),
liTag: $(this).next("li")
};
elms.push(pair);
});
$("a, li").detach(); //detach them from the dom
elms.sort(function(a, b) {
return a.liTag.data("created") < b.liTag.data("created"); //sort based upon the created data
});
$.each(elms , function(){
$("ul").append(this.aTag).append(this.liTag); //push them back to the dom.
});
Code example on jsfiddle.
You can't really have <li> and <a> elements as siblings in the first place. A list item must be inside a list (<ol>,<ul>), where other elements are not allowed.
Ignoring that, you can simply grab each pair, remove from the DOM, reorder, then put them back. It's quite straight-forward. Example:
var items = [];
$('#sortme a').each(function(){
// grab the element and its next sibling
var self = $(this)
, next = self.next('div');
items.push([
self.remove().get(0),
next.remove().get(0)
]);
});
items.sort(function(a,b){
return a[1].getAttribute('data-created') > b[1].getAttribute('data-created');
});
$.each(items, function(){
$('#sortme').append(this[0], this[1]);
});
Test here: http://jsbin.com/okajo4/edit
Edit: a simpler version :)
var sorted = $('#sortme');
sorted.find('div')
.sort(function(a,b){
return $(a).data('created') > $(b).data('created');
})
.each(function(){
$(this).prev('a').andSelf().appendTo(sorted);
});
Move the a elements inside their respective list items. Then you ought to be able to use the sort you mentioned.
Even if having the elements as siblings is valid, it still strikes me as bad form.