You are here

abstract class AjaxFormBase in Forena Reports 8

Class AjaxFormTrait

Use this trait to add ajax submit handler behaviors that complement an AjaxControllerInterface class.

Hierarchy

Expanded class hierarchy of AjaxFormBase

File

src/Form/AjaxFormBase.php, line 18

Namespace

Drupal\forena\Form
View source
abstract class AjaxFormBase extends FormBase {
  const FORM_ID = '__ABSTRACT__';

  /**
   * @var AjaxPageControllerBase
   *   The Ajax cotnroller bound to this form.
   */
  protected $controller;

  /**
   * Set controller based on sinbleton.
   * AjaxFormBase constructor.
   */
  public function __construct() {
    $this->controller = AjaxPageControllerBase::service();
  }

  /**
   * @throws \Exception
   *   Thrown when a programmer does not implement a FORM_ID constant.
   */
  public function getFormId() {
    if (static::FORM_ID == AjaxFormBase::FORM_ID) {
      $class = get_class($this);
      throw new \Exception("FORM_ID class constant not implemented in {$class}");
    }
    return static::FORM_ID;
  }

  /**
   * Return the controller that is bound to the form.
   *
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   * @return \Drupal\forena\Controller\AjaxPageControllerBase|mixed
   */
  public function getController() {
    return $this->controller;
  }

  /**
   * Ajax callback handler for submit buttons.
   *
   * @param array $form
   *   Form array
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   Drupal form state object.
   * @return \Drupal\Core\Ajax\AjaxResponse
   *   The ajax response object used to update the page.
   */
  public function submitCallback(&$form, FormStateInterface $form_state) {
    if ($this->controller->is_modal_form) {
      return $this
        ->ajaxModalCallback($form, $form_state);
    }
    else {
      return $this
        ->ajaxCallback($form, $form_state);
    }
  }

  /**
   * Ajax callback.
   * @param AjaxPageControllerBase $controller
   *   The controller to register with the interface
   * @param array $form
   *   Drupal form render array
   * @param $form_state
   *   Drupral form state object.
   * @return \Drupal\Core\Ajax\AjaxResponse
   */
  public function ajaxCallback($form, FormStateInterface $form_state) {
    $response = new AjaxResponse();

    // Make sure form error rebuilds happen.
    if ($form_state
      ->getErrors() || $form_state
      ->isRebuilding()) {
      $ctl['status_messages'] = [
        '#type' => 'status_messages',
        '#weight' => -10,
      ];

      // Array merge the status element onto the beginning of the form.
      $form = array_merge($ctl, $form);
      $section = $form_state
        ->get('e_section');
      $command = new HtmlCommand("#{$section}", $form);
      $response
        ->addCommand($command);
      $this->controller->section = $this->controller->prior_section;
    }
    else {
      $this->controller->section = $this->controller->prior_section;
      if (!$this->controller->prevent_action) {
        $this->controller->post_form_id = $form_state
          ->getFormObject()
          ->getFormId();
        $this->controller
          ->route($this->controller->action);
      }
    }
    $commands = $this->controller
      ->getCommands();
    foreach ($commands as $command) {
      $response
        ->addCommand($command);
    }
    $this->controller
      ->saveState();
    return $response;
  }

  /**
   * Ajax callback.
   * @param $form
   * @param $form_state
   * @return \Drupal\Core\Ajax\AjaxResponse
   */
  public function ajaxModalCallback(&$form, FormStateInterface $form_state) {
    if ($form_state
      ->getErrors() || $form_state
      ->isRebuilding()) {
      unset($form['#prefix']);
      unset($form['#suffix']);

      // array merge the status elements onto the beginning of the form
      $ctl['status_messages'] = [
        '#type' => 'status_messages',
        '#weight' => -10,
      ];
      $form = array_merge($ctl, $form);
      $this->controller
        ->setEndCommand(new HtmlCommand('#e-modal-form', $form));
    }
    else {

      // Process route when requested.
      $this->controller->section = $this->controller->prior_section;
      if (!$this->controller->prevent_action) {
        $this->controller->post_form_id = $form_state
          ->getFormObject()
          ->getFormId();
        $this->controller
          ->route($this->controller->action);
      }
      if (!$this->controller->modal_added) {
        $this->controller
          ->addCommand(new CloseDialogCommand());
      }
    }
    $commands = $this->controller
      ->getCommands();
    $response = new AjaxResponse();
    foreach ($commands as $command) {
      $response
        ->addCommand($command);
    }
    $this->controller
      ->saveState();
    return $response;
  }

  /**
   * @param \Drupal\forena\Controller\AjaxPageControllerBase $controller
   * @param $form
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   */
  public function bindAjaxForm(AjaxPageControllerBase $controller, &$form, FormStateInterface $form_state) {
    if ($controller->is_modal_form && $controller->jsMode != 'nojs') {
      $form_state
        ->set('e_modal', TRUE);
      $form['#prefix'] = "<div id='e-modal-form'>";
      $form['#suffix'] = "</div>";
    }
    else {
      $form_state
        ->set('e_section', $controller->section);
    }
    $form[$controller::TOKEN_PARAMETER] = [
      '#type' => 'hidden',
      '#value' => $controller
        ->getStateToken(),
    ];

    // Disable caching on this form.
    $form_state
      ->setCached(FALSE);

    // Set the form state handler.
    $controller->form_state = $form_state;

    // Alter the submit handlers.
    $this->controller = $controller;
    $method = "::submitCallback";
    $callback = $method;
    $this
      ->alterForm($form, $callback);
  }

  /**
   * @param array $elements
   *   Drupal form render array section.
   * @param string $callback
   *   Callback to apply to the form submit buttons.
   */
  private function alterForm(&$elements, $callback) {
    foreach ($elements as $key => $element) {
      if (strpos($key, '#') !== 0 && is_array($element)) {
        if (!empty($element['#type'])) {
          switch ($element['#type']) {
            case 'submit':
              if (!isset($element['#ajax'])) {
                $elements[$key]['#mode'] = $callback;
                $elements[$key]['#ajax'] = [
                  'callback' => $callback,
                  'event' => 'click',
                ];
              }
              break;
          }
        }
        $this
          ->alterForm($elements[$key], $callback);
      }
    }
  }

  /**
   * Create a report controll.
   * @param $report
   * @param null $parms
   */
  public function report($report, $parms = NULL) {
    if ($parms === NULL) {
      $parms = $this
        ->getController()->parms;
    }
    return Forena::service()
      ->report($report, $parms);
  }
  public function __wakeup() {
    $this->controller = AjaxPageControllerBase::service();
  }

}

Members

Namesort descending Modifiers Type Description Overrides
AjaxFormBase::$controller protected property The Ajax cotnroller bound to this form.
AjaxFormBase::ajaxCallback public function Ajax callback.
AjaxFormBase::ajaxModalCallback public function Ajax callback.
AjaxFormBase::alterForm private function
AjaxFormBase::bindAjaxForm public function
AjaxFormBase::FORM_ID constant 1
AjaxFormBase::getController public function Return the controller that is bound to the form.
AjaxFormBase::getFormId public function Overrides FormInterface::getFormId
AjaxFormBase::report public function Create a report controll.
AjaxFormBase::submitCallback public function Ajax callback handler for submit buttons.
AjaxFormBase::__construct public function Set controller based on sinbleton. AjaxFormBase constructor.
AjaxFormBase::__wakeup public function Overrides DependencySerializationTrait::__wakeup
DependencySerializationTrait::$_entityStorages protected property An array of entity type IDs keyed by the property name of their storages.
DependencySerializationTrait::$_serviceIds protected property An array of service IDs keyed by property name used for serialization.
DependencySerializationTrait::__sleep public function 1
FormBase::$configFactory protected property The config factory. 1
FormBase::$requestStack protected property The request stack. 1
FormBase::$routeMatch protected property The route match.
FormBase::config protected function Retrieves a configuration object.
FormBase::configFactory protected function Gets the config factory for this form. 1
FormBase::container private function Returns the service container.
FormBase::create public static function Instantiates a new instance of this class. Overrides ContainerInjectionInterface::create 87
FormBase::currentUser protected function Gets the current user.
FormBase::getRequest protected function Gets the request object.
FormBase::getRouteMatch protected function Gets the route match.
FormBase::logger protected function Gets the logger for a specific channel.
FormBase::redirect protected function Returns a redirect response object for the specified route. Overrides UrlGeneratorTrait::redirect
FormBase::resetConfigFactory public function Resets the configuration factory.
FormBase::setConfigFactory public function Sets the config factory for this form.
FormBase::setRequestStack public function Sets the request stack object to use.
FormBase::validateForm public function Form validation handler. Overrides FormInterface::validateForm 62
FormInterface::buildForm public function Form constructor. 179
FormInterface::submitForm public function Form submission handler. 192
LinkGeneratorTrait::$linkGenerator protected property The link generator. 1
LinkGeneratorTrait::getLinkGenerator Deprecated protected function Returns the link generator.
LinkGeneratorTrait::l Deprecated protected function Renders a link to a route given a route name and its parameters.
LinkGeneratorTrait::setLinkGenerator Deprecated public function Sets the link generator service.
LoggerChannelTrait::$loggerFactory protected property The logger channel factory service.
LoggerChannelTrait::getLogger protected function Gets the logger for a specific channel.
LoggerChannelTrait::setLoggerFactory public function Injects the logger channel factory.
MessengerTrait::$messenger protected property The messenger. 29
MessengerTrait::messenger public function Gets the messenger. 29
MessengerTrait::setMessenger public function Sets the messenger.
RedirectDestinationTrait::$redirectDestination protected property The redirect destination service. 1
RedirectDestinationTrait::getDestinationArray protected function Prepares a 'destination' URL query parameter for use with \Drupal\Core\Url.
RedirectDestinationTrait::getRedirectDestination protected function Returns the redirect destination service.
RedirectDestinationTrait::setRedirectDestination public function Sets the redirect destination service.
StringTranslationTrait::$stringTranslation protected property The string translation service. 1
StringTranslationTrait::formatPlural protected function Formats a string containing a count of items.
StringTranslationTrait::getNumberOfPlurals protected function Returns the number of plurals supported by a given language.
StringTranslationTrait::getStringTranslation protected function Gets the string translation service.
StringTranslationTrait::setStringTranslation public function Sets the string translation service to use. 2
StringTranslationTrait::t protected function Translates a string to the current language or to a given language.
UrlGeneratorTrait::$urlGenerator protected property The url generator.
UrlGeneratorTrait::getUrlGenerator Deprecated protected function Returns the URL generator service.
UrlGeneratorTrait::setUrlGenerator Deprecated public function Sets the URL generator service.
UrlGeneratorTrait::url Deprecated protected function Generates a URL or path for a specific route based on the given parameters.