1

I'm working on a legacy project (before Rails 3.1) which has been around for years, so it has Prototype and jQuery all over the place with the general idea to rewrite all the Prototype in jQuery.

I'm working on a problem of an autocomplete style dropdown, which will populate an area in the DOM with some data. This works fine, but certain instances of this autocomplete have an item limit. So when adding the data, it will check to see if there are more than N of a certain selector and remove the last one.

My function to do this is straight forward:

function remove_items(num, selector) {
      while (selector.length >= num) {
          selector[selector.length-1].remove()
      }
  };

I pass in the limit and the array of the objects, selected with jQuery, I want there to be a limit on.

The problem appears to be that .remove() on an element in selector will remove it from the DOM using the Prototype method, even though it's a jQuery object. Then, because the selector array hasn't been changed, the loop runs again with the prototype method and it throws an error because now the element isn't in the DOM.

I made a count variable of the length of selector before the loop and reduce this by one each time, but obviously this is a less than ideal solution.

Anyone know why this is happening or how to stop it happening?

Synthesezia
  • 291
  • 2
  • 12

3 Answers3

1

If selector is a native array, you can truncate it to num items just using:

selector.splice(num);

If selector is a jQuery object, it would be bad practise to attempt to modify it in-place - other jQuery functions return a new jQuery object, i.e.

selector = selector.slice(0, num);

Note that in the latter case it makes little sense to wrap this code in a function, and that if you did, you would have to return the new object, not rely on the passed parameter being modified in-place.

Alnitak
  • 334,560
  • 70
  • 407
  • 495
  • `selector.splice(num)` ... you mean `selector.length = num;` right? ;-) otherwise, +1. – Ja͢ck May 16 '13 at 08:48
  • @Jack no, I explicitly don't mean that, because your method has the potential to _increase_ the array length (padding with `undefined`) if it's shorter than `num`, and `.splice()` doesn't. – Alnitak May 16 '13 at 08:59
  • Good point, I had not considered that ;-) `selector.length = Math.min(selector.length, num);` is not so short anymore ... though the upside is that there's no return value. – Ja͢ck May 16 '13 at 09:02
  • That's not it ... I already gave the upvote with my first comment lol. – Ja͢ck May 16 '13 at 09:07
  • ah, I thought you were saying you _would_ give the +1 if I had used your (broken) method! :) – Alnitak May 16 '13 at 09:08
0

you can use var jQuery=jQuery.noConflict() to avoid interfering

helpful ref: Replace "$"(dollar Sign) with "JQuery"

Community
  • 1
  • 1
Muhammad Bekette
  • 1,396
  • 1
  • 24
  • 60
0

This is not about jQuery.noConflict() at all.

jQuery's .remove() is meant to remove the item from the DOM, not from the array. With the .not() method you can remove items from your collection.

See: http://api.jquery.com/remove/ & /not/

So the code will become:

function remove_items(num, selector) {
    while (selector.length >= num) {
        selector = selector.not(':last');
    }
};

If you also want to remove the element from the DOM and from your array:

function remove_items(num, selector) {
    while (selector.length >= num) {
        selector.remove(':last');
        selector = selector.not(':last');
    }
};

jsFiddle: http://jsfiddle.net/h46WT/1/

Guido Bouman
  • 3,155
  • 4
  • 22
  • 33