bipen bipen - 6 months ago 35
Javascript Question

Jquery Clone fix

so i got this jquery clone plugins which fixes the values of cloned textarea and select (copies the values of cloned elements including textarea and selects.) . The code goes like this

(function (original) {
jQuery.fn.clone = function () {
var result = original.apply(this, arguments),
my_textareas = this.find('textarea').add(this.filter('textarea')),
result_textareas = result.find('textarea').add(result.filter('textarea')),
my_selects = this.find('select').add(this.filter('select')),
result_selects = result.find('select').add(result.filter('select'));
//console.log('this',this)
//console.log('my',this.find('textarea').length,'rsult',this.filter('textarea'),length);

for (var i = 0, l = my_textareas.length; i < l; ++i)
$(result_textareas[i]).val($(my_textareas[i]).val());
for (var i = 0, l = my_selects.length; i < l; ++i)
result_selects[i].selectedIndex = my_selects[i].selectedIndex;

return result;
};
}) (jQuery.fn.clone);


this is perfect. however these lines

my_textareas = this.find('textarea').add(this.filter('textarea')),
result_textareas = result.find('textarea').add(result.filter('textarea')),


what i don't understand is, why would we need to
add
.filter('textarea')
again when we have already selected all the textarea inside
this
with
find
(which we loop through to get the value later).

my view is

my_textareas = this.find('textarea'),
result_textareas = result.find('textarea'),


should work just fine without
add(filter..)
.

is
filter
there for some other reasons ?

Answer

find only gets descendant elements. filter gets only top level elements.

By using both, you get any elements within your collection which are textarea as well as those which are descendants of elements which are in your collection.

An example:

<div class="abc">
    <textarea id="one"></textarea>
</div>
<textarea class="abc" id="two"></textarea>

IF we do this:

$(".abc").find("textarea")

our collection will contain only the textarea with an id of "two". However, if we do:

$(".abc").filter("textarea")

our collection will contain only the textarea with an id of "one". The code as you posted uses both which would get both "one" and "two".