Saturday, January 23, 2016

Using Ajax Forms in Drupal 8

# vim myexample.info.yml

name: My Example Module
description: My Example Module.
package: Custom

type: module
core: 8.x

# vim myexample.routing.yml

myexample.content:
  path: '/myexample'
  defaults:
    _controller: '\Drupal\myexample\Controller\MyexampleController::content'
    _title: 'Hello World'
  requirements:
    _permission: 'access content'

# vim src/Controller/MyexampleController.php

<?php
/**
 * @file
 * Contains \Drupal\myexample\Controller\MyexampleController.
 */

namespace Drupal\myexample\Controller;

use Drupal\Core\Controller\ControllerBase;

use Symfony\Component\HttpFoundation\Response;

class MyexampleController extends ControllerBase {
  public function content() {
    $contactform = \Drupal::formBuilder()->getForm('Drupal\myexample\Form\ContactForm');

    return [
      '#type' => 'markup',
      '#markup' => $this->t('Hello, World!'),
      'contactform' => $contactform,
    ];
  }
}
?>

# vim src/Form/ContactForm.php

<?php
/**
 * @file
 * Contains \Drupal\myexample\Form\ContactForm.
 */

namespace Drupal\myexample\Form;

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

use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\CssCommand;
use Drupal\Core\Ajax\HtmlCommand;

/**
 * Implements an example form.
 */
class ContactForm extends FormBase {

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'contact_form';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    #$form['#action'] = '/contactformsubmit';

    $form['contact_name'] = array(
      '#type' => 'textfield',
      '#title' => $this->t('Contact Name'),
    );

    $form['email'] = array(
      '#type' => 'textfield',
      '#ajax' => array(
        'callback' => array($this, 'validateEmailAjax'),
        'event' => 'blur',
        'effect' => 'fade',
      ),
    );

    $form['actions'] = array(
      '#type' => 'actions',
      'submit' => array(
        '#type' => 'submit',
        '#value' => $this->t('Save'),
        '#button_type' => 'primary',
      ),
    );

    return $form;
  }

  /**
   * Validates that the email field is correct.
   */
  protected function validateEmail(array &$form, FormStateInterface $form_state) {
    return valid_email_address($form_state->getValue('email'));
  }

  /**
   * Ajax callback to validate the email field.
   */
  public function validateEmailAjax(array &$form, FormStateInterface $form_state) {
    $response = new AjaxResponse();
    $valid = $this->validateEmail($form, $form_state);

    if ($valid) {
      $css = ['border' => '1px solid green'];
      $message = $this->t('Email ok.');
    }
    else {
      $css = ['border' => '1px solid red'];
      $message = $this->t('Email not valid.');
    }

    $response->addCommand(new CssCommand('#edit-email', $css));
    $response->addCommand(new HtmlCommand('.email-valid-message', $message));

    return $response;
  }

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state) {
    #file_put_contents('/tmp/debug1', print_r($form, TRUE) . PHP_EOL, FILE_APPEND);

    if (strlen($form_state->getValue('contact_name')) < 3) {
      $form_state->setErrorByName('contact_name', $this->t('The contact name is too short.'));
    }
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    drupal_set_message($this->t('Contact name @contact_name', array('@contact_name' => $form_state->getValue('contact_name'))));
  }
}
?>

Reference:

http://www.sitepoint.com/using-ajax-forms-drupal-8/

http://www.kalose.net/oss/drupal-8-ajax-forms/

https://www.drupal.org/node/2117411

No comments: