2009-11-17 32 views
1

我正在写一个涉及具有许多复选框的表单的drupal模块。例如。用值为0的复选框提交drupal表单的问题

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

我已经使这些复选框的数字从0开始。

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

实施此myform_checkboxes_submit功能,我发现,这是很难解释什么用户的输入了。在interwebs上,我发现了几行很好的代码,可以完成我所需要的功能。

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

这似乎工作得很好; $ checked变量是一个仅包含选中复选框的数组。唯一的问题是值0(代表第0个复选框)总是包含在$ checked中,无论它是否被实际检查。

同样有用的注意:如果它被选中,零将首先出现在列表中,但如果它没有被选中,则为零。

假设更改复选框的索引是不可能的,那么解决这种情况的最佳方法是什么? (相关的奖金问题:是否有一种更容易的方式从drupal表单变量中获取用户的选中框)

+0

我不明白你的意思_“我发现很难解释用户的输入是什么”_。你能否澄清你的意思,你想达到什么目的(例如:你能举一个'$ checked'应该是怎样的例子)? – mac

+0

我已经添加了一个答案,但我会说,重新索引数组是一个更好的主意。 'check0','check1'等等。我没有把这个作为答案,因为你在你的问题中明确拒绝了这个想法,但它会容易得多。 –

+0

@mac,我希望Drupal只是使用checked复选框键返回一个数组,而不需要使用array_intersect()来查找它们。 $ checked应该就是这样,一个选中的复选框数组。例如,$ checked == array(3,4,5)如果用户已经检查了3:00,4:00和5:00,并且没有别的。 –

回答

3

由于未检查返回的值复选框为0,如果您也使用0作为返回值,则无法识别已检查的状态。所以你的问题的直接答案是,没有最好的方式,只是因为有没有的方式(除了杰里米建议的js解决方法,这对于一个简单问题来说是一个非常复杂的解决方案)。

因此,如果您需要结果数组以索引0开始,那么在生成表单选项时必须暂时删除0条目,并在提取结果后将其重新放回。一个简单的方法是使用-1(或其他任何未在数组中使用的其他值)作为0的占位符,并在提取选中的值后再次替换它。如Jeremy所提到的,另一个明显的解决方案是重建索引。看看你的例子,你为什么不直接使用显示值(0:00,1:00,...)作为键/返回值呢?那里没有歧义,如果需要的话,很容易转换为整数。

+0

只是我需要的信息。由于稍后要执行的处理,我更愿意使用整数作为键。虽然它们很容易转换,但显示值将(最终)是动态的。将0键改为-1并返回可能是我最终要做的事情。 –

0

您可以使用JS提交处理程序来检查复选框的选中状态,并将值置于隐藏字段。

然后您需要使用Drupal表单处理程序来解码另一端的值。

1

其实,我最终做的是这样的。

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

它检查0是阵列中,并且如果它不是第一个项目,则它必须是最后一个(这发生在当用户不检查对应于0的框)。所以它从数组中删除该项,因为它没有被检查。不理想或漂亮,但对我的情况有意义。

正如已经指出的那样,在大多数其他情况下(也许在我的情况下),重新索引会更好。

编辑:任何关心的人,这是我最终为自己创建的帮助函数(包括注释)。

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; 
}