This is a migrated thread and some comments may be shown as answers.

Creating a custom Editor node with html inside

7 Answers 520 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
Martin
Top achievements
Rank 1
Veteran
Iron
Martin asked on 08 Apr 2021, 02:07 PM

Hello,

first I want to say that I have been trying to find the solution in this forum, on StackOverflow and in the examples posted by ProseMirror but so far I have been unable. I have tried some suggestions but non have helped me. If the answer is somewhere I have already looked (or not looked) I apologize.

I have a KendoReact Editor which can be pre-filled with a value from an API. This value can contain "custom tags" looking like this

${some_tag_key}

 

or like this

 <span style={{visibility: 'hidden'}}>$</span>some_tag_key<span style={{visibility: 'hidden'}}>$</span>

 

These tags are used by the API to parse a text for an email, and the editor is used to create difference standardized email templates. An example of a full text coming from the API would be:

<p>Hello ${receiver},</p>
 <p>Welcome to this page!</p>
 <p>
  Best regards<br>
  <span style={{visibility: 'hidden'}}>$</span>sender<span style={{visibility: 'hidden'}}>$</span>
 </p>

 

I also have a list of "custom tags" the user should be able add to the email template using a dropdown. I can focus on either of the above "tag types", and I don't need to support both.

I have some prerequisites:

  • The extra characters "${", "}" or "<span style={{..." should not be displayed in the editor, but must be present when getting the HTML from the editor when creating or updating a template.
  • The tags should have a different appearance than the rest of the text to distinguish them. They should have grey background and a darker grey border.
  • The tags should be draggable.

Therefore I am trying to create a custom node to put these tags in. My thought is that any tags coming from the API should be translated into this custom node, and any tags added using a dropdown should also be this custom node, and when exported to HTML have the code of a tag.

I have focused on the second solution ("<span style={{...") since it looked more straight forward to me, but I'm open to use the other one if it might be easier. This is what I have done so far: [https://stackblitz.com/edit/react-ts-1hlrqt](https://stackblitz.com/edit/react-ts-1hlrqt).

But now I am stuck. I have three questions:

  1. How do I get text coming from API to be translated into my custom node? Right now I don't see anything at all.
  2. How to I add a new node with the correct tag key to the editor? I understand that right now I'm adding a mark and not a noe, but I don't understand how to add a node instead.
  3. How do I translate my custom nodes back to the correct "tag code"?

Thanks in advance!

7 Answers, 1 is accepted

Sort by
0
Accepted
Nikolay
Telerik team
answered on 12 Apr 2021, 09:20 AM

Hello Martin,

We already have an example with similar functionality: https://www.telerik.com/kendo-react-ui/knowledge-base/add-custom-tools-to-the-editor-and-customize-built-in-tools/#toc-insert-non-editable-node. I think you will find the answers there.

Also see this example which I made: https://stackblitz.com/edit/react-y3dx71?file=app%2Fmain.jsx. It shows how to translate the custom tags into editor HTML node and back.

Please, let me know if I can help further.

Regards,
Nikolay
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

0
Martin
Top achievements
Rank 1
Veteran
Iron
answered on 12 Apr 2021, 10:08 AM

Hello Nikolay

Thanks a lot. This was exactly what I was looking for and it helped me a lot. Just one question:

I updated line 41 in your StackBlitz example to look be

state = { html: '<p>sample paragraph ${name} test</p>' };

but it does not seem to parse ${name} into a "nonEditable". See attached image Maybe I'm doing something wrong?

Again, thanks so much for this help, it really makes a huge difference!

0
Accepted
Nikolay
Telerik team
answered on 12 Apr 2021, 10:31 AM

Hello Martin,

The "${name}" tag needs to be parsed to HTML before it is inserted into the Editor. The getHtml and setHtml functions convert the "${some_tag_key}" tags into "nonEditable" tags and back - https://stackblitz.com/edit/react-y3dx71-fuxrtn?file=app%2Fmain.jsx.

const getHtml = (html) => {
    return html.replace(/<span [^>]+?class=\"uneditable\"[^>]+?>([^>]+?)<\/span>/gi, (_match, group) => {
      return '$' + group;
    });
  };

const setHtml = (html) => {
    return html.replace(/\$({[^}]+?})/g, (_match, group) => {
      return '<span contenteditable="false" class="uneditable" style="user-select: none; opacity: 0.5;">' + group + '</span>';
    });
  };

class App extends React.Component {
  state = { html: setHtml('<p>sample paragraph ${name} test</p>') };

Regards,
Nikolay
Progress Telerik

Тhe web is about to get a bit better! 

The Progress Hack-For-Good Challenge has started. Learn how to enter and make the web a worthier place: https://progress-worthyweb.devpost.com.

0
Martin
Top achievements
Rank 1
Veteran
Iron
answered on 12 Apr 2021, 10:47 AM

Hi Nikolay,

Thank you, this works perfect. Since I'm already asking, I have a related question. This is something that I counted on implementing later, but now that you seem to be online I might as well ask now.

I also would, if possible, have an "on-the-fly" parser, so that if the user types for example ${name}, it will be directly translated to a "nonEditable". Just for fun, I tried wrapping the "event.html" in a "setHtml" in the onChange method, but it did not seem to work.

Is this possible? And does this make the solution much more complex? This is not at all important but it would be a nice feature to have.

Thanks again for your help, it is so great to have someone who really explains and show how it works.

0
Accepted
Nikolay
Telerik team
answered on 13 Apr 2021, 02:47 PM

Hi Martin,

It is not something complex if you use an Input Rule. Here is an example - https://stackblitz.com/edit/react-y3dx71-r6qttk?file=app%2Fmain.jsx. Type ${name} and press space to test it.

Regards,
Nikolay
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

0
Martin
Top achievements
Rank 1
Veteran
Iron
answered on 13 Apr 2021, 03:42 PM

Thank you Nikolay!

This works wonderfully and exactly like I want it to work.

I just again need to way that I'm in awe of how great help I have gotten from you in this forum. You've actually taken time to help me find a solution and not just give me a "random generic pointer in some arbitrary direction". I hope you realize how rare that is. Keep up the wonderful work you do!

All the best
/Martin

0
Nikolay
Telerik team
answered on 15 Apr 2021, 11:11 AM

Hi Martin,

I am glad to hear that. Thank you for the kind words.

Regards,
Nikolay
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

Tags
General Discussions
Asked by
Martin
Top achievements
Rank 1
Veteran
Iron
Answers by
Nikolay
Telerik team
Martin
Top achievements
Rank 1
Veteran
Iron
Share this question
or