2

I have a cck list(text) field. Widget: select I already have data in the database and I want to add a few more options to the select list. I've tried using hook_form_alter but I can't seem to change the options. Here is my code:

function color_cats_form_alter(&$form, &$form_state, $form_id) {  
    if ($form_id == "cats_node_form") { 
        $form['#after_build'][] = 'color_cats_after_build';
    }
}

function color_cats_after_build($form, &$form_state) {
    dsm($form);
    $form['field_color_cat']['und']['#options']['brown'] ='Brown';
    $form['field_color_cat']['und']['#options']['white'] ='White';
    $form['field_color_cat']['und']['#options']['gold'] ='Gold';
    $form['field_color_cat']['und']['#options']['grey'] ='Grey';
    $form['field_color_cat']['und']['#options']['tabby'] ='Tabby';
    $form['field_color_cat']['und']['#options']['ginger'] ='Ginger';
    $form['field_color_cat']['und']['#options']['multi-colored'] ='Multi Colored';
    return $form;
}

dsm($form) is showing so the function color_cats_after_build is being called. The issue is $form['field_color_cat']['und']['#options']['brown'] ='Brown'; is not affecting the select list. dsm($form) shows

field_color_cat (Array, 17 elements)
    #type (String, 9 characters ) container
    #attributes (Array, 1 element)
    #weight (String, 2 characters ) 16
    #tree (Boolean) TRUE
    #language (String, 3 characters ) und
    und (Array, 38 elements)
        #entity (Object) stdClass
        #entity_type (String, 4 characters ) node
        #bundle (String, 4 characters ) cats
        #field_name (String, 15 characters ) field_color_cat
        #language (String, 3 characters ) und
        #field_parents (Array, 0 elements)
        #columns (Array, 1 element)
        #title (String, 5 characters ) Color
        #description (String, 56 characters ) This is the old color selection and SHOULD NOT ...
        #required (Boolean) FALSE
        #delta (Integer) 0
        #type (String, 6 characters ) select
        #default_value (Array, 0 elements)
        #multiple (Boolean) FALSE
        #options (Array, 6 elements)
            _none (String, 8 characters ) - None -
            Black (String, 5 characters ) Black
            Brown (String, 5 characters ) Brown
            Gold (String, 4 characters ) Gold
            White (String, 5 characters ) White
            Multi Colored (String, 13 characters ) Multi Colored
        #value_key (String, 5 characters ) value
        #element_validate (Array, 1 element)
        #properties (Array, 4 elements)
        #after_build (Array, 1 element)
        #input (Boolean) TRUE
        #process (Array, 2 elements)
        #theme (String, 6 characters ) select
        #theme_wrappers (Array, 1 element)
        #pre_render (Array, 1 element)
        #defaults_loaded (Boolean) TRUE
        #tree (Boolean) TRUE
        #parents (Array, 2 elements)
        #array_parents (Array, 2 elements)
        #weight (Integer) 0
        #processed (Boolean) TRUE
        #attributes (Array, 0 elements)
        #title_display (String, 6 characters ) before
        #id (String, 24 characters ) edit-field-color-cat-und
        #name (String, 20 characters ) field_color_cat[und]
        #value (Array, 0 elements)
        #ajax_processed (Boolean) FALSE
        #sorted (Boolean) TRUE
        #after_build_done (Boolean) TRUE
    #access (Boolean) TRUE
    #theme_wrappers (Array, 1 element)
    #process (Array, 1 element)
    #defaults_loaded (Boolean) TRUE
    #parents (Array, 1 element)
    #array_parents (Array, 1 element)
    #processed (Boolean) TRUE
    #required (Boolean) FALSE
    #title_display (String, 6 characters ) before
    #id (String, 20 characters ) edit-field-color-cat
    #sorted (Boolean) TRUE

How do I add values to my select list?

Thanks

This is my code just using the hook_form_alter:

function color_cats_form_alter(&$form, &$form_state, $form_id) {  
if ($form_id == "cats_node_form") { 
$form['field_color_cat']['und']['#options'] = array(   
     'All' => t('- Any -'),
        'Black' => t('Black'),
        'Brown' => t('Brown'), 
        'White' => t('White'), 
        'Gold' => t('Gold'), 
        'Grey' => t('Grey'),
        'Tabby' => t('Tabby'),
        'Ginger' => t('Ginger'),
        'Multi Colored' => t('Multi Colored')
       ); }}

The select list is showing all the values and it works if I select an old value, but if I select a new value that I added eg ginger then I can the error message: color:illegal value.

4
  • You should directly change it in the form alter function rather than form after build funtion Commented Oct 9, 2013 at 13:13
  • I tried that originally and I couldn't get it to work. The issue may be The issue could be related to drupal.org/node/726282 Where it says Sometimes you need to set both ['value']['#value'] and ['#value']['value']. And other times you need to change the field value in $form_state['values']. It seems to be that one controls the value displayed on the form, and the other affects the value sent to the database. but I can't figure out what I would do in my case where I am using #options not #value.
    – LTech
    Commented Oct 10, 2013 at 7:07
  • how did you use the hook form alter? could you add that code in your question? Commented Oct 10, 2013 at 8:17
  • You don't say which version of Drupal you are using. cck makes me think you are using Drupal 6 but some people still use the term for Drupal 7.
    – tedbow
    Commented Jan 4, 2014 at 15:16

2 Answers 2

1

There are couple of ways to achieve this.

If you always want the options to come from the code then don't bother adding the allowed values field. Once you add this it would check to make sure that the values you enter is with in this allowed values field. so if you dont give the allowed values field and then use the form alter hook to populate the field as given below it should work fine without giving the "illegal value" error.

function color_cats_form_alter(&$form, &$form_state, $form_id) {  
    if ($form_id == "cats_node_form") { 
        $form['field_color_cat']['und']['#options'] = array(   
            'All' => t('- Any -'),
               'Black' => t('Black'),
               'Brown' => t('Brown'), 
               'White' => t('White'), 
              'Gold' => t('Gold'), 
               'Grey' => t('Grey'),
              'Tabby' => t('Tabby'),
             'Ginger' => t('Ginger'),
             'Multi Colored' => t('Multi Colored')
               ); 
        }
}

If you are particular about adding the allowed values field then the way is a bit more complicated. Here again I have found two way to go about it.

One is to use the php filter for the allowed values. For this you might have to add the CCK module just the core fields module might not cut it as the php filter option is not yet there in the core.

You can follow the below steps

  1. Enable Core module PHP Filter
  2. Set/Check user permissions: admin/people/permissions#module-php
  3. Set/Check Text Formats: admin/config/content/formats
  4. Enable CCK Module. Without CCK Module enabled you wont be able to enter (and thus execute) PHP-code in the Allowed-Values-List window as mentioned above.

Now you can add the options array with in the window and return the options array.

Something like given below

<?php
  $options = get_my_options();
  //(...);
  return $options;
?> 

Above method was suggested by clivesj on drupal forum

The second method is to directly edit the database. The allowed values are stored in the database table field_config. the column is data. This is a serialized array of settings. so you could read this and then add the additional values and then update the database as given below.

$sql = "SELECT id, data FROM {field_config} WHERE id=29";
$result = db_query($sql);
    // retrieve recordset
    while($data = $result->fetchObject()){
    $rev = unserialize($data->data);  // this becomes the string containing the BLOB data
}

$rev['settings']['allowed_values']['Multi Colored']=t('Multi Colored'); // add all the additional options here. 

$rev=serialize($rev);
$db_in = db_update('field_config') 
     -> fields(array(
                'data' => $rev
         ))
     ->condition('id', 29, '=')
     ->execute();
     cache_clear_all();

You would need to clear the cache to show the options. hence you would need to call the cache_clear_all(); function to clear the cache. you could also target the exact cache you want to clear that way the entire cache is not cleared.

This is a database intensive method hence you might want to read the allowed values and make sure that the values you are about to enter is not already there in the options list. if it is already there then you can skip adding that option and hence avoid reading and writing into the db.

3
  • what do you mean by 'don't bother adding the allowed values field'? How does you example code differ form my last code insert that I have in the question see under 'This is my code just using the hook_form_alter:' This was returning illegal:choice.
    – LTech
    Commented Oct 13, 2013 at 10:26
  • While creating the field there is an option to add the allowed values. Don't add the values there. Instead add it through code. When you add the allowed values it checks if the values you add is with in this values. IF you don't add it then it wont check that. Commented Oct 15, 2013 at 5:06
  • If you can avoid it you should not use the PHP filter. It is a major security risk. See reason here drupal.stackexchange.com/questions/2509/…
    – tedbow
    Commented Jan 4, 2014 at 15:19
0

Try this, adding it to the hook_form_alter rather than your #after_build function, since (and I took this directly from the Form API) "An array of function names which will be called after the form or element is built." and it's hard to modify a form after it's been built.

function color_cats_form_alter(&$form, &$form_state, $form_id)
{
    if ($form_id == "cats_node_form")
    {
        $form['field_color_cat']['und']['#options']['brown'] ='Brown';
        $form['field_color_cat']['und']['#options']['white'] ='White';
        $form['field_color_cat']['und']['#options']['gold'] ='Gold';
        $form['field_color_cat']['und']['#options']['grey'] ='Grey';
        $form['field_color_cat']['und']['#options']['tabby'] ='Tabby';
        $form['field_color_cat']['und']['#options']['ginger'] ='Ginger';
        $form['field_color_cat']['und']['#options']['multi-colored'] ='Multi Colored';
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.