Since its introduction in #138706: FormAPI 3: Ready to rock, the form state has been an array. The form state tracks the "current state" of the form as it is built, processed, validated, and submitted.
In Drupal 8, the newly added FormStateInterface is used instead of an array for $form_state.
The following code snippets reference the FormBuilder. See drupal_*_form() methods are replaced by a form builder service for more information.
Before:
$form_state['rebuild'] = TRUE;
$form_builder->buildForm('Drupal\my_module\Form\MyForm', $form_state);
After:
use Drupal\Core\Form\FormState;
$form_state = new FormState();
$form_state->setRebuild();
$form_builder->buildForm('Drupal\my_module\Form\MyForm', $form_state);
In order to do things like setting errors, you no longer need the whole form builder:
Before:
form_set_error($element, $form_state, $message);
form_set_error('element_name', $form_state, $message);
After:
$form_state->setError($element, $message);
$form_state->setErrorByName($element, $message);
In addition to the functions that were replaced by methods, all array-based usage of $form_state is now replaced by methods:
Before:
$complete_form = &$form_state['complete_form'];
$form_state['complete_form'] = &$complete_form;
After:
$complete_form = &$form_state->getCompleteForm();
$form_state->setCompleteForm($complete_form);
Before:
$response = $form_state['response'];
$form_state['response'] = $response;
After:
$response = $form_state->getResponse();
$form_state->setResponse($response);
Before:
$form_state['redirect'] = new Url('route_name', array('route' => 'parameters'));
$form_state['redirect'] = array('route_name', array('route' => 'parameters'));
$redirect = $form_state['redirect'];
$form_state['no_redirect'] = TRUE;
if (!empty($form_state['no_redirect'])) {
}
After:
$form_state->setRedirectUrl(new Url('route_name', ['route' => 'parameters']));
$form_state->setRedirect('route_name', ['route' => 'parameters']);
$redirect = $form_state->getRedirect();
$form_state->disableRedirect();
if ($form_state->isRedirectDisabled()) {
}
Before:
$storage = &$form_state['storage'];
$form_state['storage'] = &$storage;
After:
$storage = &$form_state->getStorage();
$form_state->setStorage($storage);
Before:
$temporary = $form_state['temporary'];
$form_state['temporary'] = $temporary;
After:
$temporary = $form_state->getTemporary();
$form_state->setTemporary($temporary);
Before:
$arbitrary_value = $form_state['arbitrary_key'];
$form_state['arbitrary_key'] = $arbitrary_value;
$nested_arbitrary_value = $form_state['nested']['arbitrary_key'];
$form_state['nested']['arbitrary_key'] = $nested_arbitrary_value;
After:
$arbitrary_value = $form_state->get('arbitrary_key');
$form_state->set('arbitrary_key', $arbitrary_value);
$nested_arbitrary_value = $form_state->get(['nested', 'arbitrary_key']);
$form_state->set(['nested', 'arbitrary_key'], $nested_arbitrary_value);
Before:
$build_info = $form_state['build_info'];
$form_state['build_info'] = $build_info;
$form_state['build_info']['args'] = $args;
$args = $form_state['build_info']['args'];
After:
$build_info = $form_state->getBuildInfo();
$form_state->setBuildInfo($build_info);
$form_state->addBuildInfo('args', $args);
$args = $form_state->getBuildInfo()['args'];
Before:
$input = &$form_state['input'];
$form_state['input'] = $input;
After:
$input = &$form_state->getUserInput();
$form_state->setUserInput($input);
Before:
$foo = $form_state['values']['foo']; // This will return an array. print_r($foo)
$foobar = $form_state['values']['foo']['bar'];
$values = $form_state['values'];
$form_state['values']['foo'] = 'bar';
$form_state['values']['bar']['baz'] = 'foo';
if (isset($form_state['values']['foo'])) {
}
if (isset($form_state['values']['foo']['bar'])) {
}
if (empty($form_state['values']['foo'])) {
}
if (empty($form_state['values']['foo']['bar'])) {
}
After:
$foo = $form_state->getValue('foo');
$foobar = $form_state->getValue(['foo', 'bar']);
$values = $form_state->getValues();
$form_state->setValue('foo', array('bar'));
$form_state->setValue(['bar', 'baz'], 'foo');
if ($form_state->hasValue('foo')) {
}
if ($form_state->hasValue(['foo', 'bar'])) {
}
if ($form_state->isValueEmpty('foo')) {
}
if ($form_state->isValueEmpty(['foo', 'bar'])) {
}
Before:
$form_state['rebuild'] = TRUE;
$form_state['rebuild'] = FALSE;
if (!empty($form_state['rebuild'])) {
}
After:
$form_state->setRebuild();
$form_state->setRebuild(FALSE);
if ($form_state->isRebuilding()) {
}
Before:
$form_state['build_info']['callback_object'] = $callback;
$callback = $form_state['build_info']['callback_object'];
After:
$form_state->setFormObject($callback);
$callback = $form_state->getFormObject();
Before:
$form_state['always_process'] = TRUE;
$form_state['always_process'] = FALSE;
if (!empty($form_state['always_process'])) {
}
After:
$form_state->setAlwaysProcess();
$form_state->setAlwaysProcess(FALSE);
if ($form_state->getAlwaysProcess()) {
}
Before:
$buttons = $form_state['buttons'];
$form_state['buttons'] = $buttons;
After:
$buttons = $form_state->getButtons();
$form_state->setButtons($buttons);
Before:
$form_state['cache'] = TRUE;
$form_state['cache'] = FALSE;
$form_state['no_cache'] = TRUE;
if (!empty($form_state['cache']) && empty($form_state['no_cache'])) {
}
After:
$form_state->setCached();
$form_state->setCached(FALSE);
$form_state->disableCache();
if ($form_state->isCached()) {
}
Before:
$form_state['executed'] = TRUE;
if (!empty($form_state['executed'])) {
}
After:
$form_state->setExecuted();
if ($form_state->isExecuted()) {
}
Before:
$groups = &$form_state['groups'];
$form_state['groups'] = $groups;
After:
$groups = &$form_state->getGroups();
$form_state->setGroups($groups);
Before:
$form_state['has_file_element'] = TRUE;
$form_state['has_file_element'] = FALSE;
if (!empty($form_state['has_file_element'])) {
}
After:
$form_state->setHasFileElement();
$form_state->setHasFileElement(FALSE);
if ($form_state->hasFileElement()) {
}
Before:
$limit_validation_errors = $form_state['limit_validation_errors'];
$form_state['limit_validation_errors'] = $limit_validation_errors;
After:
$limit_validation_errors = $form_state->getLimitValidationErrors();
$form_state->setLimitValidationErrors($limit_validation_errors);
Before:
$form_state['method'] = 'get';
if ($form_state['method'] == 'get') {
}
After:
$form_state->setMethod('get');
if ($form_state->isMethodType('get')) {
}
Before:
$form_state['must_validate'] = TRUE;
$form_state['must_validate'] = FALSE;
if (!empty($form_state['must_validate'])) {
}
After:
$form_state->setValidationEnforced();
$form_state->setValidationEnforced(FALSE);
if ($form_state->isValidationEnforced()) {
}
Before:
$form_state['process_input'] = TRUE;
$form_state['process_input'] = FALSE;
if (!empty($form_state['process_input'])) {
}
After:
$form_state->setProcessInput();
$form_state->setProcessInput(FALSE);
if ($form_state->isProcessingInput()) {
}
Before:
$form_state['programmed'] = TRUE;
$form_state['programmed'] = FALSE;
if (!empty($form_state['programmed'])) {
}
After:
$form_state->setProgrammed();
$form_state->setProgrammed(FALSE);
if ($form_state->isProgrammed()) {
}
Before:
$form_state['programmed_bypass_access_check'] = TRUE;
$form_state['programmed_bypass_access_check'] = FALSE;
if (!empty($form_state['programmed_bypass_access_check'])) {
}
After:
$form_state->setProgrammedBypassAccessCheck();
$form_state->setProgrammedBypassAccessCheck(FALSE);
if ($form_state->isBypassingProgrammedAccessChecks()) {
}
Before:
$form_state['submitted'] = TRUE;
if (!empty($form_state['submitted'])) {
}
After:
$form_state->setSubmitted();
if ($form_state->isSubmitted()) {
}
Before:
$form_state['validation_complete'] = TRUE;
$form_state['validation_complete'] = FALSE;
if (!empty($form_state['validation_complete'])) {
}
After:
$form_state->setValidationComplete();
$form_state->setValidationComplete(FALSE);
if ($form_state->isValidationComplete()) {
}
Before:
$build_info = $form_state['rebuild_info'];
$form_state['rebuild_info'] = $build_info;
$form_state['rebuild_info']['copy'] = $info;
$info = $form_state['rebuild_info']['copy'];
After:
$build_info = $form_state->getRebuildInfo();
$form_state->setRebuildInfo($build_info);
$form_state->addRebuildInfo('copy', $info);
$info = $form_state->getRebuildInfo()['copy'];
Before:
$submit_handlers = $form_state['submit_handlers'];
$form_state['submit_handlers'] = $submit_handlers;
After:
$submit_handlers = $form_state->getSubmitHandlers();
$form_state->setSubmitHandlers($submit_handlers);
Before:
$validate_handlers = $form_state['validate_handlers'];
$form_state['validate_handlers'] = $validate_handlers;
After:
$validate_handlers = $form_state->getValidateHandlers();
$form_state->setValidateHandlers($validate_handlers);
Before:
$triggering_element = &$form_state['triggering_element'];
$form_state['triggering_element'] = $triggering_element;
After:
$triggering_element = &$form_state->getTriggeringElement();
$form_state->setTriggeringElement($triggering_element);
Comments
This is not correct:
Note this is not correct:
Either get $storage as a & reference, or set it once you are finished. It does not make sense to do both.
--
Jonathan Brown
http://jonathanpatrick.me/
These are not functional
These are not functional examples. Just showing what methods are available, and where appropriate, that some getters return by reference.
How to check which button is clicked...
#validate and #submit still
#validate and #submit still exist.. rather then odd logic loops in one the submit.
now that this is within it's own class the
::is used to calls the follow up function. OOP tricks.(: also, as your sample is a delete situation, check into Removed confirm_form() in favor of \Drupal\Core\Form\ConfirmFormBase to verify delete operations. better to be safe than sorry.
no follow button :(.
no follow button :(.
hence commenting..
If only it was this simple
Actually, in Drupal 7
$form_state['values']['foo']would have returned the submitted value. In Drupal 8 it appears to be an array. You have to access it like:$foo = $form_state->getValue('foo')[0]['value']. For a multivalue field as well as the values themselves it will have one blank item, and an "Add another item" object, which means stepping through the array to look at the values is ugly.---
Edit: the best way I have found to get multi-value form value into an array is this:
Hello,
Hello,
I am having a problem with port below code to Drupal 8.
$form_state['field_deltas'][] = count($form_state['field_deltas']) > 0 ?max($form_state['field_deltas'])+1: 0;Please suggest the solution for this.
Yash Khandelwal
Drupal Developer
Doesn't seem to work...
I'm attempting to use the value of an entity_autocomplete rather than the id of the entity. I've tried using
$form_state->getValue('location')[0]['value']and that didn't work, i'm still getting the id coming back. I also attempted$form_state->getValue('location')['#value']as thats what the structure looked like after doing a dsm of the $form_state array. Any insights anyone can offer?Solution
I just thought I'd update this with my solution. I ended up doing a Node::load on the variable assigned to $form_state->getValue('location'); and then pulling the title from the loaded node with -getTitle();
setValue Not working properly .
Hi,
When I tried to alter a field value it replace first latter of string to 0.
$form_state->setValue('foo', array('bar'));
That means result of this code is 0ar.Also get error
Warning: Illegal string offset '_original_delta' in Drupal\Core\Field\WidgetBase->extractFormValues() (line 361 of core/lib/Drupal/Core/Field/WidgetBase.php).
I am using this in custom validation of form.
Same issue with setValue()
Hi pankajdrync,
I'm having the same issue on custom entity submitForm,
$from_state->setValue('foo', ['value'])
is generate warning messages "Warning: Illegal string offset '_original_delta' ..."
The value is correctly saved but I get warnings...
Did you find a solution to avoid these warnings ?
Working fine as given example
Working fine as given example:-
$form_state->setValue(['field_name', '0', 'value'], 'new value');
I found above how to set
I found above how to set errored form fields as:
$form_state->setError($element, $message);but couldn't find anything explaining what $element was. In D7 it was an odd field name with inner parts of array brackets (but not outer) - e.g. 'myfieldset][myfield'.
this is an example for D8 of setting error for a field within a group of fields located within a set of fieldsets (now "detail" form item in D8):
still not sure difference between ->setError() and ->setErrorName()
Peter Lindstrom
LiquidCMS - Content Solution Experts
You have to pass the field from $form
Like this
where $form['video'] is field's name in form.
anyone tried rebuilding only
anyone tried rebuilding only current form in multistep form when validation fails?
page 1
--field1
--field2
page 2
--field3
--field4
.
.
page n
if any validation fails on "page 2" then is there a way to rebuild only that form?
$form_state->setRebuild(); will resets the complete form including page 1. In d7 this works well with just $form_state['rebuild'] = true;
Use setUserInput method
I searched for a few hours for the same issue, and $form_state->setUserInput() is the solution for me !
Exemple :
$values = $form_state->getUserInput();
$values['my_field']['0']['value'] = 'my value';
$form_state->setUserInput($values)->setRebuild();