2

I have a MySql table and I would to be able to modify through a HTML form. The MySql table has columns like this:

id (int) | name (text) | option1 (boolean) | option2 (boolean)

The number of field options will grow over time and is not fixed, but always contains boolean data (0 or 1). The number of rows is not fixed as well.

I would like to modify the table with a html form which looks like this:

<form action="file.php" method="post">
<table style="width:100%">
  <tr>
    <th>Name</th>
    <th>Option1</th>
    <th>Option2</th>
  </tr>
  <tr>
    <th>lili</th>
    <th><input type="checkbox" name="lili_1"checked></th>
    <th><input type="checkbox" name="lili_2"></th>
  </tr>
  <tr>
    <th>thor</th>
    <th><input type="checkbox" name="thor_1" checked></th>
    <th><input type="checkbox" name="thor_2" checked></th>
  </tr>
  <tr>
    <th>fred</th>
    <th><input type="checkbox" name="fred_1" checked></th>
    <th><input type="checkbox" name="fred_2" ></th>
  </tr>
</table>
<button type="submit">Update</button>
</form>

Now it gets tricky. When I submit the form, on the server side I don't know how many columns/lines there are. I would like to update the whole database table (it's small), so I need to know the state of every checkbox for columns (option1, option2, ...) and rows (lili, thor, fred,...)

My idea is to name each checkbox based on the column and value of field "name". I would also need to send an array containing all the names and the columns (because I can only know the boxes that were checked, not the unckecked ones).

On server-side, I then need to recreate the matrix with the array of columns and names and put 1 where a checkbox was checked (through the name of the checkbox).

This seems to be a very error-prone and long to implement... to do such an simple task. Can someone points me to a smarter way to to that ?

Thank you

Gordak
  • 2,060
  • 22
  • 32
  • Try `name="lili[]"` for the whole "lili" group and the same for all the rest of the groups. Server-side you'll get a list named "lili" (`$_POST['lili']`) with True/False values. – Sergiu Paraschiv Jul 08 '15 at 11:49
  • I submit the form with a html button
    – Gordak Jul 08 '15 at 11:49
  • Are you sure ? Will I not get only "true" values ? As only the checkboxes actually checked will send data ? – Gordak Jul 08 '15 at 11:53
  • 1
    Yeah, that's true. You need to also set `value="1/2/3/..."` on the checkboxes. Then you'll get a list of "id" instead of just `true` values so you can identify them. – Sergiu Paraschiv Jul 08 '15 at 11:57
  • Actually, there already is an answer for this here http://stackoverflow.com/questions/4997252/get-post-from-multiple-checkboxes – Sergiu Paraschiv Jul 08 '15 at 11:58
  • Thanks, it really helps. I will put name=lili[] and value=optionX depending on the column, like this I can directly know which column is targetted for each line. And I'll still need to send the array of names. – Gordak Jul 08 '15 at 12:01

2 Answers2

1

You can group checkboxes with name="thor[]" or name="lili[]" in php backend you can retrieve it by $_REQUEST['thor']. Remember it is an array. So you loop it by foreach($_REQUEST['thor'] as $thor){} check value by if($thor)

Dhinju Divakaran
  • 893
  • 1
  • 8
  • 11
  • I can't directly access $_REQUEST['thor'] because I don't know how many rows there are. I need to have a variable to know that. Thank you for your suggestion. I will also have an array with the names of the rows. – Gordak Jul 08 '15 at 12:07
  • How can you render this html? – Dhinju Divakaran Jul 08 '15 at 12:10
  • When I generate the html I have access to the db. I can see the number of columns and rows. When I receive the form, I don't know if new rows have been added, so I have to modify only the part of the table that was visible when I generated the html form. I'm very new to php/mysql, if you think I missed something obvious, that's very likely the case ;) – Gordak Jul 08 '15 at 12:25
0

The solution is to add a bit of Javascript that will capture all of the field names and assign them to the value of a hidden field just before the form is submitted. That will provide you with all of the info you need for server side processing. Here is a working sample.

test.php

<html>
  <head>
    <title>test.php</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script> 
    <script type="text/javascript">
      $(document).ready(function(){
        $('form').submit(function(){
          var element = $(this);
          var names = [];
          element.find('input[type=checkbox]').each(function(i,o){
            names[names.length] = $(o).attr('name');
          });
          var value = names.join();
          var hidden = $('<input>').attr('type', 'hidden').attr('name', 'names').attr('value', value);
          element.append(hidden);
        });
      });
    </script>
  </head>
  <body>
    <?php
      $post_id = $_REQUEST['post_id'];
      if(!empty($post_id)){
        $names = $_REQUEST['names'];
        $names = explode(',', $names);
        foreach($names as $name){
          $value = $_REQUEST[$name];
          if($value != "on") $value = "off";
          print "$name:$value<br/>";
        }
      }
    ?>
    <form action="test.php" method="post">
      <input type="hidden" name="post_id" value="<?php echo md5(date('Hms').session_id()); ?>" />
      <table style="width:100%">
        <tr>
          <th>Name</th>
          <th>Option1</th>
          <th>Option2</th>
          </tr>
        <tr>
          <th>lili</th>
          <th><input type="checkbox" name="lili_1"></th>
          <th><input type="checkbox" name="lili_2"></th>
        </tr>
        <tr>
          <th>thor</th>
          <th><input type="checkbox" name="thor_1"></th>
          <th><input type="checkbox" name="thor_2"></th>
        </tr>
        <tr>
          <th>fred</th>
          <th><input type="checkbox" name="fred_1"></th>
          <th><input type="checkbox" name="fred_2"></th>
        </tr>
      </table>
      <button type="submit">Update</button>
    </form>
  </body>
</html>
itsben
  • 1,017
  • 1
  • 6
  • 11