I've got a Form class, the constructor of which sets a private attribute for the Model. When the form is rendered, everything seems to work as expected. The last form element is a select which, based upon the selected value, adds another textfield to the form if needed. However, the problem is, when the ajax is called for the first time, everything is OK and the additional field is added. When I try to select a different value though, I get this error as if the constructor did not run thus not setting the $model attribute of the class.
js_zfg1OcYBPiNuiGY77hX8zdIjztYiO7UAz7wbokItO2I.js:2515 Uncaught AjaxError: An AJAX HTTP error occurred. HTTP Result Code: 200
Debugging information follows.
Path: /admin/asphira/contacts/add?ajax_form=1&_wrapper_format=drupal_ajax
StatusText: OK
ResponseText: Error: Call to a member function getKeyedList() on null in
Drupal\asphira\Form\ContactForm->buildForm() (line 112 of C:\xampp\htdocs\reality\modules\asphira\src\Form\ContactForm.php).
Here is the form class.
namespace Drupal\asphira\Form;
use Drupal\asphira\Model\ContactTypeModel;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Locale\CountryManager;
class ContactForm extends FormBase {
private $model;
public function __construct() {
$this->model = new ContactTypeModel();
}
public function getFormId() {
return 'contact_form';
}
public function buildForm(array $form, FormStateInterface $form_state) {
$form['name'] = array(
'#title' => t('Name'),
'#type' => 'textfield',
'#required' => TRUE,
);
$form['surname'] = array(
'#title' => t('Surname'),
'#type' => 'textfield',
'#required' => TRUE,
);
$form['nee_surname'] = array(
'#title' => t('Née surname'),
'#type' => 'textfield',
'#required' => TRUE,
);
$form['street'] = array(
'#title' => t('Street'),
'#type' => 'textfield',
'#required' => TRUE,
);
$form['street_no'] = array(
'#title' => t('Street no.'),
'#type' => 'textfield',
'#required' => TRUE,
);
$form['zip_code'] = array(
'#title' => t('ZIP code'),
'#type' => 'textfield',
'#required' => TRUE,
);
$form['city'] = array(
'#title' => t('City'),
'#type' => 'textfield',
'#required' => TRUE,
);
$form['country'] = array(
'#title' => t('Country'),
'#type' => 'select',
'#options' => CountryManager::getStandardList(),
'#required' => TRUE,
);
$form['phone'] = array(
'#title' => t('Telephone'),
'#type' => 'textfield',
);
$form['email'] = array(
'#title' => t('Email'),
'#type' => 'email',
'#required' => TRUE,
);
$form['contact_type_container'] = array(
'#type' => 'container',
'#attributes' => array(
'id' => 'contact-type-container',
),
);
$contact_types = $this->model->getKeyedList('t_contact_type',
'contact_type_id', 'title');
$form['contact_type_container']['contact_type'] = array(
'#title' => t('Contact type'),
'#type' => 'select',
'#options' => $contact_types,
'#required' => TRUE,
'#ajax' => array(
'callback' => array($this, 'ajaxSelectContactType'),
'wrapper' => 'contact-type-container',
'progress' => array(
'type' => 'throbber',
'message' => $this->t('Working...'),
),
)
);
$form['actions'] = array('#type' => 'actions');
$form['actions']['submit'] = array(
'#type' => 'submit',
'#value' => t('Save'),
);
return $form;
}
public function submitForm(array &$form, FormStateInterface $form_state) {
// TODO: Implement submitForm() method.
}
public function ajaxSelectContactType(array &$form, FormStateInterface $form_state) {
$contact_type = $form_state->getValue('contact_type');
$needs_specification = $this->model->needsFurtherSpeification($contact_type);
if ($needs_specification) {
$form['contact_type_container']['contact_type_specification'] = array(
'#title' => t('Specification'),
'#type' => 'textfield',
'#description' => '',
'#required' => TRUE,
);
}
return $form['contact_type_container'];
}
}
Do you have any idea how is it possible that the constructor gets passed by without calling?