1

I am a newbie to HTML/Javascript so pardon me if the question is very simplistic. I am trying to develop a toy HTML app to maintain a todo list. I am not really stuck but would like to hear about some good design decisions for the problem below.

I have a django server which serves me a list of elements in the following form:

<ul>
    <li  id="todo_1">Get groceries <a class="deletelink" href="/delete/1/">[X]</a></li>
    <li  id="todo_2">Water plants <a class="deletelink" href="/delete/2/">[X]</a></li>
    <li  id="todo_3">Repair bike <a class="deletelink" href="/delete/3/">[X]</a></li>
</ul>

I also have a bit of jQuery that is called whenever one of the "[X]" links is clicked, which deletes the parent list element like this:

$(".deletelink").on("click", function (event) {
    event.preventDefault();
    var parentItem = $(this).parent(); // the problem is here
    $.ajax({ 
    ... // ajax post request to server here
    }).success( function (status, data) {
        parentItem.delete();
    });
});

Now, the problem is that if I change the structure of the HTML a bit, e.g. doing <div><a class="deletelink" href="/delete/1/">[X]</a></div>, I have to go and change the javascript as well. So, I figured out another way to do this. Now, each element has its own id as well, like:

    <li  id="todo_1">Get groceries <a class="deletelink" id="deletelink_1" href="/delete/1/">[X]</a></li>

Upon click, the javascript changes to

var parentItem = $("#todo_" + (/\D+_(\d+)/.exec(this.id)[1]));

So this implicitly binds each deletelink_i to the todo_i list item. However this looks very hacky (e.g., now if I have a list within another list, I can't easily get all the items within the first list). My question is that is there a better or easier way to do all this in javascript? If possible, I would really like to keep the HTML rendering on the server side.

Subhasis Das
  • 1,667
  • 13
  • 13

3 Answers3

5

You are trying to delete the closest li ancestor so you can use .closest() to find the desired ancestor

var parentItem = $(this).closest('li');
Arun P Johny
  • 384,651
  • 66
  • 527
  • 531
  • 1
    @EhsanSajjad I'd always use `closest()` where possible. If you use `parent()`, changing the HTML structure will break your code. – Rory McCrossan May 20 '14 at 09:24
1

I'd say this is a nice example of how usefull the data attribute is.

This makes the strukture as flexible as possible, you could just do

<li  id="todo_1" data-item-id="1">
    Get groceries 
    <a class="deletelink" data-item-id="1" href="#">
        [X]
    </a>
</li>

And this is the jQuery Part

$(".deletelink").on("click", function (event) {
    event.preventDefault();
    var selectedItem = $(this).attr('data-item-id')
    $.ajax({ 
    ... // ajax post request to server here
    }).success( function (status, data) {
        $('[data-item-id="'+selectedItem+'"]').remove();
    });
});
  • But `data-` is supported in HTML5 right? Still, nice to know about this very useful tip :) – Subhasis Das May 20 '14 at 09:36
  • 1
    For this question I'd like to redirect to: http://stackoverflow.com/questions/3957867/is-there-any-problem-with-using-html5s-data-attributes-for-older-browsers – Christian Richert May 20 '14 at 09:44
0

parent() accepts a selector so you could simply choose to only look at the parents which are li elements:

var parentItem = $(this).parents('li');

tijs
  • 797
  • 7
  • 24
  • not exactly... `.parent()` will return the parent element, passing a selector will further filter parent element to match the passes selector... you may be thinking about [.parents()](http://api.jquery.com/parents/) – Arun P Johny May 20 '14 at 09:27
  • Ah your quite right. But it looks like your answer would actually be better in this case then. – tijs May 20 '14 at 09:30