Turn array of jQuery elements into jQuery wrapped set of elements

Viewed 23757

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.

11 Answers

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.

  1. First you need to create an empty array as a jQuery object like this: let fields = $([]);.
  2. Now, use a string containing a selector expression to get the elements that you need in this example: 'form#details :input' as jQuery Objects.
  3. Then use .each method to extract the information that you need, and add the jQuery object to the jQuery set wrapper: fields = fields.add(input);

How do you apply to this question?

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>

Related