Ajax – How to update a Drupal 7 AJAX Form

ajaxdrupalforms

I am creating a Drupal 7 module. Currently my goal is to get the form to insert something into the database and then tell the user that it worked. I can get it to submit to the database just fine. Getting the form to rebuild and tell the user that their term has been submitted won't work. I keep getting variations on these alert errors: Which I will post in comments due to spam prevention…. sigh

A more recent error I was able to copy out with Chrome developer tools:

array (
'term_name' => 'jfidj',
'set_id' => '1',
)
[
{
"command":"settings",
"settings":{
"basePath":"\/drupal7\/",
"overlay":{
"paths":{
"admin":"node\/*\/edit\nnode\/*\/delete\nnode\/*\/revisions\nnode\/*\/revisions\/*\/revert\nnode\/*\/revisions\/*\/delete\nnode\/add\nnode\/add\/*\nadmin\nadmin\/*\nbatch",
"non_admin":""
},"ajaxCallback":"overlay-ajax"
}
},"merge":false
},{
"command":"insert",
"method":null,
"selector":null,
"data":"\u003cdiv id=\"form_message\"\u003e\u003cdiv class=\"form-item form-type-textfield form-item-message\"\u003e\n \u003clabel for=\"edit-message–2\"\u003ehidden \u003c\/label\u003e\n \u003cinput type=\"text\" maxlength=\"128\" name=\"message\" id=\"edit-message–2\" size=\"60\" value=\"\" class=\"form-text\" \/\u003e\n\u003c\/div\u003e\n\u003c\/div\u003e",
"settings":null},
{
"command":"insert",
"method":"prepend",
"selector":null,
"data":"",
"settings":null
}
]

I tried to format it better, but it's just messy…

As far as I can tell I am doing things correctly. I've been following the examples module, and the Drupal Ajax forms guide.

I create the form with wrappers defined, then have an if statement in there that only runs if the form has been submitted, then use ajax to replace the wrapped form element according to what you want.

To see what all I have tried, you can look at the Drupal forum topic I will post a link to in the comments.

Here's the current code I am trying, there's some code I've commented out, that I've tried and doesn't work.

/**
 * Add a term
 */
function markit_form_term_add()
{
    $sets = markit_get_marksets();
    //drupal_set_message(var_export($sets));
    $form = array();

    $form['message'] = array(
        '#type' => 'textfield',// . !(empty($form_state['values']['term_name'])) ? 'textfield' :  'hidden',
        '#title' => t('hidden'),
        '#value' => '',// . !(empty($form_state['values']['term_name'])) ? 'Added term: ' . $form_state['values']['term_name'] :  'Message goes here.',
        '#prefix' => '<div id="form_message">',
        '#suffix' => '</div>',
    );
    $form['add'] = array(
        '#type' => 'fieldset',
        '#title' => t('Add new Term'),
        '#prefix' => '<div id="add_term_form">',
        '#suffix' => '</div>',
    );
    $form['add']['name'] = array(
        '#type' => 'textfield',
        '#title' => t('Term name'),
        '#size' => 15,
    );
    //select the set you want to add the term to

    $setNames = array();
    foreach($sets as $row)
    {
        $id = $row['set_id'];
        $setNames[$id] = t($row['set_name']);
    }
    $form['add']['sets']['set_names'] = array(
        '#type' => 'select',
        '#title' => t('Select a set.'),
        '#options' => $setNames,
        '#description' => t('Select from the list of sets.'),
        );

    $form['add']['submit'] = array(
        '#type'  => 'button',
        '#value' => t('Add'),
        '#ajax' => array(
            'callback' => 'markit_ajax_terms_add_callback',
            'wrapper' => 'form_message',
            'method' => 'replace',
        ),
    );

    if(!empty($form_state['values']['name']))
    {
        $form['message']['#type'] = 'textfield';
        $form['message']['#value'] = t('Added term: ');// . $form_state['values']['term_name'];
    }

    return $form;
}

function markit_ajax_terms_add_callback($form, $form_state)
{    
    $entry = array(
       'term_name' => $form_state['values']['name'],
        'set_id' => $form_state['values']['set_names'],
        );
    markit_form_term_add_insert($entry);
    return $form['message'];    
}

/*
 * Get an array of mark sets
 */
function markit_get_marksets()
{
    $output = '';

    $select = db_select('markit_sets','s');
    $select->addField('s','set_id');
    $select->addField('s','set_name');
    $entries = $select->execute()->fetchAll(PDO::FETCH_ASSOC);
    return $entries;
}

/**
 * Get terms by set_id
 */
function markit_get_markterms($termid=NULL,$termname=NULL,$setid=NULL)
{
    $select = db_select('markit_terms','t');
    $select->addField('t','term_id');
    $select->addField('t','term_name');
    $select->addField('t','set_id');
    if($termid)
        $select->condition('term_id',$termid);//,'=');
    if($termname)
        $select->condition('term_name',$termname);//,'=');
    if($setid)
        $select->condition('set_id',$setid);//,'=');
    $entries = $select->execute()->fetchAll(PDO::FETCH_ASSOC);
return $entries;
}

/**
 * Insert new set into database
 */
function markit_form_set_add_insert($entry)
{
    $return_value = NULL;
  try {
    $return_value = db_insert('markit_sets')
                    ->fields($entry)
                    ->execute();
  }
  catch (Exception $e) {
    drupal_set_message(t('db_insert failed. Message = %message, query= %query',
      array('%message' => $e->getMessage(), '%query' => $e->query_string)), 'error');
  }
  return $return_value;
}

/**
 * Insert new set into database
 */
function markit_form_term_add_insert($entry)
{
    drupal_set_message(var_export($entry));
    $return_value = NULL;
  try {
    $return_value = db_insert('markit_terms')
                    ->fields($entry)
                    ->execute();
  }
  catch (Exception $e) {
    drupal_set_message(t('db_insert failed. Message = %message, query= %query',
      array('%message' => $e->getMessage(), '%query' => $e->query_string)), 'error');
  }
  return $return_value;
}

Best Answer

Right. In markit_form_term_add_insert, I had some code that I had been using to figure out some previous bugs (drupal_set_message(var_export($entry));). Deleting that fixed the problem. The debug code was the bug.... bangs head against wall

Specifically, I was using drupal_set_message to view the contents of a variable and make sure they were correct. But when I started using ajax, that drupal_set_message wasn't being called correctly anymore. It's supposed be called after a form is submitted, or, apparently, returned by the ajax callback. If it's just called like you would outside of ajax, it gives those errors.

Anyway, hope that this helps someone when they are searching for similar errors.

Basically, go through every single function that is being called. Even the ones that you know are not affecting anything. Somewhere in there is some code that isn't being called the way it's supposed to.