how to preserve current checkbox values if validation fails
Hi, In a custom nodetype, I have a fieldset $form['keywords'] with stuff filled by ajax calls, e.g. $form['keywords'][$vid][$tid]['#type'] = 'checkbox'; $form['keywords'][$vid][$tid]['#value'] = $tid; $form['keywords'][$vid][$tid]['#name'] = 'taxonomy[' .$vid .'][' .$tid .']'; All works quite fine, but, if validation fails (title not set for example), my own form_alter, validate or submit function aren't called. If the user $form['taxonomy'] chexboxes are correctly set after reloading the form with the error displayed, it's not the case with my $form['keywords'] (I guess it's because values of my $form['keywords'] are in $form_state['values']['taxonomy']). So I tried to do this (set default_value depending on $_POST values) in my after_build function, but all the changes done in it aren't displayed (I dump the form so I'm sure changes are done in $form in this function). function my_after_build_callback(&$form, &$form_state) { // check if it's necessary to do something and what // ... $form['keywords'][$vid][$tid]['#value'] = $toset; $form['keywords'][$vid][$tid]['#default_value'] = $toset; $form_state['values']['taxonomy'][$vid][$tid] = $toset; // ... // drupal_set_message(dump(etc. => changes OK) return $form; } But then drupal_render seems just ignoring my changes, just lik if it took the previous cache version :-/ Any clues ? -- Daniel
Daniel Caillibaud ha scritto:
Hi,
In a custom nodetype, I have a fieldset $form['keywords'] with stuff filled by ajax calls, e.g.
$form['keywords'][$vid][$tid]['#type'] = 'checkbox'; $form['keywords'][$vid][$tid]['#value'] = $tid; $form['keywords'][$vid][$tid]['#name'] = 'taxonomy[' .$vid .'][' .$tid .']';
All works quite fine, but, if validation fails (title not set for example), my own form_alter, validate or submit function aren't called.
Strange, have you tried to add a line like drupal_set_message("In my form_alter"); to you form_alter function ? Try in _validate and _submit, too.
If the user $form['taxonomy'] chexboxes are correctly set after reloading the form with the error displayed, it's not the case with my $form['keywords'] (I guess it's because values of my $form['keywords'] are in $form_state['values']['taxonomy']).
So I tried to do this (set default_value depending on $_POST values) in my after_build function, but all the changes done in it aren't displayed (I dump the form so I'm sure changes are done in $form in this function).
function my_after_build_callback(&$form, &$form_state) { // check if it's necessary to do something and what // ... $form['keywords'][$vid][$tid]['#value'] = $toset; $form['keywords'][$vid][$tid]['#default_value'] = $toset; $form_state['values']['taxonomy'][$vid][$tid] = $toset; // ... // drupal_set_message(dump(etc. => changes OK) return $form; }
But then drupal_render seems just ignoring my changes, just lik if it took the previous cache version :-/
Because you need to say that the menu need to be rebuild ($form_state['rebuild'] = true;) (but yuo need to make this in _validate function). However I have see that in your code (the first) there is not set the "#default_value" in $form['keywords'][$vid][$tid] item. M. -- Michel 'ZioBudda' Morelli michel@ziobuddalabs.it Sviluppo applicazioni CMS DRUPAL e web dinamiche (LAMP+Ajax) Telefono: 0200619074 Telefono Cell: +39-3939890025 -- Fax: +39-0291390660 http://www.ziobudda.net ICQ: 58351764 http://www.ziobuddalabs.it Skype: zio_budda http://www.ziodrupal.net MSN: michel@ziobuddalabs.it JABBER: michel@ziobuddalabs.it
Le 20/04/10 à 09:00, Michel Morelli <michel@ziobuddalabs.it> a écrit :
All works quite fine, but, if validation fails (title not set for example), my own form_alter, validate or submit function aren't called.
Strange,
It seems normal
have you tried to add a line like
drupal_set_message("In my form_alter");
to you form_alter function ? Try in _validate and _submit, too.
Yes of course, I say that because I check it before. If validation fails, none of form_alter, validate or submit (this is logical not call submit if validate fails) are called. http://drupal.org/node/398562 http://drupal.org/node/671574 ../..
$form['keywords'][$vid][$tid]['#default_value'] = $toset;
../..
Because you need to say that the menu need to be rebuild ($form_state['rebuild'] = true;) (but yuo need to make this in _validate function).
_validate function isn't called, if I add this in _after_build function, it doesn't change anything, a call to form_builder in this _after_build doesn't change anything (changes are made but not transmitted to drupal_render).
However I have see that in your code (the first) there is not set the "#default_value" in $form['keywords'][$vid][$tid] item.
It was set ;-) (see above) My pb is why my modified form (in _after_build, I'm sure, diplaying its dump with drupal_set_message) isn't transmitted to drupal_render ? And I don't understand why drupal render is called twice with this form (same form_build_id)... Thanks for suggestions (I'll look what happen with a standard nodetype as page to better understand fapi process) -- Daniel Le hasard ne profite qu'aux esprits préparés. Pasteur
Le 20/04/10 à 11:49, Daniel Caillibaud <ml@lairdutemps.org> a écrit :
(I'll look what happen with a standard nodetype as page to better understand fapi process)
Fapi process is quite clear http://drupal.org/node/165104, but if _validate functions are called, when a previous validation fails (no title), changes made there on form or form_state are ignored then by drupal_render :-( to test function mymodule_form_alter(&$form, &$form_state, $form_id) { ... else if($form_id == 'page_node_form') { $form['#after_build'][] = '_test_after_build'; $form['#validate'][] = '_test_validate'; $form['#submit'][] = '_test_submit'; } } function _test_validate(&$form, &$form_state) { drupal_set_message('_test_validate with build_id=' .$form['#build_id']); $form['body']['#value'] = 'My new body modified in _test_validate on form'; $form_state['values']['body'] = 'My new body modified in _test_validate via form_state'; $form['title']['#default_value'] = 'My new modified title in _test_validate'; if ($errors = form_get_errors()) { // this is executed when title validation fails drupal_set_message(edulibre_get_dump($errors, 'errors already fired in _test_validate')); } drupal_set_message(edulibre_get_dump($form, 'form in _test_validate')); drupal_set_message(edulibre_get_dump($form_state, 'form_state in _test_validate')); return $form; } But then, in drupal_render (and of course on screen), we have the $form in its state before our _test_validate :-/ -- Daniel PS: my custom dump function (MAXDUMPS is set to prevent too much krumo tree, if not javascript could become really slow) function edulibre_get_dump($var, $str='', $krumo=TRUE) { static $i = 0; if ($i < MAXDUMPS) { if ($krumo && function_exists('has_krumo') && has_krumo()) { return 'Starting dumping (<strong style="color:#a00">' .$str .'</strong>)<br />' .krumo_ob($var) ."\nEnd of dump ($str)<br />"; } else { // a more classical dump... ob_start(); echo "Starting dumping ($str)<br /><pre>"; // var_export($var); // "Nesting level too deep" could be fired var_dump($var); echo "</pre>\nEnd of dump ($str)<br />"; $out = ob_get_contents(); ob_end_clean(); $i++; return str_replace("=>\n", '=> ', $out); // to compact a little bit output } } else { return "Max dumps reached (" .MAXDUMPS .") : $str)"; } }
Le 19/04/10 à 20:21, Daniel Caillibaud <ml@lairdutemps.org> a écrit :
Hi,
In a custom nodetype, I have a fieldset $form['keywords'] with stuff filled by ajax calls, e.g.
$form['keywords'][$vid][$tid]['#type'] = 'checkbox'; $form['keywords'][$vid][$tid]['#value'] = $tid; $form['keywords'][$vid][$tid]['#name'] = 'taxonomy[' .$vid .'][' .$tid .']';
All works quite fine, but, if validation fails (title not set for example), my own form_alter, validate or submit function aren't called.
_validate is called, but can't do anything directly ($form is here just for reading and drupal_render doesn't take care about $form_state). form_set_value should be a solution. I make my changes in _after_build, BUT I first forgot to add a unset($form['keywords']['#after_build_done']); in ajax callback ajax, after form_builder and before form_set_cache... -- Daniel
participants (2)
-
Daniel Caillibaud -
Michel Morelli