Search code examples
phpjqueryimplode

How to include checkbox value and associated label text in a jQuery array with line breaks after multiple implode values


I am trying to create an array combining both the label and value of an input field. The problem is my jQuery code combines ALL labels and input values, not just those which are selected. The code I am trying is as below:

jQuery:

let values = [];
        
$("label[for='servicelist-label[]'], input[name='servicelist-details[]']").each(function() {
    values.push($(this).text());
    values.push($(this).val());
});

PHP Implode Code:

$serviceinfo = implode("",array_map(function($i){
               return implode("<br>",$i);
               },array_chunk($_POST['servicelist'],2)));

PHP Form Elements:

<label for="servicelistlabel[]" >Service 1: </label><input class="list" type="checkbox" name="servicelistcheckbox[]" id="servicelist1" value="Area 1"><br>
<label for="servicelistlabel[]" >Service 2: </label><input class="list" type="checkbox" name="servicelistcheckbox[]" id="servicelist2" value="Area 2"><br>
<label for="servicelistlabel[]" >Service 3: </label><input class="list" type="checkbox" name="servicelistcheckbox[]" id="servicelist3" value="Area 3"><br>

Any help would be much appreciated! Thank you.


Solution

  • You are so close, you just need to switch the implode-separators:

    $serviceinfo = implode("<br>",array_map(function($i){
                   return implode(" ",$i);
                   },array_chunk($_POST['servicelist'],2)));
    

    This should result in the desired output.

    Edit:

    Ok I now know what you want to achieve. There are a couple of problems with the JS part. I will go over your code real quick

    $("label[for='servicelistlabel[]'], input[name='servicelistcheckbox[]']:checked").each(function() {
       values.push($(this).text());
       values.push($(this).val());
    });
    
    • You are iterating over both, label and checkbox at the same time.
    • $(this) is the label at one iteration, the checkbox in the next iteration.
    • Because of that $(this).val() is empty the first iteration since the label has no value.
    • $(this).text() is empty the next iteration since the checkbox has no text.
    • This results in an array structure like ["Label", "", "", "Value"] for each checkbox you have checked.
    • Also, the for="" attribute in a label has to match the id="" attribute of the checkbox, or else the label will not trigger on click.

    How to solve?

    https://jsfiddle.net/5ubnes1k/ Take a look at this fiddle. I put each label/checkbox-combo into a div.checkbox to have an easier time selecting it.

    let values = [];
    $(".checkbox").each(function() {
      const label = $(this).find('label');
      const checkbox = $(this).find('input[type="checkbox"]');
    
      if (checkbox.is(":checked")) {
        values.push(label.text(), checkbox.val());
      }
    });
    

    Now we only iterate over the .checkbox divs, selecting the label and checkbox inside. If the checkbox is checked, we push the label-text and checkbox-value into the array. The output is something like: ["Service 1: ", "Service1", "Service 3: ", "Service3"]

    With this array structure you should be able to get the wanted result with the implode part of your code.