GeekyOwl
GeekyOwl

Reputation: 79

jQuery convert checkbox selections to array

I have an HTML like this:

<div class="pgggo-list-taxon">
    <li>
        <label>
            <input type="checkbox" name="pgggo-category-sep-56[]">
            <div class="icon-box">
                <div name="development">Development</div>
            </div>
        </label>
    </li>
    <li>
        <label>
            <input type="checkbox" name="pgggo-category-sep-14[]">
            <div class="icon-box">
                <div name="food">Food</div>
            </div>
        </label>
    </li>
    <li>
        <label>
            <input type="checkbox" name="pgggo-category-sep-8[]">
            <div class="icon-box">
                <div name="medical">Medical</div>
            </div>
        </label>
    </li>
    <li>
        <label>
            <input type="checkbox" name="pgggo-category-sep-1[]">
            <div class="icon-box">
                <div name="uncategorized">Uncategorized</div>
            </div>
        </label>
    </li>
    <li>
        <label>
            <input type="checkbox" name="pgggo-category-sep-2[]">
            <div class="icon-box">
                <div name="wordpress">WordPress</div>
            </div>
        </label>
    </li>
</div>

Each checkbox has unique name = pgggo-category-sep-56, pgggo-category-sep-14. As multiple items are clicked the ids are added to the id field of below array.

I am trying to have a method which gives me an array as output:

$output = array(
   array(
     'taxonomy'=> 'category', // pgggo-category-sep-56 --category word is pulled from here
     'id'=> array(56,14), // ids are pulled pgggo-category-sep-56 number at the end
    )
   array(
     'taxonomy'=> 'home', // pgggo-home-sep-56 --homeword is pulled from here
     'id'=> array(56,14), // ids are pulled pgggo-category-sep-56 number at the end
    )
);

I tried this:

$('.pgggo-container-ajax-sorting').on('click', '.pgggo-list-taxon input', function(event) {
   var outputPgggo = $(this).attr('name');
}

But this only pulls the string. Is there any way to get this done?

Upvotes: 0

Views: 102

Answers (2)

Ivan
Ivan

Reputation: 40638

I would recommend storing the ids in an object instead of having an array of array. It's easier to work with. Something like this:

const array = {
  category: [],
  home: [],
};

Then, you can always transform into the desired form with some array manipulation:

Object.entries(array).map(([taxomony, id]) => ({taxomony, id}))

Here is the code to update the object when a checkbox is clicked:

const array = {};

$('[name^="pgggo-"]').on('click', function() {
  const [_, taxonomy, __, attr] = $(this).attr('name').split('-');
  const id = attr.split('[')[0];
  const checked = $(this).prop('checked');
  
  array[taxonomy] = array[taxonomy] || [];
  const index = array[taxonomy].indexOf(id);
  index == -1 ? array[taxonomy].push(id) : array[taxonomy].splice(index, 1);
  
  console.log(array);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="pgggo-list-taxon">
  <li>
    <label>
            <input type="checkbox" name="pgggo-category-sep-56[]">
            <div class="icon-box">
                <div name="development">Development</div>
            </div>
        </label>
  </li>
  <li>
    <label>
            <input type="checkbox" name="pgggo-category-sep-14[]">
            <div class="icon-box">
                <div name="food">Food (category)</div>
            </div>
        </label>
  </li>
  <li>
    <label>
            <input type="checkbox" name="pgggo-home-sep-14[]">
            <div class="icon-box">
                <div name="food">Food (home)</div>
            </div>
        </label>
  </li>
  <li>
    <label>
            <input type="checkbox" name="pgggo-category-sep-8[]">
            <div class="icon-box">
                <div name="medical">Medical</div>
            </div>
        </label>
  </li>
  <li>
    <label>
            <input type="checkbox" name="pgggo-category-sep-1[]">
            <div class="icon-box">
                <div name="uncategorized">Uncategorized</div>
            </div>
        </label>
  </li>
  <li>
    <label>
            <input type="checkbox" name="pgggo-category-sep-2[]">
            <div class="icon-box">
                <div name="wordpress">WordPress</div>
            </div>
        </label>
  </li>
</div>


Or, instead of having to go through the trouble of handling duplicates and states. You can construct the array only when you need to use it:

$('.sort-button').on('click', function() {

  const array = {};
  $('[name^="pgggo-"]').filter(':checked').each(function() {
    const [_, taxonomy, __, attr] = $(this).attr('name').split('-');
    array[taxonomy] = array[taxonomy] || [];
    array[taxonomy].push(attr.split('[')[0]);
  });
  
  console.log(array);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="pgggo-list-taxon">
  <li>
    <label>
            <input type="checkbox" name="pgggo-category-sep-56[]">
            <div class="icon-box">
                <div name="development">Development</div>
            </div>
        </label>
  </li>
  <li>
    <label>
            <input type="checkbox" name="pgggo-category-sep-14[]">
            <div class="icon-box">
                <div name="food">Food (category)</div>
            </div>
        </label>
  </li>
  <li>
    <label>
            <input type="checkbox" name="pgggo-home-sep-14[]">
            <div class="icon-box">
                <div name="food">Food (home)</div>
            </div>
        </label>
  </li>
  <li>
    <label>
            <input type="checkbox" name="pgggo-category-sep-8[]">
            <div class="icon-box">
                <div name="medical">Medical</div>
            </div>
        </label>
  </li>
  <li>
    <label>
            <input type="checkbox" name="pgggo-category-sep-1[]">
            <div class="icon-box">
                <div name="uncategorized">Uncategorized</div>
            </div>
        </label>
  </li>
  <li>
    <label>
            <input type="checkbox" name="pgggo-category-sep-2[]">
            <div class="icon-box">
                <div name="wordpress">WordPress</div>
            </div>
        </label>
  </li>
</div>

<button class="sort-button">Show!</button> <!-- for demo purposes -->

Upvotes: 1

Mischa
Mischa

Reputation: 1601

You want to store/send the selected values in one array, right? So why you use unique names then for each checkbox?! ... if they belong together then name them appropriately like so:

    <input type="checkbox" name="pgggo-category-sep[]" value="56">
    <input type="checkbox" name="pgggo-category-sep[]" value="14">
    <input type="checkbox" name="pgggo-category-sep[]" value="8">
    <input type="checkbox" name="pgggo-category-sep[]" value="1">
    <input type="checkbox" name="pgggo-category-sep[]" value="2">

    <input type="checkbox" name="pgggo-home-sep[]" value="foo">
    <input type="checkbox" name="pgggo-home-sep[]" value="bar">
    //....

Then they will be sent as an array on submit automatically, no further rearrangement needed ... or if you really want to do it the ajax way still, you can easily get all the ids for the category-checkboxes like so:

    $('[name="pgggo-category-sep[]"]').on('change', function () {
      let values = Array.from($('[name="pgggo-category-sep[]"]:checked'))
        .map(elem => $(elem).val())
    })

Upvotes: 1

Related Questions