3

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.

4
  • there is not "collection-item" in html,it is added dynamically in the html through JS Commented Jun 24, 2017 at 8:19
  • And what does this refer to: list[i].username ? Commented Jun 24, 2017 at 8:22
  • that is a internal code,it's a Django variable,the code would have become lengthy had I added the code for that,because then I will have to add the content of views.py(a Django file). Commented Jun 24, 2017 at 8:24
  • Had I included it,I would have got -1 for not providing a precise information,but it's the same case now also:/. Commented Jun 24, 2017 at 8:26

4 Answers 4

3

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.

Sign up to request clarification or add additional context in comments.

6 Comments

Thanks for the answer.I have made the changes and uploaded it:github.com/Sharma96/dropdownlist , but,still the hover it event is not running,I have uploaded the whole JS file and a html snippet for more clarity of code.
Thats quite a lot of code you have there to look through, but there still seems to be no space in the markup between 'collection-item' and 'j', causing them to fuse into one classname. You then use "collection-item.j" as a selector which implies they are two separate classes. the className should either compile to 'collection-itemj', in which case each element would be selected by a unique classname, "collection-item1", or you could use two classnames, "collection-item j", in which case you would use "collection-item.j"
If you want to do it sphinx's way, then you have to not put dots in the selector. $("a.b") will select all elements that have both css class a and b, while $("ab") will select all elements with the single css class "ab". I would suggest using two classes, that way you can use simple jquery to apply things to all "collection-items".
I tried it with space,but now the problem is all the li elements are getting the id of the last element,so,instead of $('.collection-item.'+j).attr("id",list[i].username),I need to add through "this" object.Can you specify how to access the collection-item through this object.As "this" refers to "collection".
actually I hadnt thought of that, you can just put it back in the loop again like it originally was and use the (".collection-item."j) to refer to them inside the loop while I look for a better solution. In my jsfiddle here jsfiddle.net/0wqeouxo/1 $(this) does work within the selector, but it might be a difference between "click" and "on"
|
3

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);
        }
 );

1 Comment

Thanks for the answer,but,It's not working.the hover event is not being fired.
2

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');

Comments

1

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);
        });

1 Comment

Thanks for the answer,but,It's not working.the hover event is not being fired.I think my hover event is also right,but the code for appending the number after the class is not working.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.