Hello,

I have some problem with ajax callback. After add a description by Upload button to database I try to dinamically show this result in tableselect, but db_select isn't refresh after callback.

Anybody can solution me?

function mymodule_list_desc($form, $form_state) {
  $form['fieldset'] = array(
    '#prefix' => '<div id="callback">',
    '#suffix' => '</div>',
  );

  $form['fieldset']['description'] = array(
    '#type' => 'textfield',
    '#title' => t('Description:'),
    '#maxlength' => 100,
  );

  $form['fieldset']['new'] = array(
    '#type' => 'button',
    '#value' => t('Upload'),
    '#ajax' => array(
      'callback' => 'mymodule_add_desc',
      'wrapper' => 'callback',
    ),
  );

  $header = array(
    array('data' => t('Description'), 'class' => array('center')),
  );

  $query = db_select('reg_desc', 'd')
  ->extend('TableSort');

  $query->fields('d');

  $result = $query
  ->orderByHeader($header)
  ->execute();

  $rows = array();

  foreach ($result as $desc) {
    $rows[$desc->id] = array(
      array('data' => $desc->info),
    );
  }

  $form['fieldset']['table'] = array(
    '#type' => 'tableselect',
    '#header' => $header,
    '#options' => $rows,
    '#multiple' => true,
  );

  return $form;
}


function mymodule_add_desc($form, $form_state) {
  global $user;

  $entry = array(
    'uid' => $user->uid,
    'data' => time(),
    'info' => $form_state['values']['info'],
  );

  $result = entry_insert('reg_desc', $entry);

  return $form['fieldset'];
}

Comments

jaypan’s picture

What is this function you are showing us? Is it your form definition or your ajax callback? And both of your functions have the same name, which will cause an error.

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

Thunders Master’s picture

My mistake, function mymodule_add_desc is ajax callback. First function should be called mymodule_list_desc, but the problem isn't sold.

jaypan’s picture

It looks like you are trying to save data inside your ajax callback, and then have that data sent to the browser. That won't work. You need to save your data in a submit function. By the time you get to your ajax callback, it's too late.

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

Thunders Master’s picture

Ok, but it's necessary to save this data in database dynamically (by Ajax), not save all form in submit function. Is it possible?

jaypan’s picture

Yes - you put it in a submit function, just as I explained. Submit functions are still saved during #ajax processing.

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

jaypan’s picture

Here's an example:

function ajax_save_form($form, &$form_state)
{
	$form['value'] = array
	(
		'#type' => 'textfield',
		'#title' => t('Value'),
		'#default_value' => '',
		'#prefix' => '<div id="ajax_save_wrapper">',
		'#suffix' => '</div>',
	);

	$form['submit'] = array
	(
		'#type' => 'submit',
		'#value' => t('Submit'),
		'#ajax' => array
		(
			'wrapper' => 'ajax_save_wrapper',
			'callback' => 'ajax_save_ajax_callback',
		),
	);
	return $form;
}

function ajax_save_form_submit($form, &$form_state)
{
	drupal_set_message(t('Submit function entered'));
}

function ajax_save_ajax_callback($form, &$form_state)
{
	return $form['value'];
}

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

Thunders Master’s picture

But what can I do if I have multiple submit buttons.

I cannot wirite this

$form['fieldset']['new'] = array(
'#type' => 'submit',
'#submit' => array('mymodule_add_desc'); // If we have multiple buttons this element should be here, but it doesn't work?.
'#value' => t('Upload'),
'#limit_validation_errors' => array(), // Even this won't help with multiple buttons
'#ajax' => array(
'callback' => 'mymodule_add_desc',
'wrapper' => 'callback',
),
);

jaypan’s picture

What exactly is your question? And can you please use code tags.

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

WorldFallz’s picture

Please don't post duplicate threads, I've deleted the dupe. Thanks.

Thunders Master’s picture

If anybody will have this problem we can add db_insert before db_select.

function mymodule_list_desc($form, $form_state) {
  global $user;

  $form['fieldset'] = array(
    '#prefix' => '<div id="callback">',
    '#suffix' => '</div>',
  );

  $form['fieldset']['description'] = array(
    '#type' => 'textfield',
    '#title' => t('Description:'),
    '#maxlength' => 100,
  );

  $form['fieldset']['new'] = array(
    '#type' => 'button',
    '#value' => t('Upload'),
    '#ajax' => array(
      'callback' => 'mymodule_add_desc',
      'wrapper' => 'callback',
    ),
  );

  if (isset($form_state['values']['new'])) {
    $entry = array(
      'uid' => $user->uid,
      'data' => time(),
      'info' => $form_state['values']['info'],
    );

    $result = entry_insert('reg_desc', $entry); // function db_insert
  }

  $header = array(
    array('data' => t('Description'), 'class' => array('center')),
  );

  $query = db_select('reg_desc', 'd')
  ->extend('TableSort');

  $query->fields('d');

  $result = $query
  ->orderByHeader($header)
  ->execute();

  $rows = array();

  foreach ($result as $desc) {
    $rows[$desc->id] = array(
      array('data' => $desc->info),
    );
  }

  $form['fieldset']['table'] = array(
    '#type' => 'tableselect',
    '#header' => $header,
    '#options' => $rows,
    '#multiple' => true,
  );

  return $form;
}

function mymodule_add_desc($form, $form_state) {
  return $form['fieldset'];
}
jaypan’s picture

Careful with that - form definitions can be called multiple times upon submit, and you may end up with unexpected results that can be difficult to debug. That's why it's best to put your save functions in a submit function.

That said, if it's working for you, then great!

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

Thunders Master’s picture

Maybe I could add this in submit function, but my form is very expanded with multiple submit and button. This causes that I can't do this in a simple way.

jaypan’s picture

You can attach submit handlers to buttons as necessary. If necessary, you can add one submit handler to more than one button.

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