10

I have an validate code:

public function validateForm(array &$form, FormStateInterface $form_state) {
    parent::validateForm($form, $form_state);

    $form_state->setValue('my_variable', $form_state->getValue('my_variable') + 1);
    $form_state->setRebuild();
}

And I previously set my_variable to 1 if it's NULL:

public function buildForm(array $form, FormStateInterface $form_state) {

    if($form_state->getValue('my_variable') == NULL){
        $form_state->setValue('my_variable', 1);
    }
...

I use ajax callback for form submission and the validation works fine. After click on submit button I display my_variable and I see 2 (before submission it's 1).

But when I hit the submit button again I see 2 again, instead of 3. Also, when I re-load the page the data is missing (so it's get value 1 again).

How to prevail the value? It looks like I am operating on copy of $form_state instead of reference but I cannot write &$form_state (public function validateForm(array &$form, FormStateInterface &$form_state)) because it gives me an error (as it's not the correct declaration of validateForm method).

2
  • 1
    $form_state->set('my_variable', 1); Try this Commented Jan 25, 2017 at 7:14
  • It works the same way as I described. It set variable to 1 when called in validateForm but that change is lost after reload of page as well as hiting sumbit button again. Of course if I set it to 1 in both validateForm and buildForm it's always 1 (but still, the set in validateForm is lost after refresh/submit again).
    – PolGraphic
    Commented Jan 25, 2017 at 15:12

4 Answers 4

-3

The value in the $form_state (actually everything) is lost after the PHP process ends. So there is no way to preserve your my_variable value via the $form_state. Your best option is to store this value in the session I guess.

Example:

  public function validateForm(array &$form, FormStateInterface $form_state) {
    parent::validateForm($form, $form_state);

    $session = \Drupal::request()->getSession();
    $session->set('my_variable', $session->get('my_variable') + 1);
  }

  public function buildForm(array $form, FormStateInterface $form_state) {
    $session = \Drupal::request()->getSession();

    if (empty($session->get('my_variable'))) {
      $session->set('my_variable', 1);
    }
  }

Do note that the data gets lost as soon as the user clears his cookies and/or the sessions gets invalidated. If you need a permanent global storage (for all users) use the State API. For a permanent storage per user use the Database API.

2
  • 3
    The $form_state does persist between PHP processes, as this AJAX example shows: api.drupal.org/api/examples/…
    – joachim
    Commented Feb 6, 2018 at 21:56
  • 2
    Oh! please don't use State variables for handling data in forms. It's better to keep using the form state storage since Drupal will handle the data for you and will destroy it once finished. If you use Session in this context it will work but it is not whats meant to be used for. You already have a form state storage why not you just use it. Always refer to Drupal examples module: git.drupalcode.org/project/examples/-/blob/… look for page_num variable and how you can handle it's value Commented Mar 28, 2022 at 12:22
10

If it is a custom variable, you should use $form_state->set('property_name', 'value') (instead of "$form_state->setValue(...)").

Example:

public function validateForm(array &$form, FormStateInterface $form_state) {
    parent::validateForm($form, $form_state);

    // Update custom variable (in PHP "null + 1" equals one).
    $form_state->set('my_variable', $form_state->get('my_variable') + 1);

    // Below is only required when your "buildForm(...)" depends on the variable.
    $form_state->setRebuild();
}

3
  • 2
    This is the best answer and should be accepted.
    – mbomb007
    Commented Jun 24, 2022 at 16:30
  • In Drupal 10, you should use $form_state->setValue('my_variable', $form_state->get('my_variable') + 1); Commented Jan 9, 2023 at 16:20
  • Use ->set(...) to avoid confusion, even if newer ->setValue(...) sets custom-variable if it can not find any element for given key.
    – Top-Master
    Commented Jan 9, 2023 at 18:09
2

Just to add if you'd like to actually save a form value. I do the following when using webform, I imagine it's easily modified for a usual form.

$form['elements']['form_element']['#default_value'] = 'my_value'

0

You can use

$form_state->setValue('VALUE_NAME', VALUE_PASSING);

Like -

public function validateForm(array &$form, FormStateInterface $form_state) {
    parent::validateForm($form, $form_state);
    $form_state->setValue('csvupload', $file->destination);
    $form_state->setValue('fid', $file->fid);
    $form_state->setRebuild();
}
1
  • I don't know about this... See @Top-Master's answer Commented Oct 26, 2022 at 23:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.