Array of checkbox elements

Asked

Viewed 60 times

4

Test scenario

Dynamic form:

function addReg(){

  const template = $('#formX > div').last();
  const novo = template.clone();
  $(template).find('select').each(function(i) {
    $(novo).find("select").eq(i).val($(this).val());
  });
  novo.find('.form-group > label').remove();
  novo.find('.form-check-inline').removeAttr('style');
  $('#formX').append(novo);
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">

 <div class="row">
  <form id="formX" method="post" action="action.php" target="_blank">
    <div id="registro" class="form-row">
      <div class="form-group mr-2">
       <label for="item">Item</label>
       <select id="item" class="form-control" tabindex="-1" name="item[]">
        <option selected>Selecione...</option>
        <option value="1">Item 1</option>
        <option value="2">Item 2</option>
        <option value="3">Item 3</option>
      </select>
    </div>
    <div class="form-group col-md-1">
     <div class="form-check form-check-inline" style="padding-top: 30px;">
      <input class="form-check-input" type="checkbox" id="bf" value="S" name="bf[]" tabindex="-1">
      <label class="form-check-label" for="bf"><b>BF</b></label>
    </div>
  </div>
</div>
</form>
</div>

<div class="row">
  <button form="formX" type="submit" class="btn btn-primary mr-3" tabindex="-1">Salvar</button>
  <button class="btn btn-info" onclick="addReg()" tabindex="-1">+</button>
</div>

</div>


Problem

When the checkbox, it takes the value. When not, it does not take.

Thus, the reference between the records is incorrect.


Example

lançamento

Exit:

Array
(
    [item] => Array
        (
            [0] => 1
            [1] => 3
            [2] => 2
            [3] => 1
        )

    [bf] => Array
        (
            [0] => S
            [1] => S
        )
)

Expected

The ideal way out would be:

[bf] => Array
        (
            [0] => N
            [1] => S
            [2] => S
            [3] => N
        )

Or even:

[bf] => Array
        (
            [1] => S
            [2] => S
        )

Doubts

  • What possible solutions to use array with checkbox in this case?
  • You can define the value of checkbox when unmarked?
  • 1

    Instead of using the names item[] and bf[], use registros[0][item] and registros[0][bf], so in PHP you will have a $_POST['registros'] that will be a array of array associative.

2 answers

1

I created a checkbox which is always selected and hidden, which will be used to be submitted, and other checkbox which is not hidden and has an event, this event changes the value from the occult to "S" or "N", thus the array will arrive as follows.

[bf] => Array
        (
            [0] => N
            [1] => S
            [2] => S
            [3] => N
        )

function addReg(){

  const template = $('#formX > div').last();
  const novo = template.clone();
  $(template).find('select').each(function(i) {
    $(novo).find("select").eq(i).val($(this).val());
  });
  novo.find('.form-group > label').remove();
  novo.find('.form-check-inline').removeAttr('style');
  $('#formX').append(novo);
}
$('#formX').on("click", ".form-check-input", function(){
  $(this).prev().val("N");
  if($(this).is(':checked'))
    $(this).prev().val("S");
});
#bf{
  display:none;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">

 <div class="row">
  <form id="formX" method="post" action="action.php" target="_blank">
    <div id="registro" class="form-row">
      <div class="form-group mr-2">
       <label for="item">Item</label>
       <select id="item" class="form-control" tabindex="-1" name="item[]">
        <option selected>Selecione...</option>
        <option value="1">Item 1</option>
        <option value="2">Item 2</option>
        <option value="3">Item 3</option>
      </select>
    </div>
    <div class="form-group col-md-1">
     <div class="form-check form-check-inline" style="padding-top: 30px;">
      <input type="checkbox" id="bf" value="N" name="bf[]" tabindex="-1" checked>
      <input class="form-check-input" type="checkbox">
      <label class="form-check-label" for="bf"><b>BF</b></label>
    </div>
  </div>
</div>
</form>
</div>

<div class="row">
  <button form="formX" type="submit" class="btn btn-primary mr-3" tabindex="-1">Salvar</button>
  <button class="btn btn-info" onclick="addReg()" tabindex="-1">+</button>
</div>

</div>

  • 1

    Wictor, I tested your answer too, it works, +1. But Sam’s was a little less "tidy". But thanks for the strength!

1


Create array with indexes by changing the name of select and of checkbox increasing +1 value in brackets according to amount of Rows.

For example, in the first Row, the Names begin with [0] and as you clone, the [0] of the following clones [1], [2], [3] etc..

By submitting with the values exemplified in the question, will result:

[item]
array(4) {
  [0]=> string(1) "1"
  [1]=> string(1) "3"
  [2]=> string(1) "2"
  [3]=> string(1) "1"
}

[bf]
array(2) {
  [1]=> string(1) "S"
  [2]=> string(1) "S"
}

In the select and in the checkbox of the first Row, change the Names to name="item[0]" and name="bf[0]" respectively.

And change the function as below (see comments):

function addReg(){

  const template = $('#formX > div').last();
  const novo = template.clone();
  $(template).find('select').each(function(i) {

     // conta as rows que servirá de novo índice na array
     var idx = $('#formX > div').length;

    $(novo).find("select").eq(i).val($(this).val())
    .attr("name", "item["+ idx +"]"); // altera o name do "item"

    // altera o name do bf
    $(novo).find("[name^=bf]").attr("name", "bf["+ idx +"]")

  });
  novo.find('.form-group > label').remove();
  novo.find('.form-check-inline').removeAttr('style');
  $('#formX').append(novo);

}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.