I'm defining an ajax form in my custom module (#ajax for submit). It is shown in custom block. But it works fine only on cache clear (on Drupal clear all caches or on ctrl+r in chrome). If I just use a link in navbar to navigate to another page or insert an url to browser my ajax callback stops being used. If I ctrl+r it starts working. I thought it's a cache issue but any cache disabling (form or block) doesn't take an effect. Please help.
UPD:
Here is the code for the form:
public function buildForm(array $form, FormStateInterface $form_state) {
// Add a wrapper div that will be used by the Form API to update the form using AJAX
$form['#prefix'] = '<div id="my_ajax_form">';
$form['#suffix'] = '</div>';
$form['#disable_inline_form_errors_summary'] = TRUE;
$form['#cache'] = ['max-age' => 0];
$form['#cache']['contexts'][] = 'session';
$form['left'] = [
'#type' => 'fieldset',
'#prefix' => '<div class="group-left">',
'#suffix' => '</div>',
];
$form['left']['image'] = [
'#type' => 'item',
'#markup' => '<img src="some img url"
class="my-form-image" alt="image">',
];
$form['right'] = [
'#type' => 'fieldset',
'#prefix' => '<div class="group-right">',
'#suffix' => '</div>',
];
$form['right']['headline'] = [
'#type' => 'item',
'#markup' => $this->t('some text1'),
];
$form['right']['description'] = [
'#type' => 'item',
'#markup' => $this->t('some text2'),
];
$form['right']['first_name'] = [
'#type' => 'textfield',
'#title' => $this->t('First Name'),
];
$form['right']['last_name'] = [
'#type' => 'textfield',
'#title' => $this->t('Last Name'),
];
$form['right']['email'] = [
'#type' => 'email',
'#title' => $this->t('Email address'),
];
$form['right']['cta'] = [
'#type' => 'item',
'#markup' => $this->t('some text3'),
];
$form['right']['actions'] = [
'#type' => 'actions',
];
// Add a submit button that handles the submission of the form.
$form['right']['actions']['submit'] = [
'#type' => 'submit',
'#value' => $this->t('SUBMIT'),
'#attributes' => [
'class' => [
'myCustomBehavior',
]
],
'#ajax' => [
'wrapper' => 'my_ajax_form',
'callback' => '::submitCallback',
'event' => 'click',
'progress' => [
'type' => 'none',
],
],
];
return $form;
}
/**
* Validate the title and the checkbox of the form
*
* @param array $form
* @param \Drupal\Core\Form\FormStateInterface $form_state
*
*/
public function validateForm(array &$form, FormStateInterface $form_state) {
parent::validateForm($form, $form_state);
$first_name = $form_state->getValue('first_name');
if (empty($first_name)) {
// Set an error for the form element with a key of "first_name".
$form_state->setErrorByName('first_name', $this->t('Please enter your first name'));
}
$last_name = $form_state->getValue('last_name');
if (empty($last_name)){
// Set an error for the form element with a key of "last_name".
$form_state->setErrorByName('last_name', $this->t('Please enter your last name'));
}
$email = $form_state->getValue('email');
if (empty($email)){
// Set an error for the form element with a key of "email".
$form_state->setErrorByName('email', $this->t('Please enter your email'));
}
else {
$connection = \Drupal::database();
$query = $connection->select('my_table', 'm')
->condition('m.email', $email, '=')
->fields('m', ['email']);
$count = $query->countQuery()->execute()->fetchField();
if (0 != $count) {
$form_state->setErrorByName('email', $this->t('This email already exists.'));
}
}
}
/**
* Form submission handler.
*
* @param array $form
* An associative array containing the structure of the form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current state of the form.
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$field = $form_state->getValues();
$field_arr = [
'first_name' => $field['first_name'],
'last_name' => $field['last_name'],
'email' => $field['email'],
];
$query = \Drupal::database();
$query->insert('my_table')
->fields($field_arr)
->execute();
$form_state->setRebuild(TRUE);
}
/**
* Ajax callback for the form submit
*/
public function submitCallback(array $form, FormStateInterface $form_state) {
$response = new AjaxResponse();
if (!$form_state->hasAnyErrors()) {
$form['right']['#prefix'] = '<div class="group-right group-right-processed">';
$form['right']['headline']['#markup'] = $this->t('<h1 class="my-form-headline">thank you</h1>');
$form['right']['description']['#markup'] = $this->t('some text4');
unset($form['right']['first_name'], $form['right']['last_name'], $form['right']['email'], $form['right']['cta'], $form['right']['actions']);
$response->addCommand(new ReplaceCommand(NULL , $form));
return $response;
}
else {
$form_state->setRebuild();
return $form;
}
}
Here is the code for the block:
public function build() {
$form = \Drupal::formBuilder()->getForm('Drupal\my_module\Form\MyForm');
return $form;
}
public function getCacheMaxAge() {
return 0;
}