2

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

elena
  • 123
  • 1
  • 11

0 Answers0