1) My goal is to display extra input field to a user on the main form, when user decides that displayed list of options doesn't include the one, which he/she wants to mark. User decides on that by clicking the check-box 'add new occupation'. After the user clicks it, the textfield is exposed to him/her. Now, user is expected to provide a new occupation name in order to update already displayed list of options.

2) With the code I'm trying to alter 'add new content' form and create an extra form element - single check-box - that would trigger a new action: display of an extra text-field and a button on the altered form. The button is for triggering ajax functionality, which has following tasks:
-> using, provided by a customer, data in order to create (meaning - add to an existing vocabulary) a new term (save it in database).
-> appending new created term to the list of options (taxonomy reference terms) - already being displayed on the altered form.

Afterwards users can reference created content to the added term, by checking the check-box, and carry on with populating the remaining part of the form.

3) In the first code the ajax callback creates the mentioned term in the database, withdraws updated data about the whole list of taxonomy terms, and uses it to replace the out of date one on the form. The ajax callback creates the html markup, which works but when I create render array it stops working. I tired creating form element in the main hook and displaying it using ajax callback (second code sample) as well as creating the whole render array in the ajax callback but it didn't work. I got notices 'undefined index values ...' (in $form_state) or 'undefined index value ...' (in $form). In my work I followed drupal documentation about ajax, searched the internet as well as used examples module.

4) I'm looking for explanation how to collect the data from the user's input, and use it in order to update the taxonomy reference field without reloading the whole form.

function glue_form_curriculum_vitae_node_form_alter(&$form, &$form_state, $form_id) {
  /**
   * Adds a new occupation.
   */
  $form['field_occupation']['add_occupation'] = array(
    '#type' => 'container',
  );
  
  $form['field_occupation']['add_occupation']['add_another'] = array(
    '#type' => 'checkbox',
    '#title' => t('Add another occupation'),
    '#weight' => 50,
    '#default_value' => 0,
  );

  $form['field_occupation']['add_occupation']['new_term'] = array(
   '#type' => 'textfield',
   '#title' => t('Name of the occupation: '),
   '#size' => 30,
   '#states' => array(
     'visible' => array(
       ':input[name="field_occupation[add_occupation][add_another]"]' => array('checked' => TRUE),
     ),
   ),
   '#weight' => 51,
  );
  
  $form['field_occupation']['add_occupation']['add_term'] = array(
    '#type' => 'button',
    '#value' => t('Create new occupancy'),
    '#ajax' => array(
      'event' => 'click',
      'callback' => 'add_term',
      'wrapper' => 'edit-field-occupation-und',                      // id of already existing list of terms
    ),
    '#states' => array(
      'visible' => array(
        ':input[name="field_occupation[add_occupation][add_another]"]' => array('checked' => TRUE),
      ),
    ),
    '#weight' => 52,
//    '#submit' => array('add_occupation_to_the_list'),
  );
}
  
/**
 * Ajax callback for the Occupation section.
 * Adds term to the vocabulary and lists all the terms from occupancy vocabulary
 * as checkboxes
 */   
function add_term($form, $form_state) {
  $vid = db_query("SELECT vid FROM {taxonomy_vocabulary} WHERE machine_name = 'occupation'")->fetchField();
  $occupation = check_plain($form_state['values']['field_occupation']['add_occupation']['new_term']);
  $occupation = trim($occupation);

  taxonomy_term_save((object) array(
    'name' => $occupation,
    'vid' => $vid,
  ));
  $result = db_query("SELECT tid, name FROM {taxonomy_term_data} WHERE vid = :vid", array(
    ':vid' => $vid,));
  
  foreach ($result as $record) {
    $options[$record->tid] = $record->name;
    $output .= '<div class="form-item form-type-checkbox form-item-field-occupation-und-' . $record->tid . '">';
    $output .= '<input id="edit-field-occupation-und-' . $record->tid . '" class="form-checkbox" type="checkbox" value="' . $record->tid . '" name="field_occupation[und][' . $record->tid . ']">';
    $output .= '<label class="option" for="edit-field-occupation-und-' . $record->tid . '"> ' . $record->name . '</label></div>';
  }
  return $output;
}

The attempt to put it right (failed):
I've made several attempts of updating $form['field_occupation']['und']['#options'] using conditional statement like below. Cant figure out what I'm doing wrong.

function glue_form_curriculum_vitae_node_form_alter(&$form, &$form_state, $form_id) {
  /**
   * Adds a new occupation.
   */
  $form['field_occupation']['add_occupation'] = array(
    '#type' => 'container',
  );
  
  $form['field_occupation']['add_occupation']['add_another'] = array(
    '#type' => 'checkbox',
    '#title' => t('Add another occupation'),
    '#weight' => 50,
    '#default_value' => 0,
  );

  $form['field_occupation']['add_occupation']['new_term'] = array(
   '#type' => 'textfield',
   '#title' => t('Name of the occupation: '),
   '#size' => 30,
   '#states' => array(
     'visible' => array(
       ':input[name="field_occupation[add_occupation][add_another]"]' => array('checked' => TRUE),
     ),
   ),
   '#weight' => 51,
  );
  
  $form['field_occupation']['add_occupation']['add_term'] = array(
    '#type' => 'button',
    '#value' => t('Create new occupancy'),
    '#ajax' => array(
      'event' => 'click',
      'callback' => 'add_term',
      'wrapper' => 'edit-field-occupation-und',                      // id of already existing list of terms
    ),
    '#states' => array(
      'visible' => array(
        ':input[name="field_occupation[add_occupation][add_another]"]' => array('checked' => TRUE),
      ),
    ),
    '#weight' => 52,
  );
  if (!empty($form_state['values']) && !empty($form_state['values']['add_occupation']['new_term'])) {
    $vid = db_query("SELECT vid FROM {taxonomy_vocabulary} WHERE machine_name = 'occupation'")->fetchField();
  $occupation = check_plain($form_state['values']['field_occupation']['add_occupation']['new_term']);
  $occupation = trim($occupation);

  taxonomy_term_save((object) array(
    'name' => $occupation,
    'vid' => $vid,
  ));
  $result = db_query("SELECT tid, name FROM {taxonomy_term_data} WHERE vid = :vid", array(
    ':vid' => $vid,));
  
  foreach ($result as $record) {
    $form['field_occupation']['und']['#options'][$record->tid] = $record->name;
}
}
  
/**
 * Ajax callback for the Occupation section.
 * Adds term to the vocabulary and lists all the terms from occupancy vocabulary
 * as checkboxes
 */   
function add_term($form, $form_state) {
return $form['field_occupation']['und'];
}

I'm not an experienced developer and probably I'm missing something. Many thanks for help.

Comments

mark_owsky’s picture

I'm sorry for the second post, but I posted that again after I got message that there was no response from the server, while my post had already been saved, but I was mislead by the message.

jaypan’s picture

probably I'm missing something.

You're missing:

1) Your goal - what you are trying to do. This is different from what you have done, which is the code that shows how you are trying to do whatever it is you are trying to do. But we still do not know what your end goal is. Your end goal should contain no mention of any technical details on what you are trying to do. It should be plain English that someone who doesn't even know the word 'Drupal' should know. Example "I am trying to get FIELD A to update when a user makes a selection in FIELD X".

2) An explanation of what it is that you are trying to do with the code you have shown.

3) An explanation of what is going wrong with the code you have shown, and/or any difficulties you have having troubles with in particular.

4) Ideally, a summation of your specific questions.

With the above four things, we will be much better equipped to help you with your problems.

Contact me to contract me for D7 -> D10/11 migrations.

mark_owsky’s picture

Thank you for hints, and I'm sorry for being so unclear. I hope I can do better.

WorldFallz’s picture

Please don't post duplicate threads, I've deleted the dupe. Besides being a waste, dupes are no more likely to get answers without the necessary info, as jay listed above, than the original.

mark_owsky’s picture

I'm really sorry for the duplicate thread, my bad, but it happened after several attempts of posting, when server kept responding with an error, and after such a message, when I posted it again, it turned out that It was duplicate thread. Thank you for deleting it.