I have spent all day trying to get CKEditor with React to work. Everything seems to be okay except the images. I
I have a way to upload the images to my server already (azure). ALL I NEED is to know how to connect it to the CKEditor with React! I keep getting the error "Upload adapter is not defined."
<CKEditor
editor={ ClassicEditor }
data={this.state.body ? this.state.body : "<p>Body text...</p>"}
onInit={ editor => {
// You can store the "editor" and use when it is needed.
console.log( 'Editor is ready to use!', editor );
} }
onChange={ ( event, editor ) => {
const data = editor.getData();
console.log( { event, editor, data,}, "DATA" );
} }
// config={upload=this.uploadImage()}
/>
I'm guessing it has something to do with the config file? I already have the function that uploads the file and returns the URL, I just don't know where to add that into the CKEditor in React.
That error means there is no upload adapter connected.
First, you'll need to implement your own Custom Upload Adapter which handles uploading the images to the server. There’s a sample in this Stack Overflow response
And then, you link the editor to your upload adapter in your onInit method. Like so:
<CKEditor
editor={ClassicEditor}
data={this.state.body ? this.state.body : "<p>Body text…</p>"}
onInit={editor => {
// Connect the upload adapter using code below
editor.plugins.get("FileRepository").createUploadAdapter = function(loader) {
return new UploadAdapter(loader);
};
console.log("Editor is ready to use!", editor);
}}
onChange={(event, editor) => {
const data = editor.getData();
console.log({ event, editor, data }, "DATA");
}}
/>
UploaderAdapter in the code is the name of your UploadAdapter class implementation.
Related
I'm using the following JSX code with a custom CKEditor that I built using the online-builder When I add this editor to my node modules and try to use it like the following:
import React, { Component } from 'react';
//import Editor from 'ckeditor5-custom-build/build/ckeditor';
import ClassicEditor from '#ckeditor/ckeditor5-build-custom';
import { CKEditor } from '#ckeditor/ckeditor5-react'
const editorConfiguration = {
toolbar: [ 'heading', '|', 'bold', 'italic', 'underline', 'strikethrough', '|' ]
};
class App extends Component {
render() {
return (
<div className="App">
<h2>Using CKEditor 5 from online builder in React</h2>
<CKEditor
editor={ ClassicEditor }
config={ editorConfiguration }
data="<p>Hello from CKEditor 5!</p>"
onReady={ editor => {
// You can store the "editor" and use when it is needed.
console.log( 'Editor is ready to use!', editor );
} }
onChange={ ( event, editor ) => {
const data = editor.getData();
console.log( { event, editor, data } );
} }
onBlur={ ( event, editor ) => {
console.log( 'Blur.', editor );
} }
onFocus={ ( event, editor ) => {
console.log( 'Focus.', editor );
} }
/>
</div>
);
}
}
export default App;
I get an error stating that TypeError: this.props.editor.create is not a function. Is there some step that I am apparently missing? The help is much appreciated.
After hours of research online and trying to figure out where the custom build went wrong it turned out to be the most simple solution ever! In my custom build's src folder where the ckeditor.js file is located (containing the custom build before being built) I noticed at the bottom of the file it looked something like this export default { Editor, Watchdog }; Seeing this I immediately knew the solution was to import the custom editor as a named import. If you import it as a default import then you will not have any of the features of the editor but rather the entire export as shown above. Simple solution change the line that says import ClassicEditor from '#ckeditor/ckeditor5-build-custom'; to import {Editor as ClassicEditor} from '#ckeditor/ckeditor5-build-custom'; and now it will import the way it was meant to be imported.The interesting part about this, is that if you do not add Watchdog to your custom build (using the online-builder) then it should be imported as a default import as it will export as follows export default Editor;
I am using CKEditor5 React Component Framework.I have successfully integrated the CKEditor in my project.And Being Able to use it.
But the problem is that I have to save the Content of the editor to the database and then display it to website.. All I get in the content
<blockquote><p>Hello from CKEditor 5!</p></blockquote>
And While Displaying it does not applies the css of CkEditor to show ..
Setup for CKEDITOR IS
import React, { Component } from 'react';
import CKEditor from '#ckeditor/ckeditor5-react';
import Classiceditor from '#ckeditor/ckeditor5-build-classic';
export class ClassicEditor extends Component {
constructor(){
super();
this.state = {
content : ""
}
}
onCashange = data => {
console.log( "Called" );
this.setState({
content : data.getData()
})
}
render() {
Classiceditor.builtinPlugins.map( plugin => console.log(plugin.pluginName) );
console.log("State", this.state.content);
return (
<>
<div className='App'>
<h2> Using CKEditor</h2>
<CKEditor
editor = { Classiceditor }
data = "<p>Hello from CKEditor 5!</p>"
onInit = { editor => {
//console.log( 'Editor is ready to use!', editor )
} }
onChange = { ( event, editor ) => {
this.onCashange( editor );
// const data = editor.getData();
// this.onChange( data );
// //console.log( { event, editor, data } );
}}
onBlur = { editor =>
console.log("Blur", editor) }
onFocus = { editor => {
//console.log( "Focus", editor )
} }
/>
</div>
<div className='editor'>
{ this.state.content }
</div>
</>
)
}
}
export default ClassicEditor
There are 2 options:
Download or using script to get Full CSS and include it in your project.
Link here
Note: You have to add a parent container with a class name ck-content
Create a custom CKEditor 5 build from the source code with all the CSS (both UI and the content) extracted to a separate file
Advance Guide
You can see more here from the documentation:
Content Styles
React does not allow you to render html code directly. Instead you have to use dangerouslySetInnerHTML attribute to do so. Do the following to solve your problem,
<div dangerouslySetInnerHTML={this.createMarkup()} className='editor'></div>
and have a method on the class as
createMarkup = () => {
return { __html: this.state.content };
}
This will make sure that you are not rendering the raw HTML to the page.
You can read more about this here
you can just install npm package like npm i react-render-html
enter link description here
and use it like :
<div className='...'>
{renderHTML(someHTML)}
</div>
Here is an answer to above question:
<div style={{wordWrap:'break-word',display:'inline-block'}}>
<div className="editor" dangerouslySetInnerHTML={{_html:this.state.content}}/>
</div>
Good day,
I am wanting to Use FilePond with Reactjs to facilitate image uploads to a server.What I want is to have the file populate in the Pond like the description shows then for the upload button to appear for the user to upload the file.
Initially from using their demo code I noticed that it would auto-upload files and from reading the documentation I see that I disable that auto upload feature using "instantUpload={false}" in my server. However I have done this and I still don't have an upload button for the user to use. I read the documentation some more and they say I need to specify the server which I have . Is there something that I am missing to show the upload button in my code.
Code below:
import React, { Component } from "react";
/*import agent from "superagent";*/
import classNames from "classnames";
import cookie from 'react-cookies';
// Import React FilePond
import { FilePond, registerPlugin } from "react-filepond";
// Import FilePond styles
import "filepond/dist/filepond.min.css";
// Import the Image EXIF Orientation and Image Preview plugins
// Note: These need to be installed separately
import FilePondPluginImageExifOrientation from "filepond-plugin-image-exif-orientation";
import FilePondPluginImagePreview from "filepond-plugin-image-preview";
import "filepond-plugin-image-preview/dist/filepond-plugin-image-preview.css";
// Register the plugins
registerPlugin(FilePondPluginImageExifOrientation, FilePondPluginImagePreview);
export default class FotoUpload extends Component {
constructor(props) {
super(props);
this.state = {
// Set initial files, type 'local' means this is a file
// that has already been uploaded to the server (see docs)
files: [
{
source: "index.html",
options: {
type: "local"
}
}
]
};
}
handleInit() {
console.log("FilePond instance has initialised", this.pond);
}
render() {
return (
<div className="App">
{/* Pass FilePond properties as attributes */}
<FilePond
ref={ref => (this.pond = ref)}
allowFilePoster={true}
instantUpload={false}
server=
{
{
url: 'http://mybackend.com:5000/upload/images',
process: {
headers: {
'cookie-token': cookie.load('cookie')
},
}
}
}
name="image"
acceptedFileTypes={['image/*']}
oninit={() => this.handleInit()}
onupdatefiles={fileItems => {
// Set currently active file objects to this.state
this.setState({
files: fileItems.map(fileItem => fileItem.file)
});
}}
/>
</div>
);
}
}
If I allow the instaupload feature the file will upload and success will return , but I will still not receive an Upload button.
Myimage
As you can see there isn't an upload button like shown in the offical documentation.
Similar problem
https://github.com/pqina/vue-filepond/issues/5
FilePond Documentation
https://pqina.nl/filepond/docs/patterns/api/server/
Official repo
https://github.com/pqina/react-filepond
The code is as follows.
import CKEditor from '#ckeditor/ckeditor5-react';
import ClassicEditor from '#ckeditor/ckeditor5-build-classic';
render() {
let selectedDocument = this.state.documentDetails;
return (
<div>
<div>
{
selectedDocument.html_content &&
<div className="form-group">
<CKEditor
editor={ ClassicEditor }
data={selectedDocument.html_content }
onInit={ editor => {
} }
onChange={ ( event, editor ) => {
const data = editor.getData();
let obj = {
target: {
name: 'html_content',
value: data
}
}
this.handleChange(obj);
} }
/>
</div>
}
</div>
</div>
);
}
Using the above code, the editor is displayed with basic toolbar buttons.
Now I need to add a new button to the toolbar which when clicked a javascript function needs to be called.
I have seen documentation on creating custom plugins, but I am not sure on how to implement this in the react way.
Any ideas on how to implement this? A sample piece of code would e really helpful.
Find config.js in CKEditor folder and update config.extraPlugins with your plugin like config.extraPlugins = 'html5video,widget,widgetselection,clipboard,lineutils,videoembed';
It will display new toolbar or button on CKEditor.
I am attempting to integrate CKEditor into our React.js project, using the component found here: https://github.com/ckeditor/ckeditor5-react.
I have used this code in the git repository to define the CKEditor component:
https://github.com/ckeditor/ckeditor5-react/blob/master/src/ckeditor.jsx
And inside my code, I am referencing the component:
import CKEditor from '#ckeditor/ckeditor5-react';
import ClassicEditor from '#ckeditor/ckeditor5-build-classic';
const TemplateForm = props => {
return (
<div>
/* Other form fields */
<CKEditor
name="body"
placeholder="Compose message"
content={ props.defaults.body }
value={ props.defaults.body }
errors={ props.errors.body }
onInput={ props.onInput }
onChange={ props.onValueChange }
/>
</div>
);
};
When I load my page, I get a javascript error "Cannot read property 'create' of undefined" from ckeditor.js - the "this.props.editor" value is not defined. I'm a newbie to react, so I'm sure I'm just missing something pretty straightforward. Suggestions?
Your error is from the component (CKEditor) expecting a prop with the key 'editor', which you're not currently supplying.
You can probably find a list of options in their docs, but checking their repo I found this example where they're setting the editor to ClassicEditor which you're already importing:
https://github.com/ckeditor/ckeditor5-react/blob/master/sample/index.html
So this should work:
<CKEditor
name="body"
placeholder="Compose message"
content={ props.defaults.body }
editor={ ClassicEditor }
value={ props.defaults.body }
errors={ props.errors.body }
onInput={ props.onInput }
onChange={ props.onValueChange }
/>