I'm new to react and slate and I'm trying to change editor text via jquery and make sure that the change is also reflected in the editor content.
When I select a text (07/27/21, for example) on the editor and click on button Set date in my example project:
- onChange() fired (OK)
- selection in the editor highlighted (OK) the
- editor content changed (as you can see on console) (OK)
If I click on button Test, highlighted text changed to "This is a test" via jquery, but:
- onChange() not fired :(
- the editor content not changed (as you can see on console) :(
and...
if I select highlighted text (changed via jquery to "This is a test") I got the error
Error: Cannot resolve a DOM point from Slate point: {"path":[0,0],"offset":86}
so, what am I doing wrong?
Any help would be apreciated, Elena
this is my code:
import React, { useCallback, useState, useMemo } from 'react'
import { createEditor, Editor, Transforms, Text } from 'slate'
import { Slate, Editable, withReact } from 'slate-react'
import { withHistory } from 'slate-history'
import $ from 'jquery'
import './index.css';
const Helpers = {
isDuedateActive(editor) {
const [match] = Editor.nodes(editor, {
match: n => n.duedate === true,
})
return !!match
},
toggleDuedateMark(editor) {
const isActive = Helpers.isDuedateActive(editor)
Transforms.setNodes(
editor,
{ duedate: isActive ? null : true },
{ match: n => Text.isText(n), split: true }
)
},
}
const PlainTextExample = () => {
const [value, setValue] = useState(initialValue)
const editor = useMemo(() => withHistory(withReact(createEditor())), [])
const renderLeaf = useCallback(props => <Leaf {...props} />, [])
return (
<div>
<button
onMouseDown={event => {
event.preventDefault();
console.log($('span.calendar span').text());
$('span.calendar span').text('this is a test');
console.log($('span.calendar span').text());
}}
> Test
</button> <br /><br />
<div id="mioeditor">
<Slate
editor={editor}
value={value}
state = {value}
onChange={newvalue => {
console.log("onChange fired")
setValue(newvalue)
// Save the value to Local Storage.
const content = JSON.stringify(newvalue)
console.log("JSON.stringify(editorContent)=" + content)
}
}
>
<button
onMouseDown={event => {
event.preventDefault()
Helpers.toggleDuedateMark(editor)
}}
> Set Date
</button>
<Editable placeholder="Enter some plain text..." renderLeaf={renderLeaf} />
</Slate>
</div>
</div>
)
}
const initialValue = [
{
type: 'paragraph',
children: [
{ text: 'This is editable plain text, just like a <textarea>! And this is a date 07/27/21' },
],
},
]
const Leaf = ({ attributes, children, leaf }) => {
/* se trovo duedate = true nei figli di un nodo, lo innesto in un tag con una classe 'duedate' che
mette sfondo giallino alla selezione e affianco un datepicker jquery; la funzione js che abilita il datepicker è definita nel file <root app>/public/index.html */
if (leaf.duedate) {
var myval = '';
try{
myval = children.props['leaf'].text;
}
catch (error)
{
console.log(error);
}
return <span {...attributes} className="calendar">{children}<input type="hidden" name="date" className="duedate" placeholder="dd/mm/yyyy" value={myval} readOnly={true}/></span>
}
return <span {...attributes}>{children}</span>
}
export default PlainTextExample
this is the example project: https://drive.google.com/file/d/16pQxfFJ6-As8lR9yT_lT92jjrCDffhi1/view?usp=sharing
UPDATE: there is also a sandbox with example project at https://codesandbox.io/s/slate-reproductions-forked-2yx13?file=/index.js