1

I have a form, and for every rows I have displayed it on my page. It also exists a checkbox for every item, and when I click on it then if it is unchecked, it comes checked and saves in db value 1 or value 0 otherwise. But I want to know how can I select multiple unchecked checkboxes and update all in my database, without taking them one to one. Any suggestions how to do that?

   $displayChecked = $row['publish'] == 1 ? 'checked' : '';
   $check = $row['publish'] == 1 ? 'true' : 'false';
   (...)
  <?php if ($check == "true") {echo "Publish";} else {echo "Unpublished";}?> 
   <input type="checkbox"  name="check" value = "<?php echo  $check; ?>" <?php echo $displayChecked; ?> OnClick="doAction(<?php echo $check;?>, <?php echo $id;?>);" > 

doAction:

 function doAction(check,id){
 $.ajax({

      type: "GET",
      url: "file.php",
      data: "check=" + check + "&id=" + id,
      success: function(msg){
                 alert( "Data Saved: " + msg );
               }
 });
 }

file.php

 <?php 
 require_once("connectionfile.php");

        $id = $_GET['id'];
        $check = $_GET['check'];
        if ($check == "false"){
            $query = mysql_query("update article set publish = 1 where id =" . $id);

            echo "Published";
        }
        else {
            $query = mysql_query("update article set publish = 0 where id =" . $id);
            echo "Unpublished";
        }

 ?>
codewitharefin
  • 1,398
  • 15
  • 24
chi
  • 357
  • 3
  • 15
  • 1
    I can't understand what you mean. Do you mean to make a checkbox that if checked checks all the checkboxes on the page and update the DB for all the checkboxes? – SyncroIT Jul 29 '16 at 14:25
  • 1
    I think he means bulk update. As in select multiple checkboxes and submit, in one way or another, all of them at once. As it stands he's doing one update for one checkbox. Given that that's what OP wants, it's fairly trivial to achieve. But OP has to clarify that first. – Andrei Jul 29 '16 at 14:27
  • 3
    avoid using deprecated `mysql_*` functions. – DirtyBit Jul 29 '16 at 14:28
  • @Adiiia I don't have the time right now, but if you're in no hurry, I'll answer your question in ~1 hour. – Andrei Jul 29 '16 at 14:41
  • it's okay, thank you – chi Jul 29 '16 at 14:44

3 Answers3

0

Instead of a single id, pass an array of currently checked ids to your doAction and loop over them in your file.php.

Abrucius
  • 101
  • 6
0

You can construct one string with all the check-states and another string with all the ids. Let's create the new function "saveAll" :

function saveAll () {   // ◄■■■■■ PARAMETERS UNNECESSARY.
// CONSTRUCT STRINGS WITH CHECKS AND IDS OF ALL THE CHECKBOXES.
  var checkboxes = $("[name=check]"); // ARRAY OF CHECKBOXES NAMED "CHECK".
  var checks = ""; // EXAMPLE : "0,1,1,0,0," (COMMA SEPARATED).
  var ids = ""; // EXAMPLE : "2,14,21,33,40," (COMMA SEPARATED).
  for ( i = 0; i < checkboxes.length; i++ )
  { checks += ( checkboxes[ i ].checked ) ? "1," : "0,"; // COMMA SEPARATED.
    ids += checkboxes[ i ].id + ","; // COMMA SEPARATED.
  }
 $.ajax({
      type: "GET",
      url: "save_all.php",  // ◄■■■■■ NEW PHP CODE.
      data: "checks=" + checks + "&ids=" + ids,  // ◄■■■■■ PLURAL VARIABLES.
      success: function(msg){
                 alert( "Data Saved: " + msg );
               }
 });
 }

Right now you are displaying the checkboxes with the IDs as parameter for "doAction":

   <input type="checkbox"  name="check" value = "<?php echo  $check; ?>"
          <?php echo $displayChecked; ?>
          OnClick="doAction(<?php echo $check;?>, <?php echo $id;?>);" >   ◄■■■■■

Notice the new function "saveAll" requires that the checkboxes have "name" and "id", so let's change a little the previous block of code:

   <input type="checkbox"  name="check" value = "<?php echo  $check; ?>"
          <?php echo $displayChecked; ?>   id="<?php echo $id;?>"  ◄■■■■■
          OnClick="doAction(<?php echo $check;?>, <?php echo $id;?>);" > 

Now the new function "saveAll" can get all the check-states an all the ids of the checkboxes, construct strings with them and send them to the new PHP code "save_all.php", that looks like this:

<?php
if ( isset( $_GET["checks"] ) && isset( $_GET["ids"] ) )
   { $checks = explode( ",", $_GET["checks"] ); // IGNORE LAST ITEM.
     $ids    = explode( ",", $_GET["ids"]    ); // IGNORE LAST ITEM.
     for ( $i = 0; $i < (count( $ids )-1); $i++ )
        $query = mysql_query("update article set publish=" .
                             $checks[$i] . " where id=" . $ids[$i] );
   }
?>

$checks and $ids are arrays. We have to ignore the last element of each array because the strings end with commas, so the last item is empty.

Now, you only need a button to make everything work :

<button onclick="saveAll()">Save all</button>
0

You should avoid using mysql_* functions since they are deprecated from PHP 5.5.x and will be removed in the future.

I really suggest moving towards PDO as it is more OOP or if you prefer the old procedural way then mysqli is the way to go.


Now, with that said:

Lets start with the html/javascript part:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title be here</title>

    <script src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
</head>
<body>
    <form action="" method="post" id="_form">
        <div class="row">
            <?php for($i = 1; $i <= 10; $i++):?>
            <label for="id_<?php echo $i; ?>">Checkbox <?php echo $i; ?></label>
            <input type="checkbox" id="id_<?php echo $i; ?>" name="ids[<?php echo $i; ?>]"><!-- here we assume $i is $id -->
            <br />
            <?php endfor; ?>
            <input type="submit" value="Submit" name="submit" id="_submit">
        </div>
    </form>


    <script type="text/javascript">
        $(document).ready(function(){

            $('#_submit').on('click', function(e){
                e.preventDefault();

                $.ajax({
                    type: "post",
                    url: "file.php",
                    data: $('#_form').serialize(),
                    success: function(data){
                        if(data.success == true){
                            // do stuff here
                        }else{
                            // do other stuff here
                        }
                    }
                });
            });
        });
    </script>
</body>
</html>

And lets continue with the PHP part:

<?php

if(isset($_POST['ids']))
{
    $input = $_POST['ids'];

    // Lets take care of the query here

    $query = ' UPDATE `article` SET `publish` = CASE';

    foreach($input as $key => $value)
    {
        $query .= ' WHEN `id` = ' . /* typecast to int just in case */ (int) $key . ' THEN ';
        if($value == 'on')
        {
            $query .= '1';
        }
        else
        {
            $query .= '0';
        }
    }

    $query .= ' END WHERE `id` IN (' . implode(',', array_keys($input)) . ')';

    // update stuff using the database handler here

    // return a json response here or just echo out whatever you need
}
else
{
    // return a response here
}

Notice that I've placed name="ids[<?php echo $i; ?>]" as an array. Php will actually interpret that as an array, and it will look like this:

Array
(
    [2] => on
    [4] => on
    [5] => on
    [6] => on
    [7] => on
    [8] => on
)

Note that the keys are not random, they are our ids.

However, you'll also note that some ids are missing, namely the ones that didn't have the checkbox checked. That would be a problem. A simple workaround would be to do the following:

<input type="hidden" name="ids[<?php echo $i; ?>]" value="off">
<!-- Add a hidden filed with the exact same id BUT with off as a value -->
<!-- In case the user checks the checkbox, then it will overwrite the hidden field -->
<!-- The order of the fields in very important here. Hidden field MUST come first -->

<input type="checkbox" id="id_<?php echo $i; ?>" name="ids[<?php echo $i; ?>]"><!-- here we assume $i is $id -->

So now our array looks like this:

Array
(
    [1] => off
    [2] => off
    [3] => off
    [4] => off
    [5] => on
    [6] => off
    [7] => off
    [8] => on
    [9] => off
    [10] => off
)

From there on it's a simple matter of building the query and updating the table.

The query will look something like this:

UPDATE `article` SET `publish` = CASE WHEN `id` = 4 THEN 1 WHEN `id` = 5 THEN 1 WHEN `id` = 6 THEN 1 END WHERE `id` IN (4,5,6)

Which will allow you to update all the records in one go without looping over the results and without being forced to execute one query for each checkbox.


As for the front-end part as the user experience, I suppose you could simply flash an alert when the update is done and successful, otherwise just display an error.

Community
  • 1
  • 1
Andrei
  • 3,434
  • 5
  • 21
  • 44