Drupal 8 custom module from with ajax and template override

Viewed 1112

I'm creating a module that has a custom admin 2-col page that uses ajax to populate a div, showing content based on a dropdown selection before form submission.

It all works fine, and I can see the container updated by ajax.

But when I try use a custom template for 2-col layout, I get the following inserted into the container:

An unrecoverable error occurred. The uploaded file likely exceeded the maximum file size (50 MB) that this server supports.

There are no watchdog messages or log details, so this might suggest an apache configuration issue (https://www.drupal.org/forum/support/post-installation/2013-02-27/an-unrecoverable-error-occurred-the-uploaded-file-likely), but mod_security does not appear to be enabled, and the form does not contain any files and it's no way near 50MB! So I don't know where this is coming from. This is currently in my dev environment on my laptop and I've not faced this before, so I don't think apache config is an issue.

It strikes me that there may be a core bug in the form API for ajax with custom templates, because it works fine without a custom template... unless I'm implementing the custom template incorrectly.

A possible workaround would be to use CSS for force the container onto the RHS, but this should ideally be in the template so that admin themes can work with it.

I've put the code in pastebin: https://pastebin.com/F1zkd5rg.

or listed below:

my_module.links.menu.yml

my_module.main:
  route_name: my_module.main
  title: My Module
  parent: system.admin
  weight: -6
my_module.form_page:
  route_name: my_module.form_page
  title: My Module Form
  parent: my_module.main
  weight: -6

my_module.routing.yml

my_module.main:
  path: '/admin/my_module'
  defaults:
    _controller: 'Drupal\system\Controller\SystemController::systemAdminMenuBlockPage'
    _title: 'My Module'
  requirements:
    _permission: 'administrator'
my_module.form_page:
  path: '/admin/my_module/form'
  defaults:
    _form: 'Drupal\my_module\Form\MyModuleForm'
    _title: 'My Module Form'
  requirements:
    _permission: 'administrator'

my_module.module

<?php
/**
 * Implements hook_theme_registry_alter
*/
function my_module_theme($existing, $type, $theme, $path) {
  return [
    'my_module_form' => [
      'render element' => 'form',
    ],
  ];
}

templates/my-module-form.html.twig

<form {{ attributes }}>
  <div class="layout-column layout-column--half">
    {{ form.user_view }}
    {{ form.submit }}
  </div>
  <div class="layout-column layout-column--half">
    {{ form.user_list_wrapper }}
  </div>
</form>

src/Form/MyModuleForm.php

<?php
/**
 * @file
 * Contains \Drupal\my_module\Form\MyModuleForm.
 */
namespace Drupal\my_module\Form;

use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\HtmlCommand;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\views\Views;

/**
 * Configure custom_rest settings for this site.
 */
class MyModuleForm extends FormBase {

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

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    ...

    $form['#theme'] = 'my_module_form';

    $form['user_view'] = [
      '#type' => 'select',
      '#title' => $this->t('Select element'),
      '#options' => $userViews,
      '#ajax' => [
        'callback' => '::findUsers',
        'event' => 'change',
        'wrapper' => 'edit-user-list',
        'progress' => array(
          'type' => 'throbber',
          'message' => t('Searching Users...'),
        ),
      ],
    ];
    $form['user_list_wrapper'] = [
      '#type' => 'container',
      '#attributes' => array(
        'class' => array(
          'user-list-wrapper',
        ),
      ),
    ];
    $form['user_list_wrapper']['user_list'] = [
      '#type' => 'item',
      '#attributes' => [
        'id' => ['user_list'],
      ],
      '#markup' => '<ul><li><a href="#">None</a></li></ul>'
    ];
    $form['submit'] = [
      '#type' => 'submit',
      '#value' => t('Submit'),
    ];

    return $form;
  }

  /**
 * Ajax callback to list users.
 */
  public function findUsers(array &$form, FormStateInterface $form_state) {
    // Create the user list HTML
    $selected = $form_state->getValue('user_view');
    ...
    $user_list = '';
    ...
    if (strlen($user_list) == 0) {
      $user_list = 'None';
    } else {
      $user_list = "<ul>$user_list</ul>";
    }

    // Generate the AJAX response
    $ajax_response = new AjaxResponse();
    $ajax_response->addCommand(new HtmlCommand('#edit-user-list', $user_list));
    return $ajax_response;
  }

  public function submitForm(array &$form, FormStateInterface $form_state) {
    drupal_set_message('Nothing Submitted. Just an Example.');
  }
}

Thanks in advance

0 Answers
Related