Froala editor: insert into caret position when clicking a div
Asked Answered
S

4

6

I'm using Froala v2.6.1 and I want to insert a string into the editor exactly at the last caret position when user click a divs, but the string is always inserted at the end of the editor.

Here is the thing I did:

<div class="variable" data-value="{{user_id}}">USER ID</div>

Jquery:

$('div.variable').click(function() {
    $("#template_editor").froalaEditor('html.insert', $(this).data('value'), true); 
});

Anyone know how to solve this would be great help.

Semicircle answered 1/6, 2017 at 16:8 Comment(1)
You can add a custom button to froala toolbar, like in this example: froala.com/wysiwyg-editor/examples/insert-htmlMillrace
S
2

It looks you have an external button there. For that the editor has a built-in mechanism, highlighted in a demo. In your case it would be something like this:

$('#template_editor')
  .on('froalaEditor.initialized', function (e, editor) {
    editor.events.bindClick($('body'), 'div.variable', function (ev) {
      var that = ev.originalEvent && ev.originalEvent.originalTarget;
      editor.html.insert($(that).data('value'));
    });
  })
  .froalaEditor()
Selfaggrandizement answered 10/7, 2017 at 8:36 Comment(0)
E
12

It looks like you are loosing the context of caret. I had the same problem (Even in V3) where in i had to click an external button which would open a popup and in the popup user would select a html template which had to be inserted into the last known caret postilion.

What i did was save the caret position using selection save, open popup, get the text and restore the selection and then do html.insert

1) First save the selection

// Call this before doing any kind of insert operation
editor.selection.save();

2) Restore the selection and then insert html

// Restore the selection
editor.selection.restore();
editor.html.insert(data.Body);

Hope this helps

Eelpout answered 24/6, 2019 at 12:19 Comment(3)
This is exactly what I needed. Had essentially the same exact use-case as you it seems. Thanks!Hazel
I put editor.selection.save() in 'blur' event, so every time editor lose focus I save it cursor position and restore it if I need do insertSupportable
Legend. Thanks @guru !Inkhorn
S
2

It looks you have an external button there. For that the editor has a built-in mechanism, highlighted in a demo. In your case it would be something like this:

$('#template_editor')
  .on('froalaEditor.initialized', function (e, editor) {
    editor.events.bindClick($('body'), 'div.variable', function (ev) {
      var that = ev.originalEvent && ev.originalEvent.originalTarget;
      editor.html.insert($(that).data('value'));
    });
  })
  .froalaEditor()
Selfaggrandizement answered 10/7, 2017 at 8:36 Comment(0)
C
1

In case someone is looking information about Froala v3 and with React I had this exactly some problem and couldn't get it work how I wanted. Froala always creates newline before inserting html. My problem is probably related to opening a custom modal through plugin method so then Froala loses context. Here are some fixes I tried:

Inside custom plugin save the cursor position using: this.selection.save();

Then try first if this solves your problem, if not please follow along. Before inserting the HTML restore selection insert html and undoSavestep to get Froala update.

this.selection.restore();
this.html.insert(html);
this.undo.saveStep();

Full example in React:

Froala.RegisterCommand('customcommand', {
        title: mytitle,
        focus: true,
        undo: true,
        refreshAfterCallback: true,
        callback(_, val) {
            this.selection.save();
            return displayDialog((removeDialog) => ({
                children: (
                    <DialogComponent
                        removeDialog={removeDialog}
                        submit={(html) => {
                            removeDialog();
                            this.selection.restore();
                            this.html.insert(html);
                        }}
                    />
                ),
            }));
        },

If this doesn't help then you can try putting it inside promise example of callback:

  callback: function () {
            this.selection.save();
            let result = new Promise((resolve) => {
                displayDialog((removeDialog => ({
                    children: (
                        <DialogComponent
                            removeDialog={removeDialog}
                            submit={(html) => {
                                removeDialog();
                                resolve(html);
                            }}
                        />
                    ),
                })));
            });
            result.then((html) => {
                this.selection.restore();
                this.html.insert(html);
                this.undo.saveStep(); // Make froala update https://github.com/froala/wysiwyg-editor/issues/1578
            });

This is the closest thing I have got so far. This appends the element almost to the correct position. I just don't understand why the caret position doesn't stay in place and Froala always appends to the bottom of the editor. If anyone else has better ideas I am looking for answer as well.

Crumbly answered 23/4, 2020 at 4:21 Comment(0)
C
0

I had the same problem. My scenario was: click inside the editor -> click on a toolbar button -> modify editor content inside a dialog -> save modified content into the editor. The editor was loosing context while working in the dialog. I fixed it by placing a marker at the beginning of work .froalaEditor('html.insert', '{MARKER}') and use the marker afterwards to know the last caret position.

Or you can use selection.save and selection.restore methods: https://www.froala.com/wysiwyg-editor/examples/selection

Cellulose answered 22/2, 2019 at 6:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.