1

I have the below simple if else condition for a custom module form page in buildForm method for recommendation submission. I would like my form to be displayed to all user who visit for the first time and submits and cannot submit again from the same url. If the url is used again it should just display the thank you message(if already submitted). The below code wrks perfectly if the user is logged in. Like if the user is logged in, he comes and submit, thank you message is displayed everything is saved in DB correctly. The problem comes when anonymous user comes. The page loads as expected. But after filling up the details and submit button is clicked. It reloads and the same form is displayed again(instead of the thank yo message) and then if I submit again it displays validation errors even though the fields are there and gives the thank you message. Can anyone explain me why its behaving differently for logged in and anonymous users.

    public function buildForm(array $form, FormStateInterface $form_state)
    {
       if($this->CheckRecommendationStatus())
       {
          $form = array();
          $form['form_label'] = [
          '#type' => 'processed_text',
          '#text' => t('<h3<strong>Thank you already submitted</h3>'),
          ];
        }
        else if($this->validateUrl())
        {
           $form = array();
           //it will have controls and submit button.if submit is clicked those values will be saved
        }
        return $form;
     }
     //This below method check the Database whether already the submission is made or not
     public function CheckRecommendationStatus()
     {
           $this->setUniqueIdentifier(htmlspecialchars($_GET["rec"]));
           $query = \Drupal::database()->select('m_tablename', 'mr');
           $query->fields('mr',array('id'));
           $query->condition('mr.column_name',$this->getUniqueIdentifier());
           $query->range(0,1);      
           $results = $query->execute()->fetchAll();
           return $results;
     }
1

1 Answer 1

1

This sounds like a caching issue. Check the cache api and make sure to set the $form['#cache'] appropriately.

When the anonymous user submits the form, it's submitted fine, but when the form loads the second time Drupal doesn't know that it should not be serving the original cached form.

You can quickly confirm that it is a caching issue by set the form to not be cached like:

$form['#cache'] = [
  'max-age' => 0,
]; 
5
  • It looks like a caching issue. Even though manually I am giving incorrect querystring value, still it loads correctly with previous details. I tried the above code before the if condition, it did'nt work. Sep 20, 2018 at 22:02
  • You will need to add it below, just before the return $form; as you completely reset the form variable within each if case
    – sonfd
    Sep 20, 2018 at 22:06
  • Perfect its working as expected. Thanks a lot. But why did it work for logged in users. Caching is different for them. Sep 20, 2018 at 22:10
  • I think because caching is not enabled by default for logged in users. But I think that changed with a recent release, or is changing soon?
    – sonfd
    Sep 20, 2018 at 22:15
  • 1
    the thing is that for authenticated users, all forms are currently uncacheable because they CSRF protection. However, for anonymous users, you are hitting the dynamic page cache, which by default does not consider the query argument when caching, you would need to add url.query_args.rec cache context. Note that max-age 0 is additionally not respected by the internal page cache, so you might also need to use \Drupal::service('page_cache_kill_switch')->trigger(); so it is not cached there
    – Berdir
    Sep 21, 2018 at 5:57

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.