English 中文(简体)
Issues with a drupal form submission with a checkbox whose value is 0
原标题:

I am writing a drupal module that involves a form with many checkboxes. E.g.

$form[ myform_checkboxes ] = array( #type  =>  checkboxes , ...)

I have made the key for these checkboxes numeric, starting with 0. E.g.

$form[ myform_checkboxes ][ #options ][0] =  0:00 ;
$form[ myform_checkboxes ][ #options ][1] =  1:00 ;

Upon implementing the myform_checkboxes_submit function, I have discovered that it is difficult to interpret what the user s input was. On the interwebs, I found a few nice lines of code that did what I needed.

$checked = array_intersect(
  array_keys($form_state[ values ][ myform_checkboxes ]),
  array_values($form_state[ values ][ myform_checkboxes ])
);

This seems to work great; the $checked variable is an array including only the checked checkboxes. The only problem is that the value 0 (representing the 0th checkbox) is always included in $checked, whether it was actually checked or not.

Also useful to note: the zero appears first in the list if it is was checked, but last if it is not.

What would be the best way to resolve this situation, assuming that changing the indexing of the checkboxes were out of the question? (Related bonus question: is there an easier way to get the user s checked boxes from the drupal form variables?)

最佳回答

As the value returned by an unchecked checkbox is 0, there is no way to recognize the checked state if you use 0 as the return value for that also. So the immediate answer to your question is that there is no best way, simply because there is no way (apart from a js workaround as suggested by Jeremy, which would be a pretty complicated solution to a simple problem).

So if you need your result array to start with index 0, you will have to get rid of the 0 entry temporarily when building the form options, putting it back in after extracting the results. An easy way to do this would be to use -1 (or any other value not used in the rest of the array) as a placeholder for 0, replacing it again after extracting the checked values.

Another obvious solution would be reindexing, as mentioned by Jeremy. Looking at your example, why don t you just use your display values (0:00, 1:00, ...) as keys/return values also? No ambiguity there, and easy to convert to integers, if need be.

问题回答

Actually, what I ended up doing was this.

if (in_array(0, $checked) && $checked[0] != 0) {
  unset($checked[count($checked) - 1]);
}

It checks if 0 is in the array, and if it s not the first item, then it must be the last (this happens when the user doesn t check the box corresponding to 0). So it removes that item from the array, since it was not checked. Not ideal or pretty, but it made sense for my situation.

In most other situations (and perhaps in mine), as has been pointed out, re-indexing would be better.

EDIT: for anyone who cares, this is the helper function I ended up creating for myself (comments included).

function _mymodule_get_checked_checkboxes(&$form_state, $table) {

  // Discover which boxes were checked.
  $checked = array_intersect(array_keys($form_state[ values ][$table]),
                          array_values($form_state[ values ][$table]));

  // The key  0  is included in the first position if it was selected,
  //  and in the last if it was not.
  //  this is how checkboxes return their data.
  //  However, we don t want 0 to be in the array
  //  therefore, we remove it if 0 is found to be in the last position
  $num_checked = count($checked);
  if ($checked[0] != 0 && $checked[$num_checked - 1] == 0) {
    unset($checked[count($checked) - 1]);
  }
  // It also happens if nothing is selected.
  // In the case that only 0 is selected, assume otherwise.
  else if ($num_checked == 1 && $checked[0] == 0) {
    unset($checked[0]);
  }

  sort($checked);
  return $checked;
}

You could use a JS submit handler to check the checked state of the checkboxes and put the values into a hidden field.

You would then need to use a Drupal form handler to decode the values on the other end.





相关问题
Brute-force/DoS prevention in PHP [closed]

I am trying to write a script to prevent brute-force login attempts in a website I m building. The logic goes something like this: User sends login information. Check if username and password is ...

please can anyone check this while loop and if condition

<?php $con=mysql_connect("localhost","mts","mts"); if(!con) { die( unable to connect . mysql_error()); } mysql_select_db("mts",$con); /* date_default_timezone_set ("Asia/Calcutta"); $date = ...

定值美元

如何确认来自正确来源的数字。

Generating a drop down list of timezones with PHP

Most sites need some way to show the dates on the site in the users preferred timezone. Below are two lists that I found and then one method using the built in PHP DateTime class in PHP 5. I need ...

Text as watermarking in PHP

I want to create text as a watermark for an image. the water mark should have the following properties front: Impact color: white opacity: 31% Font style: regular, bold Bevel and Emboss size: 30 ...

How does php cast boolean variables?

How does php cast boolean variables? I was trying to save a boolean value to an array: $result["Users"]["is_login"] = true; but when I use debug the is_login value is blank. and when I do ...

热门标签