2009-11-17 31 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; 
}