I am working on a Drupal 9 form, which is used in the following manner:
- In the first step, user fills up the form and presses the unique submission button ("CHECK");
- if the form validation succeeds, the data is processed, and the result of this processing is displayed in the form, as well as an additional submission button ("SUBMIT");
- at this point, user can either check that everything is fine with the processed data, and make the final submission with "SUBMIT", or edit the form and press "CHECK" again.
public function buildForm(array $form, FormStateInterface $form_state){
//build inputs...
if($form_state->get('isValidated')){
//show "edit-check" and "edit-submit" buttons...
}
else{
//show "edit-check" button only...
}
}
public function validateForm(array &$form, FormStateInterface $form_state){
$form_state->set('isValidated', 0);
//validation logic...
}
public function submitForm(array &$form, FormStateInterface $form_state){
$form_state->setRebuild(true);
$isValidated = true;
//do some processing that may change the value of $isValidated...
if(!$isValidated){
\Drupal::messenger()->addError("Processing error.");
}
else{
$submitButton = $form_state->getTriggeringElement()['#id'];
if($submitButton == 'edit-check'){
\Drupal::messenger()->addWarning('You can check processed data and submit.');
$form_state->set('isValidated', 1);
}
elseif($submitButton == 'edit-submit'){
//submit to DB...
$form_state->setRebuild(false);
}
}
}
My problem is the following: as long as user remains in the first step (that is, until the first successful validation occurs), failed validations lead to the form being rebuilt and displaying the last inputs user has submitted. But once a successful validation has occurred, the form is not rebuilt anymore on further failed validations, and the inputs are reset to the values they were holding at the time of the last successful validation, which is not what I would expect.
I've tried forcing the rebuilding of the form in validateForm()
; I've tried messing with the caching in buildForm()
; I've tried some things with hook_form_alter()
(with little hope, since it doesn't allow to alter the $form_state
anyway)... None of these changed anything.
After a conversation with chatGPT, where the concept of "form lifecycle" was mentionned, I'm starting to suspect that I'm using the validation/submission system of Drupal in a hacky way that it is not designed to support, and that perhaps I should use some other mechanism, e.g. AJAX, for the first (pre)validation.
So, is there an easy fix to force the rebuilding of the form so it will always display the last submitted values, independently of a previous successful validation? Or should I look into another way of achieving what I want?