Skip to main content

Bug Tracker

Side navigation

#8897 closed feature (wontfix)

Opened April 16, 2011 05:12PM UTC

Closed April 16, 2011 09:14PM UTC

Last modified November 14, 2012 01:15AM UTC

append() should work with an array of jQuery objects

Reported by: humaninternals <nadav+jquery@humaninternals.com> Owned by:
Priority: low Milestone: 1.next
Component: core Version: 1.5.2
Keywords: Cc:
Blocked by: Blocking:
Description

This works as expected (array of DOM elements):

$(document.createElement('form'))
        .append([document.createElement('input')]);

But passing an array of jQuery objects:

$(document.createElement('form'))
        .append([$(document.createElement('input'))]);

Fails with Uncaught Error: NOT_FOUND_ERR: DOM Exception on Chrome and Node cannot be inserted at the specified point in the hierarchy" code: "3 on Firefox. It can be seen here.

I assume this isn't intentional and that it should work, shouldn't it?

Attachments (0)
Change History (12)

Changed April 16, 2011 08:06PM UTC by timmywil comment:1

component: unfiledcore
priority: undecidedlow
resolution: → invalid
status: newclosed

jQuery understands passing an array of elements as it can be easily converted to a jQuery object. Passing an array of jQuery objects is not supported.

Changed April 16, 2011 08:14PM UTC by humaninternals <nadav+jquery@humaninternals.com> comment:2

Well, I am aware that its not supported, but why wouldn't it be? Is there any special reason you wouldn't want to support that? It should be easy enough to add support for that.

Its really annoying in cases you dynamically create multiple children, such as $('<ul>').append($.map(["foo", "bar"], function(val){ return $("<li>").text(val); }). Adding support for that can really benefit for those cases.

I do realize I can manually call .get(0) to transform those jQuery object to DOM elements, but... its much cleaner if it'll be done by jQuery itself instead of by the developer.

Changed April 16, 2011 08:54PM UTC by timmywil comment:3

resolution: invalid
status: closedreopened
type: bugfeature

Fair enough. This is more of a feature request then. I was going to say we have discussed this in the past and decided it would be too costly to support. However, I think I have an idea on how to support it, but I want to do more performance testing first.

Changed April 16, 2011 09:14PM UTC by timmywil comment:4

resolution: → wontfix
status: reopenedclosed

My idea didn't pan out. I think this would be too costly to support as was previously indicated by ajpiano.

Changed April 16, 2011 09:19PM UTC by humaninternals <nadav+jquery@humaninternals.com> comment:5

Oh, well.. if anyone stumbles here expecting this to work, you can (function($){var jq_append = $.fn.append; $.fn.append = function(arr) { return $.isArray(arr) ? jq_append.call(this, $.map(arr, function(el){ return el instanceof $ ? el.get() : el; })) : jq_append.apply(this, arguments); }})(jQuery); to add support for that. It'll also work with an array that contains both DOM elements and jQuery objects - but when the first argument is an array it'll ignore the other arguments. Do note that duck punching it like that is somewhat slower and more resource intensive.

Changed February 07, 2012 06:23PM UTC by miasnikov@mail.ru comment:6

Would be really helpful to fix it, otherwise we have to spread .get(0) across code to make it working. Very annoying.

Changed April 25, 2012 09:30AM UTC by anonymous comment:7

this is surely not a feature request, if you pass an array you simply expect it to appended just like any other jquery method, it's a bit confusing that it's not compatible with it's own object model.

Changed April 25, 2012 04:22PM UTC by ajpiano comment:8

What about a 2 level deep array of arrays that contains jQuery objects? An object where some of the members are jQuery objects and some are not? There are essentially infinite permutations of input that .append() (etc) could accept, just because somewhere nested deep inside somewhere, is a bunch of DOM elements. We can't reasonably support all these possible variations, and not doing so doesn't mean that jQuery "isn't compatible with it's own object model," it means that there's a difference between accepting a certain data type as input and accepting *any* data type as input just because somewhere inside that structure exists the first, acceptable data type.

Changed June 19, 2012 12:19AM UTC by narcvs@gmail.com comment:9

Another monkey-patch to enable this: https://gist.github.com/2951521

Changed July 05, 2012 05:53PM UTC by Jeremy comment:10

Replying to [comment:8 ajpiano]:

We can't reasonably support all these possible variations

Would you mind taking just a moment to expand on that? It seems to me that a fairly simple recursive operation, with a function like the following, could solve every possible permutation that append might be expected to accept (including every one you mentioned, which means accepting arrays with a mix of other arrays/jQuery objects/raw elements/strings):

function newAppend(stuff) {
  if(isRawElement(stuff) || typeof stuff == 'string') {
    // Cover strings and raw elements
    this.oldAppend(stuff);
  } else  if (isJQueryObject(stuff)) {
    // Cover jQuery objects
    stuff.appendTo(this);
  } else if (isArray(stuff)) {
    // Cover arrays of *anything*
    var thiz = this; // Could use $.proxy instead
    $.each(stuff, function(i, subStuff) {
      newAppend.call(thiz, subStuff);
    })
  } else {
    throw "What garbage have you given me you crazy developer!?!?";
  }

Changed August 07, 2012 08:23PM UTC by Mustafa comment:11

This seems like an intuitive way of using the append() method. A developer should not expect nested arrays to be recursively cycled through for this method (although that would be nice and pretty simple) but expecting it to at least understand jquery objects is not asking too much.

Changed November 14, 2012 01:15AM UTC by dmethvin comment:12

If you like this idea, please use one of the suggested patches above or make a plugin.