function cortisol_form( $node, &$form_state ) { // // Generate the form from a database table -- it's too easy to fuck up // and/or flatten the fields accidentally otherwise! $form_fields works OK, // but it doesn't store the attributes of the form elements, whereas with a DB // table, it would be trivial to add new fields and/or leave a space at the // end of theme_cortisol_form() to handle ''extra'' misc. fields at the end. // $form = array(); $form_fields = _cortisol_inputs(); $conflict_fields = _cortisol_conflict_fields(); // CSS: allow jQuery to replace some fields with radios $check = array( 'class' => 'checkconflicts' ); +--- 63 lines: $p0: Top of the paper survey on all 3 pages; just enter it once. +---128 lines: $p1: Page 1.----------------------------------------------------- +--- 96 lines: $p2: Page 2.----------------------------------------------------- +--- 30 lines: $p3: Page 3.----------------------------------------------------- +--- 27 lines: $p4: Page 4.----------------------------------------------------- // {{{ assemble the form... at least provisionally... foreach( array($p0, $p1, $p2, $p3, $p4) as $page ) { foreach( $page as $key => $value ) { $form[$key] = $value; } } $form['#submit'][] = 'cortisol_submit'; $form['#validate'][] = 'cortisol_validate'; $form['handentered']['#type'] = 'hidden'; $form['handentered']['#value'] = TRUE; $form['checked']['#type'] = 'hidden'; $form['sid']['#type'] = 'hidden'; $validation_code =<<<__END_JS // JavaScript for jQuery validation hooks should be injected here... __END_JS; drupal_add_js( $validation_code ); // }}} // {{{ If there are conflicts from validation, modify the form to show them. if( isset($form_state) ) { // Avoid the need to screw around during $node insertion $form['sid']['#value'] = $form_state['storage']['sid']; // Rebuild the form if instructed to do so if( $form_state['rebuild'] ) { if( $form_state['storage']['conflicts'] && !$form_state['storage']['resolved'] ) { $conflicts = unserialize($form_state['storage']['conflicts']); foreach( $conflicts as $field => $conflict ) { $new_old = explode('|',$conflict); $new = $new_old[0]; $old = $new_old[1]; foreach(_cortisol_conflict_radios($new, $old) as $prop => $val) { if( $prop == '#title' && isset($form[$field]['#title']) ){ $form[$field]['#title'] = "Correct value for '". $form[$field]['#title']."'"; } else { $form[$field][$prop] = $val; } } $form[$field]['#attributes']['class'] .= ' error'; unset($form_fields[$field]); } foreach($form_fields as $field) { $form[$field]['#default_value'] = $form_state['values'][$field]; } $form_state['storage'] = NULL; } drupal_set_message("Attempting to unset form_state['storage']..."); unset($form_state['storage']); drupal_set_message("\$form_state['storage'] = ".$form_state['storage']); unset($form_state['rebuild']); drupal_set_message("\$form_state['rebuild'] = ".$form_state['storage']); } else { foreach($form_fields as $field) { $form[$field]['#default_value'] = $form_state['values'][$field]; } } } else { $form['conflicts']['#value'] = 0; $form['resolved']['#value'] = 0; $form['checked']['#value'] = 0; } // }}} return $form; } function cortisol_validate( $node, &$form_state ) { // {{{ check for required (ID) fields // $values = 'values'; if( isset($form_state[$values]) ) { if ($form_state[$values]['participant'] < 100 || $form_state[$values]['participant'] > 999 ) { form_set_error('participant', t("Invalid ID #".$form_state[$values]['participant'].": please check!")); } if( !isset($form_state[$values]['phase']) ) { form_set_error('phase', t('The phase of the survey must be selected to proceed.')); } } else { form_set_error('$form_state['.$values.'] is not set! (This is a bug.)'); } // }}} // {{{ anything jQuery missed: silly stuff like '1 pack a day' etc. // foreach (_cortisol_conflict_fields(TRUE) as $field => $type) { if(!empty($form_state[$values][$field])) { switch( $type ) { case 'numeric': // NA/null should be '' or just NULL... if( preg_match('/(N\/?A|none)/i',$form_state[$values][$field]) ){ $form_state[$values][$field] = 0; } // still busted? if( !is_numeric($form_state[$values][$field]) ) { form_set_error('General badness',"$field must be a $type value"); } break; case 'time': if( !preg_match('/\d+:\d+/', $form_state[$values][$field]) ) { form_set_error('General badness',"$field must be a $type value"); } break; default: break; } } } // }}} // {{{ validation & conflict catching // if( isset($form_state[$values]['participant']) && isset($form_state[$values]['phase']) && !isset($form_state['storage']['checked']) ) { $inputs = _cortisol_inputs(); $pid = $form_state[$values]['participant']; $phase = $form_state[$values]['phase']; if( WELLELDERLY_DEBUG ) { drupal_set_message("Checking survey for subject $pid, phase $phase..."); } $conflicts = _cortisol_fetch_conflicts($form_state); if( $conflicts ) { $clist = array(); foreach( $conflicts as $field => $conflict ) { $new_old = explode('|',$conflict); $new = $new_old[0]; $old = $new_old[1]; if(is_numeric($old) || is_numeric($new)) { $clist[] = "$field: existing value is $old, you entered $new"; } else { $clist[] = "$field: existing value is '$old', you entered '$new'"; } $num++; } unset($inputs[$field]); foreach( $inputs as $field ) { $values[$field] = $form_state['values'][$field]; } $num = count($clist); $s = ($num > 1) ? "s" : ""; if ($num > 0) { form_set_error('conflicts', t("Found $num conflict$s (highlighted in red): ". theme_item_list($clist))); form_set_value(array( '#parents' => array('conflicts')), serialize($conflicts), $form_state ); form_set_value(array('#parents' => array('resolved')), 0, $form_state ); $form_state['storage']['conflicts'] = serialize($conflicts); $form_state['storage']['inputs'] = serialize($values); $form_state['rebuild'] = TRUE; } else { form_set_value(array('#parents' => array('conflicts')), 0, $form_state); form_set_value(array('#parents' => array('resolved')), 1, $form_state); } foreach( $inputs as $input ) { $form_state['storage'][$input] = $form_state[$values][$input]; } $form_state['storage']['inputfields'] = serialize($inputs); $form_state['storage']['checked'] = TRUE; } else { form_set_value(array( '#parents' => array('conflicts')), 0, $form_state); form_set_value(array( '#parents' => array('resolved')), 1, $form_state ); unset($form_state['storage']); unset($form_state['rebuilt']); } } }