0

I'm trying to process my custom form. However, code inside the submitForm function is never called. I have not seen any solutions, yet for getting Drupal 8's submitForm to be called.

namespace Drupal\archive\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;

class DateForm extends FormBase
{
    public function getFormId() { return 'archive_dateform'; }

    public function buildForm(array $form, FormStateInterface $form_state)
    {
        $form['#action'] = Url::fromRoute('archive.dateform')->toString();

        $form['type'] = [
            '#type' => 'hidden',
            '#value' => $form_state->get('type')
        ];

        $form['year'] = [
            '#title'         => 'Year',
            '#type'          => 'number',
            '#size'          => 4,
            '#step'          => 1,
            '#default_value' => $form_state->get('year'),
        ];

        $options = [];
        for ($i=1; $i<=12; $i++) { $options[$i] = date('F', mktime(0, 0, 0, $i, 10)); }
        $form['month'] = [
            '#title'         => 'Month',
            '#type'          => 'select',
            '#options'       => $options,
            '#default_value' => $form_state->get('month'),
            '#empty_option'  => 'All',
            '#empty_value'   => 0
        ];

        $form['actions']['#type'] = 'actions';
        $form['actions']['submit'] = [
            '#type'        => 'submit',
            '#value'       => 'Search',
            '#button_type' => 'primary'
        ];
        return $form;
    }

    public function validateForm(array &$form, FormStateInterface $form_state)
    {
        $type = $form_state->get('type');
        if (!$type) {
            $form_state->setErrorByName('type', 'Missing Type');
        }
    }

    public function submitForm(array &$form, FormStateInterface $form_state)
    {
        echo "submitForm\n";
        exit();
        $type = $form_state->get('type');

        $year = (int)$form_state->get('year');
        if (!$year) { $year = (int)date('Y'); }
        $params = ['year'=>$year];

        $month = (int)$form_state->get('month');
        if ($month) { $params['month'] = $month; }

        $form_state->setRedirect("archive.$type", $params);
        return;
    }
}

And using from a controller

namespace Drupal\archive\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Form\FormState;

class ArchiveController extends ControllerBase
{
    public function archive($type, $year, $month, $day)
    {
        $year  = (int)$year;
        $month = (int)$month;
        $day   = (int)$day;

        if (!$year) { $year = (int)date('Y'); }

        if (!$month) {
            $date = "$year-01-01";
            $period = new \DateInterval('P1Y1D');
        }
        else {
            if (!$day) {
                $date   = "$year-$month-01";
                $period = new \DateInterval('P1M1D');
            }
            else {
                $date   = "$year-$month-$day";
                $period = new \DateInterval('P1D');
            }
        }
        $start = new \DateTime($date);
        $end   = new \DateTime($date);
        $end->add($period);

        $manager = \Drupal::entityTypeManager();
        $query   = \Drupal::entityQuery('node')
                ->condition('type',    $type)
                ->condition('created', $start->format('U'), '>=')
                ->condition('created', $end  ->format('U'), '<')
                ->condition('status',  1);

        $form_state = new FormState();
        $form_state->set('type',  $type);
        $form_state->set('year',  $year);
        $form_state->set('month', $month);
        $form = \Drupal::formBuilder()->buildForm('Drupal\archive\Form\DateForm', $form_state);

        return [
            '#theme'   => 'archive_results',
            '#year'    => $year,
            '#start'   => $start,
            '#form'    => $form,
            '#results' => $manager->getViewBuilder('node')->viewMultiple(
                            $manager->getStorage('node')->loadMultiple($query->execute()),
                            'teaser'
                        )
        ];
    }
}
  • If you're determining that the submit handlers is not reached because of your echo statement, that won't work. Change it to drupal_set_message("submit"); and remove the call to exit, and you will likely see the submit handler is called. – Jaypan May 19 '17 at 18:20
0

I think your validation fails because you need to

$form_state->setValue('type',  $type);

in your controller instead of

$form_state->set('type',  $type);
  • Calling form_state->setValue() results in the fields not being rendered with those values. I'm not sure setValue() works that way. – Cliff Ingham May 19 '17 at 18:14
  • Did you also change '#default_value' => $form_state->get('year') to getValue() in your Form class? Think it's supposed to work that way. – Rainer Feike May 19 '17 at 18:25
  • Okay, I think that is, a big part of my problem. I am now calling ->getValue() and ->setValue(), instead of just plain ->get() and ->set(). The validate() and submitForm() functions are, in fact, being called now. Now I just have to figure out why the values are not there when I call $form_state->getValue('type') from inside the validate() and submitForm() functions. (but that sounds like a topic for another question.) – Cliff Ingham May 19 '17 at 18:31
  • The type field is now coming across as well. I had to use #default_value, instead of #value. $form['type'] = [ '#type' => 'hidden', '#default_value' => $form_state->getValue('type') ]; I had thought that #default_value was only for non-hidden fields. Turns out, I was wrong (as I often am). – Cliff Ingham May 19 '17 at 18:52
1

You're returning the form in #form. Drupal doesn't process things inside #attributes. That means your form isn't really a form and a lot of the required processing isn't happening.

You need to define your template as accepting a render element, and then e.g. print it as elements.form and set as just 'form' => $form.

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.