Shahar Shokrani
Shahar Shokrani

Reputation: 8740

Set on click to `<li>` without iterating

I'm creating a dynamic <ul>, by creating a dynamic <li> tags list based on a template.

the <li> template looks something like that:

<script type="text/html" id="itemTemplate">
    <li id="{{id}}">
        <div class="name" title="{{name}}">{{name}}</div>
        <div class="saveAs"></div>
        <div class="copy"></div>
    </li>
</script>

My goal is to make the saveAs and the copy div clickable and execute a function with the id as a parameter.

Iv'e managed to do that by this function:

function myView() { 
    self.itemTemplate = null;
    self.myArrayOfObjects = null;

    self.initItemsUl = () => {
        self.itemsUl = self.mainContainer.find('.itemsUl');

        self.myArrayOfObjects.forEach(self.initItemLi);
    };
    self.initItemLi = (item) => {        
        var viewObj = {
            id: item.Id,            
            name: item.Name
        };

        var itemLi = $(Mustache.render(self.itemTemplate, viewObj));
        self.mainContainer.append(itemLi[0]);
        self.setupItemOnClick(itemLi, item.Id);
    };
    self.setupItemOnClick = (itemLi, id) => {
        itemLi.find('.saveAs').on('click', null, () => {
            //do_something(id)
        });

        itemLi.find('.copy').on('click', null, () => {
            //do_something(id)
        });
    };

    return {
        init: (myArrayOfObjects) => {                               
            self.myArrayOfObjects = myArrayOfObjects;               
            self.itemTemplate = $('#itemTemplate').html();      
            Mustache.parse(self.itemTemplate);

            self.initItemsUl();
        }
    };
}

Pay attention that the function setupItemOnClick is being called every time i'm rendering the li template, my question is how to make this function to be called only once?

Upvotes: 0

Views: 73

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1074098

Use event delegation on the ul, rather than handlers on the individual .saveAs and .copy elements:

$("selector-for-your-ul")
    .on("click", ".saveAs", e => {
        // Handle click here, `e.currentTarget` is the `.saveAs` that was clicked
    })
    .on("click", ".copy", e => {
        // Handle click here, `e.currentTarget` is the `.copy` that was clicked
    });

Re your comment:

...how do i get the id of the parent li out of the e object?

By using $(e.currentTarget).closest("li").attr("id").

Upvotes: 4

Related Questions