codeslayer1 / react-ckeditor

CKEditor component for React with plugin and custom event listeners support
MIT License
130 stars 34 forks source link

Inline editor type #46

Closed MKietlinski closed 6 years ago

MKietlinski commented 6 years ago

Hi, is it possible to use react-ckeditor in inline mode? (https://sdk.ckeditor.com/samples/inline.html)

vgb0332 commented 6 years ago

If you read the source code, it's quite straight forward to understand the usage of the editor in react format. On the component you want to CKEDITORFY, call the CKEDITOR instance for the inline styling as mentioned in the official documentation on componentDidMount API. For example, Comp1 extends Component {

... componentDidMount() { //make sure window prefix is on window.CKEDITOR.inline( 'youreditorID' ); }

render(){ return (

); }

Make sure you give an id to the component you want to editorfy either giving an id or using refs whatever u prefer. Hope this helped.

Oh forgot to mention, you need to import react-ckeditor(of course) by adding script link to your root index file.

lveillard commented 6 years ago

Hello there! Not sure i'm able to follow your instructions @vgb0332 :S

1) I created a component called Editor where i call the CKeditor component. This component will be called from my app.js file to pop the editor in a div.

<CKEditor activeClass="p10" id="p10" content={this.props.activeArticle.Contenido} 
              scriptUrl = 'https://cdn.ckeditor.com/4.10.0/full/ckeditor.js'
...

2) In this Editor component i add the line window.CKEDITOR.inline( 'youreditorID' );

3) As CKEDITOR is not recognised, i add <script crossorigin src="https://cdn.ckeditor.com/4.10.0/full/ckeditor.js"></script> on my index.html (even tho it's already in the script url of my component)

But then, when i mount the component editor, and i get to the line window.CKEDITOR.inline( 'p10' ); i get TypeError: a is undefined. Do you know what I'm doing wrong?

Btw @codeslayer1 Your code is awesome! It simplifies so much the integration of CKEditor!

vgb0332 commented 6 years ago

Error seems to be coming fron the ckeditor library itself Based on ur codes i noticed u provide id on the component itself which i believe ur supposed to on the div tag.

In fact my answer does require this package but at the same time you dont directly use it u only use it for loading script. By including src script on your index html file you can acheive the same result without using this package.

If you are too confused about the way i did it I made a ckditor package of my own with ckeditor5 version. Check out react-ckeditor5-component m from npm

codeslayer1 commented 6 years ago

@saityro You are trying to set inline CKEditor the incorrect way. Here is the correct way to do it.

onInstanceReady(){
    var inlineCk = window.CKEDITOR.inline( 'editor1' );
    inlineCk.on( 'instanceReady', function( ev ) {
      var editor = ev.editor;
      editor.setReadOnly( false );
    });
}

render() {
    return (
        <div>
            <div id="editor1">Set inline editor</div>
            <CKEditor
               activeClass="hidden"
               events={{
                    instanceReady: this.onInstanceReady
               }}
             />
        </div>
    )
} 

Here editor1 is the id of the div that you want to set inline. The CKEditor below that is only used as a dummy to load the necessary CKEditor files and call the onInstanceReady function after all files are loaded (you will get an error if you try to set your inline CKEditor without first fetching the required files). I have given a class hidden to it. The hidden class should simply set the display of that component to none so that the dummy editor is not visible.

In the onInstanceReady function you need to set inline editor on your div and once the inline instance is ready, you need to setReadyOnly property to false so that your inline editor is editable.

Hope that helps. Let me know in case you still face issues.

lveillard commented 6 years ago

It works! And after a couple of hours i managed to adapt it to my app.

However i'm kind of new to react and i'm facing another problem;

ISSUE: If i run my app, and I load the old CKeditor classic component, and then the new inline ckeditor, everything is ok.

But if i load the new one without loading the old before, it gets some buttons and features broken.

So what usually was: imagen

Becomes: imagen And the buttons styles, format... just don't work.

Note1: If i do it the other way arround (loading the inline before the classic) the classic gets the same ugly problem Note2: Both are being loaded with the same config object Note3: I fixed the buttons loading
scriptUrl="https://cdn.ckeditor.com/4.10.0/full/ckeditor.js On the dumb ckeditor for some reason. Style, heading & size button remain broken tho Note4: removing the hidden classname (it means, showing the ckeditor component) solves the problem, It seems that loadiing that dummi ckeditor in hidden causes the problem.

OTHER INFO:

In case it helps somebody i explain what i did to adapt:

When i'm using the classic ckeditor, i'm saving/loading content from firebase (as html) that i send as props.

So i send the content at the creation of the ckeditor with: <CKEditor activeClass="p10" content={this.props.activeArticle.content} .... />

into the classic ckeditor and once is saved (onChange event changes some state that i'm sending after clicking Save button) and then i'm printing it in my jsx code.

 //by the way not sure if this is the correct way to go, looks ugly haha
                  <div 
                      dangerouslySetInnerHTML={{
                        __html: this.props.activeArticle.content
                      }}
                    />

1) Sending data to CKEDITOR: I managed to send my data to the new inline editor just adding the id to this div

 //not sure if this is the correct way to go
                  <div id="editor1"
                      dangerouslySetInnerHTML={{
                        __html: this.props.activeArticle.content
                      }}
                    />

2) Saving the content from the instance of inline CKEDITOR i changed the way i save, as i can't use onChange here i'm just doing: var testContent = window.CKEDITOR.instances["editor1"].getData(); to get the data and then i'm sending it to firebase.

codeslayer1 commented 6 years ago

Looks like your issue is solved @saityro, hence closing this issue. Feel free to re-open it in case you still face any problem.