Boris Böhne
Drupal Developer, Sindelfingen, Germany
05/07/2015
<?php
/**
* @file
* Contains \Drupal\config\Form\ConfigExportForm.
*/
namespace Drupal\config\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
class ConfigExportForm extends FormBase {
public function getFormId() {
return 'config_export_form';
}
public function buildForm(array $form, FormStateInterface $form_state) {
$form['description'] = array(
...
);
...
return $form;
}
public function submitForm(array &$form, FormStateInterface $form_state) {
...
}
}
Example: /modules/config/src/Form/ConfigExportForm.php
<?php
/**
* @file
* Contains \Drupal\config\Form\ConfigExportForm.
*/
namespace Drupal\config\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
class ConfigExportForm extends FormBase {
public function getFormId() {
return 'config_export_form';
}
public function buildForm(array $form, FormStateInterface $form_state) {
$form['description'] = array(
'#markup' => '<p>' . $this->t('Use the export button below to download your site configuration.') . '</p>',
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => $this->t('Export'),
);
return $form;
}
public function submitForm(array &$form, FormStateInterface $form_state) {
$form_state->setRedirect('config.export_download');
}
}
Complete class: \Drupal\config\Form\ConfigExportForm
ban.delete:
path: '/admin/config/people/ban/delete/{ban_id}'
defaults:
_form: '\Drupal\ban\Form\BanDelete'
_title: 'Delete IP address'
requirements:
_permission: 'ban IP addresses'
ban.routing.yml
<?php
namespace Drupal\ban\Form;
use Drupal\Core\Form\ConfirmFormBase;
...
class BanDelete extends ConfirmFormBase {
...
}
Rendering a standalone form on a page
BanDelete.php
...
public function translatePage() {
return array(
'filter' => $this->formBuilder()->getForm('Drupal\locale\Form\TranslateFilterForm'),
'form' => $this->formBuilder()->getForm('Drupal\locale\Form\TranslateEditForm'),
);
}
...
\Drupal\locale\Controller\localeContoller
<?php
namespace Drupal\locale\Form;
use Drupal\Core\Form\FormStateInterface;
class TranslateFilterForm extends TranslateFormBase {
...
}
Embedding a form in other markup
\Drupal\locale\Form\TranslateFilterForm
public function validateForm(array &$form, FormStateInterface $form_state) {
$this->file = file_save_upload('file', $form['file']['#upload_validators'], 'translations://', 0);
// Ensure we have the file uploaded.
if (!$this->file) {
$form_state->setErrorByName('file', $this->t('File to import not found.'))
}
}
Example: \Drupal\locale\Form\ImportForm
public function validateForm(array &$form, FormStateInterface $form_state) {
$name = trim($form_state->getValue('name'));
// Try to load by email.
$users = $this->userStorage->loadByProperties(array('mail' => $name, 'status' => '1'));
if (empty($users)) {
// No success, try to load by name.
$users = $this->userStorage->loadByProperties(array('name' => $name, 'status' => '1'));
}
$account = reset($users);
if ($account && $account->id()) {
$form_state->setValueForElement(array('#parents' => array('account')), $account);
}
else {
$form_state->setErrorByName('name', $this->t('Sorry, %name is not recognized as a
username or an email address.', array('%name' => $name)));
}
}
Example: \Drupal\user\Form\UserPasswordForm
public function submitForm(array &$form, FormStateInterface $form_state) {
if ($form_state->getValue('confirm')) {
$this->commentStorage->delete($this->comments);
$count = count($form_state->getValue('comments'));
$this->logger('content')->notice('Deleted @count comments.', array('@count' => $count));
drupal_set_message($this->formatPlural($count, 'Deleted 1 comment.', 'Deleted @count comments.'));
}
$form_state->setRedirectUrl($this->getCancelUrl());
}
Example: \Drupal\comment\Form\ConfirmDeleteMultiple
public function submitForm(array &$form, FormStateInterface $form_state) {
$allowed_types = array_filter($form_state->getValue('book_allowed_types'));
// We need to save the allowed types in an array ordered by machine_name so
// that we can save them in the correct order if node type changes.
// @see book_node_type_update().
sort($allowed_types);
$this->config('book.settings')
// Remove unchecked types.
->set('allowed_types', $allowed_types)
->set('child_type', $form_state->getValue('book_child_type'))
->save();
parent::submitForm($form, $form_state);
}
Example: \Drupal\book\Form\BookSettingsForm
<?php
/**
* @file
* Contains \Drupal\block\Form\BlockDeleteForm.
*/
namespace Drupal\block\Form;
use Drupal\Core\Entity\EntityDeleteForm;
use Drupal\Core\Url;
/**
* Provides a deletion confirmation form for the block instance deletion form.
*/
class BlockDeleteForm extends EntityDeleteForm {
/**
* {@inheritdoc}
*/
public function getCancelUrl() {
return new Url('block.admin_display');
}
}
Example: \Drupal\block\Form\BlockDeleteForm
...
use Drupal\Core\Form\FormStateInterface;
...
function mymodule_form_node_form_alter(&$form, FormStateInterface $form_state, $form_id) {
// Add a checkbox to the node form about agreeing to terms of use.
$form['terms_of_use'] = array(
'#type' => 'checkbox',
'#title' => t("I agree with the website's terms and conditions."),
'#required' => TRUE,
);
}
Example: mymodule.module
http://slides.com/drubb
http://slideshare.net/drubb
By Boris Böhne
Working with forms in Drupal 8 modules, a presentation at Drupal Meetup Stuttgart, 05/07/2015