I have two fields in question, field_in and field_cm. The user is presented with one or the other (based on roles rule only one filed is shown, the other one is hidden). The form is created via admin - a custom content type form.

Problem: trying to populate the hidden field based on the user input in the visible field - the value is not saving to the db.

I added a custom submit function to the normal node_form_submit to handle the calculation, but it does not seem to add data - I do not see anything in the db. What am I doing wrong?

<?php
/**
* Implements hook_form().
*/
function my_module_form_alter(&$form, &$form_state, $form_id) {
  if(
$form_id == 'reading_node_form') {
    
$form['actions']['submit'] = array(
   
'#type' => 'submit',
   
'#value' => t('Add Reading'),
   
'#weight' => 50,
     
'#ajax' => array(
       
'wrapper' => 'reading-node-form',
       
'callback' => 'my_module_callback',
       
'clear' => TRUE,
       
'effect' => 'fade'
   
),
   
'#submit' => array('calculate_values_submit','node_form_submit'),
    );
}
  return
$form;
}
function
my_module_callback($form, &$form_state) {
 
$node = new stdClass();
 
$node->type = 'reading';
  return
drupal_get_form('node_form', $node);
}
function
calculate_values_submit($form_id, &$form_state) {
 
$form_state['rebuild'] = TRUE;
  if (!empty(
$form_state['values']['field_in'])) {
    
$form_state['values']['field_cm'] = $form_state['values']['field_in'] * 2.54;
  }
  else {
    
$form_state['values']['field_in'] = $form_state['values']['field_cm'] / 2.54;
  }
  }
?>

Comments

If you are trying to change the values saved as part of a node I believe you want to use hook_node_presave().

Well, not quite...I am just trying to modify some values on submit - to see if the value of the field is blank, and if so, populate it with a calculation based on the value in the populated field. This is a basic submit function, but I am not sure why it does not work.

If you do your calculations in a validate function instead of a submit function it will probably work

Changed it to validate - same issue. The db is not populated. It seems to be a very simple thing - add some calculation on the user-input values after validating the form, but before saving it to the db. Once the values are modified, then save the updated values. Is there an error somewhere in my code? This is the updated code:

<?php
/**
* Implements hook_form().
*/
function my_module_form_alter(&$form, &$form_state, $form_id) {
  if(
$form_id == 'reading_node_form') {
    
//debug($form);
     // $form['warning'] = array(
     // '#markup' => t('Testing to see if the message shows up!'),
     // '#weight' => -1
     // );
    
$form['actions']['submit'] = array(
   
'#type' => 'submit',
   
'#value' => t('Add Reading'),
   
'#weight' => 50,
     
'#ajax' => array(
       
'wrapper' => 'reading-node-form',
       
'callback' => 'my_module_callback',
       
'clear' => TRUE,
       
'effect' => 'fade'
       
),
   
'#submit' => 'node_form_submit',
   
'#validate' => array('calculate_values_validate','node_form_validate'),
    );
}
  return
$form;
}
// rebuilds form
function my_module_callback($form, &$form_state) {
 
$node = new stdClass();
 
$node->type = 'reading';
  return
drupal_get_form('node_form', $node);
}
// if field_in is empty, then it is filled by dividing the value from field_cm by 2.54
// if field_cm is empty, then it is filled by multiplying the value from field_in by 2.54
// for some reason, the results of the calculation do not get inserted into the db
function calculate_values_validate($form_id, &$form_state) {
 
$form_state['rebuild'] = TRUE;
  if (!empty(
$form_state['values']['field_in'])) {
    
$form_state['values']['field_cm'] = $form_state['values']['field_in'] * 2.54;
  }
  else {
    
$form_state['values']['field_in'] = $form_state['values']['field_cm'] / 2.54;
  }
  }
?>

Only thing I can see is that the #submit callback in your form alter should be wrapped in an array

Thanks to nevets for suggesting hook_node_presave(). Removed calculations from submit and validate functions - didn;t work there and added a hook_node_presave. Works like a charm! Thanks everyone. Here is the final code:

<?php
/**
* Implements hook_form().
*/
function my_module_form_alter(&$form, &$form_state, $form_id) {
  if(
$form_id == 'reading_node_form') {
      
$form['actions']['submit'] = array(
   
'#type' => 'submit',
   
'#value' => t('Add Reading'),
   
'#weight' => 50,
     
'#ajax' => array(
       
'wrapper' => 'reading-node-form',
       
'callback' => 'my_module_callback',
       
'clear' => TRUE,
       
'effect' => 'fade'
       
),
   
'#submit' => array (
        
0 => 'node_form_submit',
         ),
    );
}
  return
$form;
}
function
my_module_callback($form, &$form_state) {
 
$node = new stdClass();
 
$node->type = 'reading';
  return
drupal_get_form('node_form', $node);
}
function
my_module_node_presave($node) {
  if (
$node->type == 'reading') {
   
// set the *_reading fields
   
if (!empty($node->field_in['und'][0]['value'])) {
     
$node->field_cm['und'][0]['value'] = $node->field_in['und'][0]['value'] * 2.54;
    }
    else {
     
$node->field_in['und'][0]['value'] = $node->field_cm['und'][0]['value'] / 2.54;
    }
}
}
?>