UPDATE: Select list saves data, changed the way it was attached to ajax.. Multiselect form thats gets populated once ajax fires, those values are empty upon node save.

I'm using hook form alter to do 2 things. First I'm adding an ajax callback on a select list. Based upon the selection I'm calling a function to pull in data that I'm then using to populate the multiselect list.

All is visually working fine and the data is properly going in as a key => value for the multiselect.

The problem I'm having right now is when I submit the form those form values set for multiselect are not saved with the node.

This is Drupal 7.. am I missing something.. do I need to programmatically populate the fields, do I need to do something with #after_build


  • Hook form alter
  • -- overriding 2 form elements
  • --- 1 select list with ajax call back
  • --- 2 Multiselect with key value data added based upon the results from the select list

  • ajax callback function that returns the $form

  • function to pull in the data I need for the multi select.


code: hook form alter block

 * Implements hook_form_alter().
function lm_groups_form_alter(&$form, $form_state, $form_id) {

  if($form_id == 'group_node_form') {

    // ajax callback for org type value to populate help populate tags multiselect
    $group_type = isset($form_state['values']['field_group_type']) ? $form_state['values']['field_group_type'] : NULL;
    // return select list array for multiselect to filter tags by group type
    if($group_type != NULL) {
      // function to return key => value from a custom view
      $tags = lm_groups_get_likemojis($group_type['und'][0]['tid'], TRUE);
    } else {
      $tags[0] = NULL;


    // Add Ajax callback to parent field.
    $form['field_group_type'][LANGUAGE_NONE]['#ajax'] = array(
        'callback' => 'lm_groups_ajax_callback',
        'wrapper' => 'checkboxes-div',

    $form['field_group_tags'] = array(
      '#prefix' => '<div id="checkboxes-div">',
      '#suffix' => '</div>',
      '#type' => 'multiselect',
      '#title' => t('tags'),
      '#options' => $tags,
      '#default_value' => _lm_groups_options(),
      '#multiple' => TRUE,
      '#size' => 15,
      '#weight' => 3,
      '#required' => TRUE,

    $form['#attached']['css'] = array(
      drupal_get_path('module', 'multiselect') . '/multiselect.css',

    $form['#attached']['js'] = array(
      drupal_get_path('module', 'multiselect') . '/multiselect.js',


2 blocks of code, one to pull in (eventually default values for the multi select on edit node)

function _lm_groups_options() {
  return variable_get('multiselector', array());

function lm_groups_ajax_callback($form, $form_state) {  
  return $form['field_group_tags'];

The callback is for the multiselect to prep it for values from the function below which just pulls some data from a view and provides the key->value for select lists.

The key is on the callback the form $group_type is set which calls the function lm_groups_get_tags the below function.

// function to get key->value from a view and some extra magic I need for the display name
function lm_groups_get_tags($tid, $filter = FALSE) {
  // custom view = tags Filter Tax which contains a tid argument that can be passed in.
  $data = views_get_view_result('tags_filter_tax', $display_id = NULL, $tid);

  foreach($data as $key => $value) {
    $nid = (int)$value->nid;
    // show tags filters on select lists if set to TRUE
    if($filter == TRUE) {
      // get taxonomy id out of the array, check if we had more than one filter
      $tids = $value->_field_data['nid']['entity']->field_filters['und'];

      foreach($tids as $key => $value2) {
        $name = taxonomy_term_load($value2['tid']);
        $filters[] = $name->name;       
      // build the actual output for the title including filters in ( )
      $title = trim($value->node_title) . ' - (' . implode(",",$filters) . ')';      unset($filters);
    } else {
      $title = trim($value->node_title);
    $tags[$nid] = $title;

  return $tags;

Visually in the form as stated above, the select list has an ajax callback, and multiselect form is populated.. when I submit this and look at the node on presave or just devel both field_group_tags are empty..

Please note these are already set up on the content type as a select list and a multiselect, im just over-riding and hoping to get the values to save.

excuse the mess :P

  • Maybe post the code? It would be easier to see whats going on. – Veez Jul 20 '17 at 22:47

The values won't automatically be saved. You need to created database tables using hook_schema() in an .install file, then save those values manually in hook_node_insert() and hook_node_update().

Or, if I recall correctly, you can add the fields to the {node} table in hook_install(), define the fields in hook_schema_alter(), and use hook_update_n() to actually add the fields since it sounds like your site is already up and running. Then, if you name the form keys with the same names as the columns you created, they should automatically save and update.

  • hmm, Im not creating a brand new form in the module, this is hooking into an existing content type. So for example, I have My List - field type list - Widget Select list.. and its field is field_my_list in the content type.. then in my hook form alter im adding an ajax callback to field_my_list .. my thoughts would be since this is already created as a db field that hook_form_alter would save the value upon submit.. Unless I need to set some values like $form['somefield']['und'][0]['value] = some value.. but not sure if thats needed ? – Steve Jul 20 '17 at 23:05
  • Ahh you didn't mention in the original post hat you're working with already existing fields. Yeah, you'll have to set your form keys differently. Analyze the structure of the definition of a different field to get an idea of how to do it. – Jaypan Jul 20 '17 at 23:29
  • thats where im stuck, any suggestions, I posted the code now. – Steve Jul 20 '17 at 23:36
  • Do those fields already exist on the node type you are editing? Or do they exist on a different node or entity? – Jaypan Jul 20 '17 at 23:53
  • Yea. content type group has those fields and thats what im targeting in hook_form_alter.. – Steve Jul 21 '17 at 0:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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