Skip to main content

AjaxResponse

Displaying 1 - 5 of 5

Open Ajax Modal Dialog from Controller

Dialogs are often called dialog boxes, modal windows, or pop-up windows. 
Whatever you call them, they are a quick and easy way to display additional information without reloading the entire page. 
Dialog boxes can display just some static text, any node or form of your page, a views page, or any custom markup you'll feed them. 

DrupalVIP technical notebook & support

        public function requestResidenceUpload(Request $request): AjaxResponse {
            $arg = $request->get('arg1');
            
            // Add an AJAX command to open a modal dialog with the form as the content.      
            $response = new AjaxResponse();
            $modal_form = $this->formBuilder->getForm('Drupal\mymodule\Form\MyForm', $arg);
            $response->addCommand(new OpenModalDialogCommand('Upload', $modal_form, ['width' => 600, 'height'=>600]) );
            return $response;        
        } 

Display Forms in a Modal Dialog

Display create a node in a modal dialog

By default when creating a node, the save action will redirect the user to another page but if we want to just close the modal dialog and leave the user on the same page we need to tell the form to do that.

For this we are going to alter the form and add an AJAX command letting Drupal know that we want to close the dialog as soon as the node is created.

use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\CloseModalDialogCommand;
use Drupal\Core\Ajax\RedirectCommand;

/**
 * Implements hook_form_alter().
 */
function modal_form_example_form_node_article_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  $form['actions']['submit']['#submit'][] = '_modal_form_example_ajax_submit';
  $form['actions']['submit']['#attributes']['class'][] = 'use-ajax-submit';
  // in some cases this was needed:
  // $form['#attached']['library'][] = 'core/jquery.form';
  // $form['#attached']['library'][] = 'core/drupal.ajax';
}

/**
 * Close the Modal and redirect the user to the homepage.
 *
 * @param array $form
 *   The form that will be altered.
 * @param \Drupal\Core\Form\FormStateInterface $form_state
 *   FormState Object.
 */
function _modal_form_example_ajax_submit(array $form, FormStateInterface &$form_state) {
  $response = new AjaxResponse();
  $response->addCommand(new CloseModalDialogCommand());
  $form_state->setResponse($response);
}

Select Element, its more hard to deal with Ajax

Drupal Form Select element is harder to deal with when desired to add to it Ajax activities

Ajax is a bit misleading, it's not all on the client side, and if we still want to handle it from the code which is located on the server, e/s program it with the form objects like $form & $form_state it still needs to update the server side within the flow, and the form is still need to have synchronization transactions between the client, server, and cache

not enough documentation on that, especially when working with specific elements like SELECT

    public function buildForm(array $form, FormStateInterface $form_state, $dashboard = 0, $project=0, $sprint=0, $redirect='') {  //
      $config = \Drupal::config('drupalvip_task.settings');
      $log = $config->get('log');
      ($log)? \Drupal::logger("drupalvip_task")->debug(__FUNCTION__ . ": START "):'';      
      ($log)? \Drupal::logger("drupalvip_task")->debug("Form Args: da[$dashboard] pr[$project] sp[$sprint] rd[$redirect]"):'';
      
      $form['redirect'] = array(
          '#type' => 'value',
          '#value' => $redirect,
      );
      
      //dashboard select
      $dashboard_default = ($dashboard==0) ? null : $dashboard;
      $dashboard_options = DashboardController::getDashboards();
      $form['dashboard_select'] = [
        '#type' => 'select',
        '#title' => t('Dashboard'),
        //'#name' => 'dashboard-select',  <-- prevent the form_state to update
        '#options' => $dashboard_options,
        '#sort_options' => TRUE,
        '#required' => TRUE,
        '#empty_option' => "-- SELECT --",
        '#size' => 1,
        '#default_value' => $dashboard_default,
        '#attributes' => [
          'class' => ['use-ajax'],
          //'id' => "edit-dashboard-select", <-- this prevent the callback
        ],         
        '#ajax' => [
          'callback' => '::submitFormDashboardSelected',
          'wrapper' => 'group-select-wrapper',
          'suppress_required_fields_validation' => TRUE,
        ],        
      ];      
      
      $form['group'] = [
        '#type' => 'fieldgroup',
        '#prefix' => '<div id="group-select-wrapper">',
        '#suffix' => '</div>',         
      ];      
        $options[0] = "-- select --";        
        $form['group']['project_select'] = [
          '#type' => 'select',
          '#title' => $this->t('Project'),
          '#options' => $options,
          '#limit_validation_errors' => [],
          //'#empty_option' => "-- select --",
          '#size' => 1,        
          '#default_value' => 0, 
        ]; 
        if ($dashboard > 0) {
          $project_options = DashboardController::getProjects($dashboard);
          $project_options_2 = $options + $project_options ;
          $form['group']['project_select']['#options'] = $project_options_2; //$project_options; 
          $form['group']['project_select']['#default_value'] = $project;
        }      

        $form['group']['sprint_select'] = [
          '#type' => 'select',
          '#title' => $this->t('Sprint'),
          '#options' => $options,
          '#limit_validation_errors' => [],
          //'#empty_option' => "-- select --",
          '#size' => 1,        
          '#default_value' => 0, 
        ]; 
        if ($dashboard > 0) {
          $sprint_options = DashboardController::getSprints($dashboard);
          $sprint_options_2 = $options + $sprint_options ;
          $form['group']['sprint_select']['#options'] = $sprint_options_2; 
          $form['group']['sprint_select']['#default_value'] = $sprint;
        }      
        
      $form['subject'] =  [
        '#type' => 'textfield',
        '#title' => $this->t('Subject'),
        '#required' => TRUE,
        '#attributes' => [
          //'id' => "task-subject-box",
        ],        
      ];
      
      $form['actions'] = [
        '#type' => 'actions',
        '#attributes' => [
          'class' => ['form_actions'],
        ],         
      ];
        $form['actions']['cancel'] = [
          '#type' => 'submit',
          '#value' => $this->t('Cancel'),
          '#attributes' => [
            'class' => ['button','use-ajax','form-submit-modal','action-cancel' ],
          ],
          '#ajax' => [
            'callback' => [$this, 'submitFormClose'],
            'event' => 'click',
          ],
        ];       
        $form['actions']['create'] = [
          '#type' => 'submit',
          '#value' => $this->t('Create'),
          '#attributes' => [
            'class' => ['button','use-ajax','form-submit-modal','action-create' ],
          ],
          '#ajax' => [
            'callback' => [$this, 'submitFormCreate'],
            'event' => 'click',
            'onclick' => 'javascript:var s=this;setTimeout(function(){s.value="Saving...";s.disabled=true;},1);',
          ],
        ];              

      $form['#attributes']['class'][] = 'drupalvip_form';  
      $form['#attached']['library'][] = 'drupalvip_task/content';
      $form['#attached']['library'][] = 'core/drupal.dialog.ajax';
      $form['#attached']['library'][] = 'core/drupal.ajax';
      $form['#attached']['library'][] = 'core/jquery.form';
      
      ($log)? \Drupal::logger("drupalvip_task")->debug(__FUNCTION__ . ": RETURN FORM "):'';
      return $form;    
    }

Select Element with AJAX updating form dynamically

Using AJAX callbacks to dynamically react on user input, alter form elements, show dialog boxes or run custom Javascript functions.

Ajax is the process of dynamically updating parts of a page's HTML based on data from the server without requiring full page refresh. You can find events triggering Ajax requests all over Drupal.

<?php
  namespace Drupal\drupalvip\Form;

  use Drupal\Core\Form\FormBase;
  use Drupal\Core\Form\FormStateInterface;
  
  class AjaxForm extends FormBase {    

    public function getFormId() {
      return 'mymodule_ajax_form';
    }

    public function buildForm(array $form, FormStateInterface $form_state) {
      $triggering_element = $form_state->getTriggeringElement();

      $form['country'] = [
        '#type' => 'select',
        '#title' => $this->t('Country'),
        '#options' => [
          'serbia' => $this->t('Serbia'),
          'usa' => $this->t('USA'),
          'italy' => $this->t('Italy'),
          'france' => $this->t('France'),
          'germany' => $this->t('Germany'),
        ],
        '#ajax' => [
          'callback' => [$this, 'reloadCity'],
          'event' => 'change',
          'wrapper' => 'city-field-wrapper',
        ],
      ];

      $form['city'] = [
        '#type' => 'select',
        '#title' => $this->t('City'),
        '#options' => [
          'belgrade' => $this->t('Belgrade'),
          'washington' => $this->t('Washington'),
          'rome' => $this->t('Rome'),
          'paris' => $this->t('Paris'),
          'berlin' => $this->t('Berlin'),
        ],
        '#prefix' => '<div id="city-field-wrapper">',
        '#suffix' => '</div>',
        '#value' => empty($triggering_element) ? 'belgrade' : $this->getCityForCountry($triggering_element['#value']),
      ];

      return $form;
    }

    public function reloadCity(array $form, FormStateInterface $form_state) {
      return $form['city'];
    }

    protected function getCityForCountry($country) {
      $map = [
        'serbia' => 'belgrade',
        'usa' => 'washington',
        'italy' => 'rome',
        'france' => 'paris',
        'germany' => 'berlin',
      ];
      return $map[$country] ?? NULL;
    }

    public function submitForm(array &$form, FormStateInterface $form_state) {  }

} // end of class

Drupal has adopted Ajax, review how it implemented in Forms

Drupal has adopted Ajax - full integration

Ajax is the process of dynamically updating parts of a page's HTML based on data from the server. 
When a specified event takes place, a PHP callback is triggered, which performs server-side logic and may return updated markup or JavaScript commands to run. 
After the return, the browser runs the JavaScript or updates the markup on the fly, with no full page refresh necessary.

Many different events can trigger Ajax responses, including Clicking a button, Pressing a key, Moving the mouse

$response = new AjaxResponse(); 
$response->addCommand(new ReplaceCommand('#edit-date-format-suffix', '<small id="edit-date-format-suffix">' . $format . '</small>')); 
return $response;
'#ajax' => [
  'callback' => 'Drupal\config_translation\FormElement\DateFormat::ajaxSample',
  'event' => 'keyup',  
  'progress' => [ 'type' => 'throbber', 'message' => NULL,  ], 
],