简体   繁体   English

drupal表单提交的问题,其复选框的值为0

[英]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. 我正在编写一个drupal模块,它涉及一个包含许多复选框的表单。 Eg 例如

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

I have made the key for these checkboxes numeric, starting with 0. Eg 我已将这些复选框的密钥设为数字,从0开始。例如

$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. 在实现myform_checkboxes_submit函数后,我发现很难解释用户输入的内容。 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. $ checked变量是一个仅包含已选中复选框的数组。 The only problem is that the value 0 (representing the 0th checkbox) is always included in $checked, whether it was actually checked or not. 唯一的问题是值0(代表第0个复选框)始终包含在$ checked中,无论是否实际检查过。

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?) (相关的红利问题:是否有更简单的方法从drupal表单变量中获取用户的复选框?)

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. 由于未选中复选框返回的值为0,如果使用0作为返回值,则无法识别已检查状态。 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). 所以你的问题的直接答案是没有最好的方法,只是因为没有办法(除了Jeremy建议的js解决方法,这对于一个简单的问题来说是一个非常复杂的解决方案)。

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. 因此,如果您需要将结果数组从索引0开始,则在构建表单选项时必须暂时删除0条目,并在提取结果后将其重新置入。 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. 一种简单的方法是使用-1(或数组其余部分未使用的任何其他值)作为0的占位符,在提取选中的值后再次替换它。

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? 看看你的例子,你为什么不用你的显示值(0:00,1:00,...)作为键/返回值呢? 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). 它检查数组中是否为0,如果它不是第一项,那么它必须是最后一项(当用户没有选中对应于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. 您可以使用JS提交处理程序来检查复选框的已检查状态,并将值放入隐藏字段中。

You would then need to use a Drupal form handler to decode the values on the other end. 然后,您需要使用Drupal表单处理程序来解码另一端的值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM