質問

I am using the hook_form_FORM_ID_alter in Drupal 7 to create a custom form so that the user can enter and edit data which is then attached to a custom node type.

For a new node the default number of input boxes in a group is 10, this can then be added to in groups of 5. When the node is reloaded for editing the saved data is used to create the form with whatever number of inputs have been saved previously and also the ability to add more fields in the same manner as required.

I have managed to get both the initial version of the form and the editing version to work using the following code however when the 'add five' button is pressed and the AJAX called (in both cases), any values which have been entered without saving are removed.

<?php 

/**
 * Implements hook_form_FORM_ID_alter().
 */

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


$node = $form['#node'];
// fieldset
$form["section"] = array(
    '#type' => 'fieldset',
    '#title'=> 'Section 1',     
);
$form["section"]["termwrapper"] = array(
    "#type" => 'container',
    "#attributes" => array(
        "id" => 'groupWrapper',
    ),
);
$form["section"]["termwrapper"]["terms"]["#tree"] = TRUE;
if(!isset($form_state['fired'])){
    $form_state['terms'] = $node->entries_form['term'];
}

foreach ($form_state['terms'] as $key => $values) {
    $form["section"]["termwrapper"]["terms"][$key] = array(
        '#type' => 'textfield',
        '#size' => 20,
        '#attributes' => array(
            'class' => array('left'),
        ),
    '#value' => $values,
    );  
}

$form['section']['addFive_button'] = array(
    '#type' => 'submit',
    '#value' => t('+5'),
    '#submit' => array('entries_form_add_five_submit'),
    '#ajax' => array(
      'callback' => 'entries_form_commands_add_callback',
      'wrapper' => 'groupWrapper',
      ),
    '#prefix' => "<div class='clear'></div>",
);
dpm($form_state);
}

function entries_form_commands_add_callback($form, $form_state) {
    return $form["section"]["termwrapper"]; 
}

function entries_form_add_five_submit($form, &$form_state){
    $form_state['rebuild'] = TRUE;
    $form_state['fired'] = 1;
    $values = $form_state['values'];
    $form_state['terms'] =  $values['terms'];
    $numterms = count($values['terms']);
    $addfivearray = array_fill($numterms,5,'');
    $form_state['terms'] = array_merge($values['terms'],$addfivearray);

}


/**
 * Implements hook_node_submit().
 */

function entries_form_node_submit($node, $form, &$form_state) {
    $values = $form_state['values'];
    $node->entries_form['term'] = $values['term'];
}

/**
 * Implements hook_node_prepare().
 */
function entries_form_node_prepare($node) {
    if (empty($node->entries_form)){
        $node->entries_form['term'] = array_fill(0, 10, '');
    }
}

/**
 * Implements hook_node_load().
 */
function entries_form_node_load($nodes, $types) {
    if($types[0] == 'entries'){
        $result = db_query('SELECT * FROM {mytable} WHERE nid IN(:nids)', array(':nids' => array_keys($nodes)))->fetchAllAssoc('nid');
        foreach ($nodes as &$node) {
            $node->entries_form['term'] = json_decode($result[$node->nid]->term);
        }
    }   
}

/**
 * Implements hook_node_insert().
 */
function entries_form_node_insert($node) {
  if (isset($node->entries_form)) {
    db_insert('mytable')
      ->fields(array(
        'nid' => $node->nid,
        'term' => json_encode($node->entries_form['term']),
      ))
      ->execute();
  }
}

How can I keep the values which have been typed in and retain the ajax functionality?

Any help or pointers much appreciated. This is my first dip into Drupal so I'm sure there is something which hopefully is quite obvious that I'm missing.

役に立ちましたか?

解決

Ok, I think I finally have the answer.

Within the foreach that builds the form input boxes I had set '#value' => $values, when it seems that '#default_value' => $values, should have been set instead.

The updated section of the code that is now working for me is as follows

foreach ($form_state['terms'] as $key => $values) {
        $form["section"]["termwrapper"]["terms"][$key] = array(
            '#type' => 'textfield',
            '#size' => 20,
            '#attributes' => array(
                'class' => array('left'),
            ),
        '#default_value' => $values,
        );  
    }

Seems to be as simple as that. Hope this helps someone else.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top