insertAfter specific element based on ID
Asked Answered
B

2

4

I have two lists of links. I have it such that when a user clicks on a link on either list, it is moved to the other list. Very quickly the lists become unorganised so I would like to keep them organised by an ID.

What I want then is when a user clicks the link, it will search in the list for the last element whose data-id is less than the link that was clicked. I would then insert the element after that.

Now, what I am really interested in is the most efficient (code wise) way of doing this with jQuery. I understand I can do this using $(".added").each() but it seems very clunky. Is there a better way using selectors or something else?

<div class="available">
    <h2>Available Groups</h2>
    <a href="" data-id="1">Group 1<span>Add</span></a>
    <a href="" data-id="2">Group 2<span>Add</span></a>
    <a href="" data-id="3">Group 3<span>Add</span></a>
    <a href="" data-id="4">Group 4<span>Add</span></a>
    <a href="" data-id="5">Group 5<span>Add</span></a>
</div>

<div class="added">
    <h2>Added Groups</h2>
</div>

The current implementation:

$(".available a").on("click",function(){
        var myID = parseInt($(this).data("id"));
        var alist = $(".added a");
        if (alist.length > 0) {
            var nodeToInsertAfter;
            $(".added a").each(function () {
                if (parseInt($(this).data("id")) < myID)
                    nodeToInsertAfter = $(this)
            });

            if (nodeToInsertAfter)
                $(this).insertAfter(nodeToInsertAfter);
            else
                $(this).prependTo(".added");
        }
        else {
            $(this).appendTo(".added");
        }
});
Bombardon answered 28/8, 2012 at 14:36 Comment(2)
Might want to post this over on codereview.stackexchange.comIntercommunion
I'm thinking that it's either you iterate over all the element candidates, or you just insert then sort. Complexity-wise, the former sounds simpler, so you'll probably have to use .each() or some other variant. One optimization I'd suggest is that since you're always inserting in order anyway, you can break the iteration loop once you've come across an element that has a data-id value greater than your insertion element.Imperishable
I
1

Here's one way: jsFiddle example

$(".available a").on("click", function(e) {
    e.preventDefault();
    $('.added h2').after($(this));
    var items = $('.added a').get();
    items.sort(function(a, b) {
        var A = $(a).data('id');
        var B = $(b).data('id');
        if (A < B) return -1;
        if (A > B) return 1;
        return 0;
    });
    $('.added h2').after(items);
});​
Intercommunion answered 28/8, 2012 at 14:59 Comment(5)
I updated your code a little (jsfiddle.net/yRxcq/3) to reflect exactly what I wanted... It works great though, thanks. Could you explain a little how it works - I have never actually seen .after. Why is it used twice?Bombardon
The first after inserts the link in the added section without any sort, but the second after replaces all of the links with the sorted version. In other words, the first after allows you to just add a link to whats already down there, but the second added is adding the entire sorted list of links. And after is just another DOM manipulation function, in this case outside of the targeted element.Intercommunion
Aha, that makes sense. How efficient is this? If I had 100 items for example, might it be slow?Bombardon
I'm not sure. Probably the best way to test this is to run an analysis on jsPerf.com to compare. It should be pretty efficient as it uses JavaScript's built-in sort function.Intercommunion
Cheers j08691! Much appreciated.Bombardon
E
0

insertAfter is not good way, try this: http://api.jquery.com/appendTo/

Eubanks answered 28/8, 2012 at 14:43 Comment(1)
appendTo will only work if I want to always append to the end, which I do not, I want to insert the element at the correct location based on its IDBombardon

© 2022 - 2024 — McMap. All rights reserved.