I have a content type "event" with a field called "field_pricelist". It's a dropdown with no values, I add the values when I alter the form. The values come from a custom table (install / schema) in my database. I want to save this custom value on insert/update. My code works but I don't think it's the best way to save/update a custom field.. Any suggestions?

function TableManager_form_alter(&$form, &$form_state, $form_id){
if ($form_id == 'event_node_form') {

global $user;
$query = db_select('pricelist', 'p');
$query->fields('p');
$query->condition('user_id', $user->uid,'=');
$results = $query->execute()->fetchAll();

$query2 = db_select('field_data_field_pricelist', 'd');
$query2->fields('d');
$query2->condition('entity_id', $form['nid']['#value'],'=');
$results2 = $query2->execute()->fetchAll();

$dropdown_array = array();
foreach ($results as $r) {
    $form['field_pricelist']['und']['#options'][$r->pricelist_id] = $r->pricelist_name;
}
$form['field_pricelist']['und']['#default_value']['0'] = $results2['0']->field_pricelist_value;
$form['#submit'][] = "TableManager_form_submit";
}

}

function TableManager_form_submit($form, &$form_state) {

global $user;

$nid = $form_state['values']['nid'];
$pricelist_id = $form_state['values']['field_pricelist']['und']['0']['value'];

$query = db_update('field_data_field_pricelist');// Table name no longer needs {}
$query->fields(array('field_pricelist_value' => $pricelist_id));
$query->condition('entity_id', $nid, '=');
$query->execute();
}
  • Any reason why don't you 1) just add form element on alter, whole, both element itself and it's data; or 2) provide custom field with all that logic enclosed in field itself? – Mołot Jul 9 '14 at 7:24

Try this...

function TableManager_form_alter(&$form, &$form_state, $form_id) {

  if ($form_id == 'event_node_form') {

    global $user;
    $query = db_select('pricelist', 'p');
    $query->fields('p', array('pricelist_id', 'pricelist_name'));
    $query->condition('user_id', $user->uid);
    $results = $query->execute()->FetchAllKeyed(0,1);

    $results['_none'] = "-Select-";

    $query2 = db_select('field_data_field_pricelist', 'd');
    $query2->fields('d', array('field_pricelist_value'));
    $query2->condition('entity_id', $form['nid']['#value']);
    $results2 = $query2->execute()->fetchField();

    if(empty($results2)) {
      $results2['_none']="-Select-";
    }

    $form['field_pricelist'][LANGUAGE_NONE]['#options'] = $results;
    $form['field_pricelist'][LANGUAGE_NONE]['#default_value'] = $results2;

   // $form['#submit'][] = "TableManager_form_submit";  // No longer need of this function

  }

}

You were done well node form alter but for submitting you need to use hook_node_submit() this is the best way.

https://api.drupal.org/api/drupal/modules%21node%21node.api.php/function/hook_node_submit/7.x

(i.e)

function hook_node_submit($node, $form, &$form_state) {

    if($node->type == 'node_machine_name') {
        //your code..
    }
}

Thank You.

I'd use allowed_values_function property, rather than feeding it in hook_form_alter. So, select field comes with this special property known as 'allowed_values_function'. This property can't be assigned through Drupal UI, but it can be assigned programmatically. What you need to do is to:

Declare hook_update function in your install module file (TableManager.install):

function TableManager_update_7001() {
  // Get the field info
  $field = field_info_field('field_pricelist');
  $field['settings']['allowed_values'] = '';
  $field['settings']['allowed_values_function'] = 'TableManager_field_pricelist_allowed_values';

  // Save the field
  field_update_field($field);
}

Write up your custom code that's going to return an array of values that field should have. Within your TableManager.module file it'd be that easy:

function TableManager_field_pricelist_allowed_values() {
  $list = array();
  // your logic to get the values
  // example list that needs to be returned
  // $list = array(
  //   'pc1' => t('Pricelist 1'),
  //   'pc2' => t('Pricelist 2'),
  //   'pc3' => t('Pricelist 3'),
  // );
  return $list;
}

After that you'll need to run update.php or drush updb (if you're using) and you should be good to go. Your field is going to be updated, so it's gonna use your function.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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