Reputation: 2828
Is there any elegant way of turning [$(div), $(span), $(li)]
into $(div, span, li)
?
What I need is a jQuery-wrapped set of elements instead of an array of jQuery elements. I would like to do this in as few lines of code as possible, and with minimal (if any) looping.
Edit: For those of you confused by this question, this code is copied and pasted from firebug using console.log on an array of elements that have already been selected.
Upvotes: 52
Views: 24063
Reputation: 9504
Say you have an array of jQuery elements:
let elementList = [$("selector1"), $("selector2"), $("selector3"), ...];
You can simply use the jQuery function ($()
) directly on the array which will return a jQuery set:
let jQuerySetOfElements = $(elementList);
Upvotes: 3
Reputation: 707716
If what you really mean is how to convert:
[$(a), $(b), $(c)]
into the result of:
$(a, b, c)
then you can use the add function to add each jQuery object to another jQuery object:
var x = $(); // empty jQuery object
$.each([$(a), $(b), $(c)], function(i, o) {x = x.add(o)});
At this point, x will contain a combined jQuery object that is the combination of the previous a, b and c jQuery objects in the array.
I couldn't find any way to do it without the each()
loop. The add()
function accepts an array of DOM elements as an argument, but (at least according to the documentation), not an array of jQuery objects.
Or, you could convert each jQuery object to a DOM element, which would likely be a little more efficient because it only makes one new jQuery object at the end:
$([$(".a"), $(".b"), $(".c")].map(function(o) { return o.get() }));
Upvotes: 18
Reputation: 8915
I have a similar problem long time ago. I have a huge form and I need to get every input
. So, my idea was take each input
as jQuery object and turn it into jQuery wrapped set of elements. How can I do that? Well this is the solution for your question.
let fields = $([]);
. 'form#details :input'
as jQuery Objects. .each
method to extract the information that you need, and add the jQuery object to the jQuery set wrapper: fields = fields.add(input);
If you have a list of elements let elements = [$('#gw_id'), $('#erv_id'), $('#name')];
you can replace $('form#details :input')
with elements
;
Another, alternative is to use .reduce
vanilla js. in this let set = $(elements.reduce((acc, cur) => {return acc.concat(cur.get())}, []));
snippet we use the array of elements
and apply reduce
reduce has 4 parameters but we can use the first two that are accumulator
as acc
and currentValue
as cur
also we use the Arrow function (=>
) to reduce the callback. In this callback we concatenate each current value in a new array. Finally, the return array is wrapped into a jQuery object $()
. You can replace elements
with $('form#details :input')
also.
let fields = $([]);
let elements = [$('#gw_id'), $('#erv_id'), $('#name')];
$(function() {
console.log('List of fields: ');
$('form#details :input').each((index, value) => {
let input = $(value);
let id = input.attr('id');
let type = input.attr('type');
fields = fields.add(input);
if (id && type == 'text') {
console.log('Input: ' + id + ' | Text: ' + type);
}
});
fields.addClass('ui-state-error');
let set = $(elements.reduce((acc, cur) => {
return acc.concat(cur.get())
}, []));
console.log('Set list: ');
set.each((index, value) => {
let input = $(value);
let id = input.attr('id');
let type = input.attr('type');
console.log('Input: ' + id + ' | Text: ' + type);
});
});
.ui-state-error {
background: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="details">
<fieldset>
<p>
<label for="gw_id">GW Id</label>
<input type="text" name="gw_id" id="gw_id" value="" class="text ui-widget-content ui-corner-all">
</p>
<p>
<label for="erv_id">ERV Id</label>
<input type="text" name="erv_id" id="erv_id" value="" class="text ui-widget-content ui-corner-all">
</p>
<p>
<label for="name">Name</label>
<input type="text" name="name" id="name" value="" class="text ui-widget-content ui-corner-all">
</p>
<p>
<label for="description">Description</label>
<input type="text" name="description" id="description" value="" class="text ui-widget-content ui-corner-all">
</p>
<input type="hidden" name="no" id="no" value="23" disabled readonly>
<!-- Allow form submission with keyboard without duplicating the dialog button -->
<input type="submit" tabindex="-1" style="position:absolute; top:-1000px">
</fieldset>
</form>
Upvotes: 0
Reputation:
A bit more concise than the accepted answer, one can use the $.fn.toArray
as the argument passed to $.fn.map
:
var list = [$('<a>'), $('<b>'), $('<i>')];
$(list).map($.fn.toArray);
Or perhaps (this is really inferior, but only has one function call in your code):
$.fn.map.call(list, $.fn.toArray);
Upvotes: 9
Reputation: 490423
If Array.prototype.reduce()
is supported in your environment.
var jQueryCollection = [$("a"), $("div")]
.reduce(function (masterCollection, collection) {
return masterCollection.add(collection);
}, $());
Upvotes: 1
Reputation: 7434
To add single element:
var $previousElements = $();
$previousElements.add($element);
to convert array to jQuery set of elements:
var myjQueryElementArray = [$element1, $element2, $elementN];
$(myjQueryElementArray ).map (function () {return this.toArray(); } );
to add array of elements to existing elements:
var $previousElements = $(),
myjQueryElementArray = [$element1, $element2, $elementN];
$previousElements.add($(myjQueryElementArray).map (function () {return this.toArray(); } ));
Upvotes: 2
Reputation: 93533
jQuery's map()
function is perfect for reshaping arrays and/or jQuery collections.
So, given an array set like so:
var arrayOfJQ_Objects = [$("div"), $("span"), $("li")];
This one line of code is all you need (See it in action at jsFiddle):
$(arrayOfJQ_Objects).map (function () {return this.toArray(); } );
Resulting in this console display in Firebug:
jQuery(div, span, li)
Reference, also, jQuery's .toArray()
function.
Upvotes: 51
Reputation: 700562
You can use the add
method to copy the elements in a jQuery object to another. This will copy all elements from each of the jQuery objects in the array source
into the jQuery object items
:
// Create an empty jQuery object
var items = $([]);
// Add the elements from each jQuery object to it
$.each(source, function(){ items = items.add(this); });
(Prior to version 1.3.2 the add
method doesn't support adding a jQuery object, so you would need to use items.add(this.get());
instead.)
Upvotes: 5
Reputation: 6188
Edit: I thought jQuery supported all Array
methods, but nay, so here's a working version of my initial solution, albeit it's a bit odd since I am sticking to the same methods:
var set; // The array of jQuery objects,
// but make sure it's an Array.
var output = set.pop();
$.each(set, function (_, item) {
return [].push.call(output, [].pop.call(item));
});
Upvotes: 1
Reputation: 31249
you could do something like this:
var $temp = $();
$.each([$("li"), $("li"), $("li")], function(){
$temp.push(this[0]);
})
$temp all your elements in one jQuery selector
But i am curious what brings you to this situation having an array of different jQuery elements. You know that you can select different elements using a comma? like $("li, ul > li:eq(0), div")
edit as Guffa pointed out, this only adds the first element of each section. .add()
is a better choice then .push()
here.
Upvotes: 0