Score:-3

Upon failed validation, why are form values reset to what they were at the time of last successful validation?

mg flag

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?

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.