alisa kibin
alisa kibin

Reputation: 582

Click to get index of array element with jquery

Ok, I've tried my best at searching, but. I've got a task, where I need to load some js using the Ajax and so on. Long story short, I've stuck.

First a code in script.js (which I must load AND which I can't modify):

var divs = [
    '<div class="item">Lorem ipsum 0</div>',
    '<div class="item">Lorem ipsum 1</div>',
    '<div class="item">Lorem ipsum 2</div>',
    '<div class="item">Lorem ipsum 3</div>',
    '<div class="item">Lorem ipsum 4</div>',
    '<div class="item">Lorem ipsum 5</div>',
    '<div class="item">Lorem ipsum 6</div>',
    '<div class="item">Lorem ipsum 7</div>'
];
delete(divs[3]);

Then my script to load it

$.getScript('script.js', function() {
    $('.a').append('<div class="yep">' + divs.join('') + '</div>');
    $('.item').each(function() {
        $(this).click(function() {
            console.log( $('.item').index(this) );
        });
    });     
});

The problem is that on click I need to get index of item in array, i.e. if I click on "Lorem ipsum 4" console should print "4", not "3" as it happens now (because of deleted element which doesn't appear in dom). Is there a way to get the right result using jQuery?

Ok, I need to say that it's a task. And here is the thing: I simply CAN'T modify script.js. Let's say it's on server and I have no access to it until I get it. But I need index of an element which it has in the original array.

Upvotes: 7

Views: 12408

Answers (4)

Ian
Ian

Reputation: 50905

Try something like this:

http://jsfiddle.net/YjNAL/1/

var divs = [
    '<div class="item">Lorem ipsum 0</div>',
    '<div class="item">Lorem ipsum 1</div>',
    '<div class="item">Lorem ipsum 2</div>',
    '<div class="item">Lorem ipsum 3</div>',
    '<div class="item">Lorem ipsum 4</div>',
    '<div class="item">Lorem ipsum 5</div>',
    '<div class="item">Lorem ipsum 6</div>',
    '<div class="item">Lorem ipsum 7</div>'
];
delete(divs[3]);

var yep = $('<div class="yep"></div>');    // Changed (from edit)

for (var i = 0; i < divs.length; i++) {
    if (divs[i]) {  // Don't operate on undefined items
        var theDiv = $(divs[i]).data("idx", i);    // Changed (from edit)

        yep.append(theDiv);    // Changed (from edit)
    }
}

$(".a").append(yep);    // Changed (from edit)

$('.item').on("click", function() {
    console.log( $(this).data("idx") );
});

Notice how the original array isn't modified.

Each item in the array is modified and creates a jQuery object before it is appended. <- I'm sure that part could be done more efficiently, I was just trying to throw something together.

It stores its index in the array from of the for loop, so that should be accurate.

Any undefined (deleted) items are ignored.

Upvotes: 2

Mark Schultheiss
Mark Schultheiss

Reputation: 34168

If you would rather have it a bit dynamic, you could create an element, add a data field to it, then access that element:

var divs = [
    '<div class="item">Lorem ipsum 0</div>',
    '<div class="item">Lorem ipsum 1</div>',
    '<div class="item">Lorem ipsum 2</div>',
    '<div class="item">Lorem ipsum 3</div>',
    '<div class="item">Lorem ipsum 4</div>',
    '<div class="item">Lorem ipsum 5</div>',
    '<div class="item">Lorem ipsum 6</div>',
    '<div class="item">Lorem ipsum 7</div>'
    ];
var newdivs = $('<div class="yep">').append(divs.join(""));
newdivs.find('.item').each(function() {
     $(this).data("myindex", $(this).index());
});
var elementToDelete = 3
delete(divs[elementToDelete]);
newdivs.find('.item').eq(elementToDelete).remove();
$('.a').append(newdivs);

$('.a').on('click','.item',function() {
    $(this).css("background-color","lime");
    alert($(this).data("myindex"));
});

see how it works here: http://jsfiddle.net/rZjNd/2/

Upvotes: -1

Cerbrus
Cerbrus

Reputation: 72857

You can try this. Give all the divs an ID, and get that:

var divs = [
    '<div class="item" id="0">Lorem ipsum 0</div>',
    '<div class="item" id="1">Lorem ipsum 1</div>',
    '<div class="item" id="2">Lorem ipsum 2</div>',
    '<div class="item" id="3">Lorem ipsum 3</div>',
    '<div class="item" id="4">Lorem ipsum 4</div>',
    '<div class="item" id="5">Lorem ipsum 5</div>',
    '<div class="item" id="6">Lorem ipsum 6</div>',
    '<div class="item" id="7">Lorem ipsum 7</div>'
];
delete(divs[3]);

$('.a').append('<div class="yep">' + divs.join('') + '</div>');
$('.item').each(function() {
    $(this).click(function() {
        console.log(this.id);
    });
});  ​

Numbers in id's?!?

Yea, I know, in HTML4 ids starting with numbers weren't allowed. HTML5, however, removed this restriction.
Those divs will validate according to the w3 validator.

Upvotes: -1

Blazemonger
Blazemonger

Reputation: 92903

You're asking for the INDEX of the clicked item. Your code is doing exactly what it's supposed to do. jQuery has no way to know if you've deleted items from the original list, it can only see what's currently there.

The best solution is to add an HTML attribute to the original items, and console.log that attribute instead of the .index. Like this:

var divs = [
    '<div data-idx="0" class="item">Lorem ipsum 0</div>',
    '<div data-idx="1" class="item">Lorem ipsum 1</div>',
    '<div data-idx="2" class="item">Lorem ipsum 2</div>',
    '<div data-idx="3" class="item">Lorem ipsum 3</div>',
    '<div data-idx="4" class="item">Lorem ipsum 4</div>',
    '<div data-idx="5" class="item">Lorem ipsum 5</div>',
    '<div data-idx="6" class="item">Lorem ipsum 6</div>',
    '<div data-idx="7" class="item">Lorem ipsum 7</div>'
    ];
delete(divs[3]);


$('.a').append('<div class="yep">' + divs.join('') + '</div>');

$('.item').each(function() {
    $(this).click(function() {
        console.log($(this).data('idx'));
    });
});​

http://jsfiddle.net/mblase75/8NLGm/

Upvotes: 4

Related Questions