Search code examples
phparraysdrupaldrupal-6

Drupal 6 forms and optgroup arrays


The following array is produced by converting xml to a array (using xml2array). However its not the exactly the right format I need for a optgroup in a Drupal 6 form.

Array (
   [root] => Array ([attr] => Array ([id] => 1) [label] => Array ([value] => My Root)
      [node] => Array (
         [0] => Array ([attr] => Array([id] => 2) [label] => Array([value] => Category 1)
            [node] => Array(
               [0] => Array ([attr] => Array ([id] => 14) [label] => Array ([value] => Sub-Category 1))
               [1] => Array([attr] => Array ([id] => 15) [label] => Array([value] => Sub-Category2))

I think the array has too be reduced to this format with id values intact for the sub-categories. However I can't confirm this with the drupal docs as they don't mention anything about assigning values to a option.

Array (
   [Category 1] => Array(
      [14] => Sub-Category 1
      [15] => Sub-Category 2
   )
)

So my questions are 1) is what is the correct array format for Drupal optgroups with my specified values and 2) how do I reduce my array to match?


Solution

  • 1) The correct format for an option group array is (I will use a list of states as an example):

    $state_list = array(
      'AL'=>"Alabama",  
      'AK'=>"Alaska",  
      'AZ'=>"Arizona",  
      'AR'=>"Arkansas",
      ...
    );
    

    This would display a list of the state names, accessible by the state initials as keys.

    In order to use subgroups, you would modify the above like:

    $state_list = array(
      'A'=> array(
        'AL'=>"Alabama",  
        'AK'=>"Alaska",  
        'AZ'=>"Arizona",  
        'AR'=>"Arkansas",
        ...
      ),
      'C'=> array(
        'CA'=>'California',
        'CO'=>'Colorado',
         ...
      ),
      ...
    );
    

    So, you would need the following format for your translated data as given:

    $options = array(
      'My Root' => array(
        'Category 1' => array(
          '14' => 'Sub-Category 1',
          '15' => 'Sub-Category 2'
        )
      )
    )
    

    However, if 'My Root' is the name of the select element, use this instead (I'll show you a form definition for each one below):

    $options = array(
      'Category 1' => array(
        '14' => 'Sub-Category 1',
        '15' => 'Sub-Category 2'
       )
    )
    

    Your forms API definition would look like this:

    function mymodule_form() {
      $options = array(
        'My Root' => array(
          'Category 1' => array(
            '14' => 'Sub-Category 1',
            '15' => 'Sub-Category 2'
          )
        )
      );
      ...
      $form['Select Box Name'] = array(
        '#type' => 'select',
        '#title' => 'Select a Category',
        '#options'=> $options,
      );
      ...
      return $form;
    }
    

    Or like this, if 'My Root' is the name of the select element and not one of it's categories:

    function mymodule_form() {
      $options = array(
        'Category 1' => array(
          '14' => 'Sub-Category 1',
          '15' => 'Sub-Category 2'
         )
      );
      ...
      $form['My Root'] = array(
        '#type' => 'select',
        '#title' => 'Select a Category',
        '#options'=> $options,
      );
      ...
      return $form;
    }
    

    In this definition, your subcategories are keyed using integers - I am not sure this is what you want. Many times Drupal developers use arrays with identical keys and values (e.g. '[CA}=>[CA]') to make things easier.

    A side-effect of this format is that 'Category 1' is not itself selectable (since your XML source has keys for both 'Root' and "Category 1' it would seem to me that they were selectable in their previous incarnation); I am not sure if HTML option group sub-category labels even are, so I am not sure if this is a problem or not.