GetmeUK / ContentTools

A JS library for building WYSIWYG editors for HTML content.
http://getcontenttools.com
MIT License
3.94k stars 393 forks source link

How to use assign ? #574

Open D-Kalck opened 2 years ago

D-Kalck commented 2 years ago

I'm trying to build a minimal HTML editor, in my HTML file I have some buttons and content-editable div like this :

<button id="tag_b">B</button>
<div id="text_prompt" contenteditable="true" data-editable data-name="main-content"></div>

The goal is when I click the button, the text selected in the div have the bold tag. In the doc I saw the method ContentTools.Tool.apply(element, selection, callback) In the source I saw that there is ContentTools.Bold.apply(element, selection, callback) So I tried something like this :

editable = document.getElementBiId('text_prompt');
ContentTools.Bold.apply(editable, ContentSelect.Range.query(editable));

It does not work because editable is not a member of ContentTools.Node, I tried to load the editor and to put the first region as the first argument of the apply method with no success. What is the right to do what I want to do ?

anthonyjb commented 2 years ago

CT tools can't be used against nodes directly the DOM node must be converted to a ContentEdit.Node instance. Each ContentEdit.Node class has a class method of fromDOMElement which can be used to convert a DOM node to a relevant instance, e.g:

const myNode = document.getElementById('my-node');
const myEditableNode = ContentEdit.fromDOMElement(myNode)
ContentTools.Bold.apply(myEditableNode, ContentSelect.Range.query(myNode));

However, the library isn't really designed to be used in this way so I'm not sure the above would be all that useful as a general solution here.

So there's 2 approaches I might recommend - you could either use the default editor but use CSS to make it appear how you want it to, you could changes the tools in the toolbox by updating the value of ContentTools.DEFAULT_TOOLS (https://github.com/GetmeUK/ContentTools/blob/master/src/scripts/namespace.coffee). This is a fairly simple approach and one I've used before to implement minimal page editors where more appropriate.

However, if you want full control then you need to look at the EditorApp class (https://github.com/GetmeUK/ContentTools/blob/master/src/scripts/editor.coffee) and basically implement a version of this that uses the UI you want to implement. That would be quite a big task.

If you are looking for really minimal editing features (bold, italic, link) there are libraries better suited I believe such as https://github.com/yabwe/medium-editor

D-Kalck commented 2 years ago

Thank you for your answer. I managed to do what I wanted. First, it seems that div Element are not allowed to be converted in editable Elements. So I added a

element to surround my text.

<button id="tag_b">B</button>
<div id="text_prompt" contenteditable="true" data-editable data-name="main-content"><p>Test test test test</p></div>

To convert my node to an editable node, I tried ContentEdit.fromDOMElement (it doesn't exist), I tried ContentEdit.Static.fromDOMElement (it's not the correct class for what I want) and it worked with ContentEdit.Text.fromDOMElement When I tried to apply I had this error :

Uncaught TypeError: this._domElement is null

That's because I added the third line :

var myTextNode = document.getElementById('text_prompt').firstChild;
myEditableTextNode = ContentEdit.Text.fromDOMElement(myTextNode);
myEditableTextNode._domElement = myTextNode;
ContentTools.Tools.Bold.apply(myEditableTextNode, ContentSelect.Range.query($('text_prompt')), function(){});

So I think there's a bug when we create an editable element from a DOM element.