-->

How to dynamically switch text direction in CKEdit

2020-07-23 18:34发布

问题:

On my current project, users can type text in English and Hebrew languages. Would be great to define direction automatically, according to the current text. For example, if the text contains Hebrew symbols, the direction should be RTL. But if the text doesn't contain Hebrew, then the direction is LTR.

Text can be changed at any moment, and I think that the best solution is to switch the direction dynamically like it works in the Google Translate service.

回答1:

I didn't find already done solution and I want to propose my own.

It works pretty simply. Each time, when text has been changed, I'm checking it for Hebrew symbols and I change the text direction if need. To apply changes in config (in my case it's direction of the text), I should destroy and init CKEditor with updated config.

How you can test it:

  1. Try to type something in English
  2. Try to type something in Hebrew, for example, "שם"
  3. Try to remove Hebrew symbols
  4. You will see how the direction in editor will be changed according to current text

Here is the code:

var CKEditorConfig = {
    contentsLangDirection: 'ltr',
    forcePasteAsPlainText: true
  },
  editorInstance;

(function () {   
  // Initialise editor.
  function initEditor() {
    editorInstance = CKEDITOR.replace('editor', CKEditorConfig);
    editorInstance.on('contentDom', function () {
      var body = this.document.getBody();

      // These listeners will be deactivated once editor dies.
      // Input event to track any changes of the content
      this.editable().attachListener(body, 'input', function () {
        editorOnChange();
      });
    });
  }
  
  // On change callback.
  function editorOnChange() {
  	var text = CKEDITOR.instances['editor'].getData(),
        direction = isHebrew(text) ? 'rtl' : 'ltr',
        currentDirection = CKEditorConfig.contentsLangDirection;

      // Direction was changed -> reinit CKEditor.
      if (currentDirection && currentDirection != direction) {      	
        CKEditorConfig.contentsLangDirection = direction;
        CKEDITOR.instances['editor'].destroy();
        editorInstance = initEditor();
      }
  }
  
  // Checks is current text uses hebrew language or not.
  function isHebrew (text) {
    const HebrewChars = new RegExp("[\u05D0-\u05FF]+");

    if (!HebrewChars.test(text)) {
      return false;
    }
    return true;
  }
  
  // Init editor.
  initEditor();

})();
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
<script src="https://cdn.ckeditor.com/4.7.1/basic/ckeditor.js"></script>

<body>
  <textarea id="editor" cols="50" rows="20"></textarea>
</body>

Seems CKEditor cannot be launched here. I see some error. You can try to launch it right on JSFiddle

One problem: strange but event "input" is not launched for operations like copy-paste in this example, but work in my current application. Seems versions of libraries are the same. But it's not very important for this example.

I hope it will be useful for somebody.