29

I have a form like below :

<form action="" method="post">
    <input type="checkbox" id="status_1" name="status_1" value="1" />
    <input type="checkbox" id="status_2" name="status_2" value="1" />
    <input type="checkbox" id="status_3" name="status_3" value="1" />
</form>

When i check all checkbox and post the form, the result is like this:

Array ([status_3] => 1 [status_2] => 1 [status_1] => 1 ) 

Then i uncheck second checkbox and post the form, the result is like this:

Array ( [status_3] => 1 [status_1] => 1 ) 

Is it possible to make result like this below when i uncheck second checkbox :

Array ( [status_3] => 1 [status_2] => 0 [status_1] => 1 ) 

There are ideas to do it?

Zoe
  • 27,060
  • 21
  • 118
  • 148
Fredy
  • 2,840
  • 6
  • 29
  • 40

11 Answers11

50

First way - hidden fields (disadvantage: the user can manipulate the value of the field (but one can manipulate the value of the checkbox too, so it's not really a problem, if you only expect 1 or 0))

<form action="" method="post">
<input type="hidden" name="status_1" value="0" />
<input type="checkbox" id="status_1" name="status_1" value="1" />
<input type="hidden" name="status_2" value="0" />
<input type="checkbox" id="status_2" name="status_2" value="1" />
<input type="hidden" name="status_3" value="0" />
<input type="checkbox" id="status_3" name="status_3" value="1" />
<input type="submit" />
</form>
<?php
var_dump($_POST);
/*
 * checking only the second box outputs:
 * 
 * array (size=3)
  'status_1' => string '0' (length=1)
  'status_2' => string '1' (length=1)
  'status_3' => string '0' (length=1)
 */

Second way - to assign default value for non-set indexes:

<form action="" method="post">
<input type="checkbox" id="status_1" name="status_1" value="1" />
<input type="checkbox" id="status_2" name="status_2" value="1" />
<input type="checkbox" id="status_3" name="status_3" value="1" />
<input type="submit" />
</form>
<?php
for($i = 1; $i<=count($_POST); $i++) {
    $_POST["status_$i"] = isset($_POST["status_$i"]) ? $_POST["status_$i"] : 0;
}
var_dump($_POST);

/**
 * Here we will be checking only the third checkbox:
 * 
 * array (size=3)
  'status_3' => string '1' (length=1)
  'status_1' => int 0
  'status_2' => int 0
 */
Royal Bg
  • 6,988
  • 1
  • 18
  • 24
  • 1
    Worth noting that a) the first technique is just about the only way if you want the server side to properly recover all the from inputs without additional, pre-established knowledge about them (see e.g. dynamically generated forms on the client side), and b) duplicate name values are fine with the specs (although I couldn't find a *normative* place in the spec to just link to, but see e.g. here: https://html.spec.whatwg.org/multipage/forms.html#naming-form-controls:-the-name-attribute). – Sz. Jan 27 '16 at 12:44
  • @Royal Bg Is there any priority based thing happening here? I mean if value of checkbox is set, how is it deciding that which value to take(checkbox or hidden input)? – hellodear Apr 08 '16 at 07:03
  • 1
    Yes, the priority depends on how they are sent to server. Basically in HTML form, they are sent successively. From the first input to the last. This means first the hidden field will be send, then the checkbox if present. If the checkbox is not sent, the hidden will take place. But if the checkbox is sent, it will override the hidden field. If you change their places (e.g. first checkbox, then hidden), then only the hidden field override the checkbox. – Royal Bg Apr 08 '16 at 08:42
  • Yes. that's the problem. It was opposite in my case. When I am keeping it opposite (first checkbox, then hidden) then it was working fine for me. I am writing jsp file. Can you please explain something about this? – hellodear Apr 08 '16 at 08:50
  • This could be because of the framework. I guess the hashtable in the http request context does not support overriding values, but just does not put the second value. In the native scenario all `key=>value` pairs are sent, not matter of equal keys. How does the different frameworks handle duplicate keys and populate the request object is field specific. Isn't JSP dead already? – Royal Bg Apr 08 '16 at 11:11
  • When you said jsp dead already, u mean it is not used these days? Secondly, can you explain when you said "How does the different frameworks handle duplicate keys and populate the request object is field specific"? any example will work. Thanks for you valuable response. – hellodear Apr 08 '16 at 12:27
  • For example the php `$_REQUEST` uses standard hashtable overriding - the last `key=>value` pair with the same key is preserved. On the other side, it's possible the javax servlet implementation of `ServletRequest` to first check `containsKey(key)` before adding to the hashtable. To be honest, the default implementation does not provide specification of parameter order and collision resolution. There's a discussion here http://stackoverflow.com/questions/9813803/request-parameter-order-in-servlet-containers – Royal Bg Apr 08 '16 at 13:48
  • Important note: the HTTP request will contain both values if the checkbox is checked. – Basj May 13 '20 at 12:03
9

I think adding hidden fields like this will work

<input type="hidden" id="status_1_" name="status_1"  value="0">
<input type="checkbox" id="status_1" name="status_1" value="1" />

<input type="hidden" id="status_2_" name="status_2" value="0">
<input type="checkbox" id="status_2" name="status_2" value="1" />

<input type="hidden" id="status_3_" name="status_3" value="0">
<input type="checkbox" id="status_3" name="status_3" value="1" />
nithin
  • 449
  • 2
  • 5
  • 7
    Please keep in mind, that HTTP request will contain both values. It is the PHP parser what removes the first value. – Josef Kufner Jul 30 '14 at 16:01
  • @JosefKufner Thanks, you are correct. But this is the method used by many php frameworks like CakePHP. – nithin Aug 01 '14 at 07:25
  • 1
    I'm not saying that it is wrong. Only that it is important to know where the '0' value is lost, since it may cause some unexpected side-effects. – Josef Kufner Aug 01 '14 at 11:27
2

I thinks it impossible to get array like what you want from html forms. But this some tricks can be used:

$defaultForm = array(
'status_1' => 0,
'status_2' => 0,
'status_3' => 0, 
);

// example array from $_POST
$form = array(
'status_1' => 1,
'status_3' => 1, 
);

$form = array_merge($defaultForm, $form);

Result:

array(3) {

'status_1' => int(1)
'status_2' => int(0)
'status_3' => int(1)

}

Community
  • 1
  • 1
Somy A
  • 1,682
  • 15
  • 18
2

Try this. If the checkbox is not checked, then the hidden field with the same name will be passed instead.

<form action="" method="post">
  <input type="hidden" id="hidden_status_1" name="status_1" value="0" />
  <input type="checkbox" id="status_1" name="status_1" value="1" />
  <input type="hidden" id="hidden_status_2" name="status_2" value="0" />
  <input type="checkbox" id="status_2" name="status_2" value="1" />
  <input type="hidden" id="hidden_status_3" name="status_3" value="0" />
  <input type="checkbox" id="status_3" name="status_3" value="1" />
</form>
luttkens
  • 1,272
  • 8
  • 16
1

Thanks all. Thank to @RoyalBg give me solution. Like this :

<input type="hidden" name="status_1" value="0" />
<input type="checkbox" id="status_1" name="status_1" value="1" /> Check 1 <br />
<input type="hidden" name="status_2" value="0" /> 
<input type="checkbox" id="status_2" name="status_2" value="1" /> Check 2 <br />
<input type="hidden" name="status_3" value="0" />
<input type="checkbox" id="status_3" name="status_3" value="1" /> Check 3 <br />

It's work perfectly.. :)

Fredy
  • 2,840
  • 6
  • 29
  • 40
1

the question may already be answered but i just wanted to take a stab at it...server side only solution:

$p = $_POST;
$a = array();
$a['status_3'] = (int) ($p['status_3'] === 1);
$a['status_2'] = (int) ($p['status_2'] === 1);
$a['status_1'] = (int) ($p['status_1'] === 1);

Testing

 // if input is Array("status_1"=>1) output will be
 Array ( [status_1] => 1 [status_3] => 0 [status_2] => 0 )

 // if input is Array("status_1"=>1, "status_2"=>1) output will be
 Array ( [status_1] => 1 [status_3] => 0 [status_2] => 1)
Jay Harris
  • 4,201
  • 17
  • 21
1
<!--html code-->                                                                  
<input type="checkbox" name="correct" value="1">Option 1
<input type="checkbox" name="correct" value="2">Option 2
<input type="checkbox" name="correct" value="3">Option 3
<input type="checkbox" name="correct" value="4">Option 4                                   

//php code in function called on form submit       
  public function addOptions(Request $request)
   {
    $option = array('1' => 0,'2'=>0,'3'=>0,'4'=>0 );
    $option[$request->correct] = 1;
    return $option;
   }
0

Why have you taken it in an array? You can get the unchecked box as 0 by using "isset"

    if(!isset($_POST['status_2'])
    {
      //Set status_2 parameter as 0
    }
Ankur
  • 75
  • 2
  • 9
0

try below code

    $myresult = array();

    if(!isset($_POST['status_1'])){ 
        $myresult['status_1'] = 0;
    }
    if(!isset($_POST['status_2'])){ 
        $myresult['status_2'] = 0;
    }
    if(!isset($_POST['status_3'])){ 
        $myresult['status_3'] = 0;
    }

    echo "<pre>";
    print_r($myresult);
    echo "</pre>";
    exit;
Mandip Darji
  • 775
  • 4
  • 12
0

Try this one:

for ($i = 1; $i<=3; $i++) {
    $_POST["status_$i"] = isset($_POST["status_$i"]) ? $_POST["status_$i"] : 0; // 0 if not set
}

var_dump($_POST);
Jeroen Bellemans
  • 2,049
  • 2
  • 25
  • 42
M.Athish krishna
  • 227
  • 1
  • 2
  • 13
0

Assuming we are using checkboxes with zeros or ones...

Using a hidden checkbox with a zero value is just a work-around. Another work around would be to add 0 to the value when receiving the post or get.

Example:

$chkbx1 = $_POST['chckbx1']; $chkbx1 += 0;

This takes a NULL value an turns it into a zero, but if the value is one, as in its checked, then the value stays the same.

The real issue here isn't inventing a work-around. Its understanding why this is happening. Older versions of mySQL takes null values and converts them into a zero. In newer versions, you must disable strict mode and then a work-around is not needed.

tom
  • 1
  • Add the tags so that you will get answers faster. Add some tags on the tags text box - http://stackoverflow.com/questions/ask – Garfield Dec 09 '16 at 05:47