7

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 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
    Jan 25, 2017 at 15:12

4 Answers 4

0

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
  • 2
    The $form_state does persist between PHP processes, as this AJAX example shows: api.drupal.org/api/examples/…
    – joachim
    Feb 6, 2018 at 21:56
  • 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 Mar 28 at 12:22
5

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();
}

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();
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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