0

I am using Drupal 8's Ajax API to update form fields in a form depending on the input in another field. One of the fields I want to update is a text_format field that uses Drupal's ckeditor.

If I understand the CKEditor API correctly, I should be able to update the text in the ckeditor widget using the setData() method (https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_editor.html#method-setData). The ckeditor instance should be the textarea id - and that I can easily identify in my AjaxResponse function.

However, I am not sure how to use Drupal's invokeCommand() to make use of the CKEditor API?

0

In the end I was able to solve this using a custom Ajax command:

  1. In our custom module (called b47_custom_authors) we created a custom ajax command in src/Ajax/B47CustomAjax.php

    /**
     * @file
     * Contains \Drupal\b47_custom_authors\Ajax\B47CustomAjax.
     */
    
    namespace Drupal\b47_custom_authors\Ajax;
    
    use Drupal\Core\Ajax\CommandInterface;
    
    class B47CustomAjax implements CommandInterface
    {
    
      /**
       * A CSS selector string.
       *
       * If the command is a response to a request from an #ajax form element then
       * this value can be NULL.
       *
       * @var string
       */
      protected $selector;
    
      /**
       * An optional list of arguments to pass to the method.
       *
       * @var array
       */
      protected $arguments;
    
      /**
       * Constructs an b47customajax object.
       *
       * @param string $selector
       *   A jQuery selector.
       * @param array $arguments
       *   An optional array of arguments to pass to the method.
       */
      public function __construct($selector, array $arguments = []) {
        $this->selector = $selector;
        $this->arguments = $arguments;
      }
    
      public function render(){
        return [
          'command' => 'b47customajax',
          'selector' => $this->selector,
          'args' => $this->arguments,
        ];
      }
    }
    
  2. The custom js (in js/b47customajax.js) is as follows:

    Drupal.AjaxCommands.prototype.b47customajax = function (ajax, response) {
    
    // response is an array with the keys
    // response.command: the command called (b47customajax)
    // response.selector: the selector to be used (NULL)
    // response.args: the arguments to be passed as an array: 0: the ckeditor instance, 1: the text (data) to be passed
    
    var ajaxckeditorinstance = response.args[0];
    var ajaxckeditordata = response.args[1];
    var editor;
    
    var instance = CKEDITOR.instances[ajaxckeditorinstance];
    
    if (instance) {
       // Trying to call setData method: https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_editor.html#method-setData
       editor = instance.setData( ajaxckeditordata , {
              callback: function() {
                          this.checkDirty(); // true
                      }
              });
    
    };
    

    };

  3. In my ajax callback function I call my custom ajax via:

$response->addCommand(new \Drupal\b47_custom_authors\Ajax\B47CustomAjax('textarea'.$fieldid,[$fieldid, $texttobeinserted]));

The $fieldid is the id of the textarea, and @texttobeinserted is the full html of the text I want in ckeditor.

This now allows me to update the ckeditor based on the text dynamically via my AjaxResponse. The textfield is hidden by default and depending on the input in another field I fetch the text that needs to be placed in the textarea/ckeditor. The form field is then also displayed.

This now works.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.