ckeditor5 icon indicating copy to clipboard operation
ckeditor5 copied to clipboard

I Feel I cant able to add button with javascript its only for npm

Open vizvasrj opened this issue 1 year ago • 3 comments

function MyCustomTimestampPlugin(editor) {
    editor.ui.componentFactory.add( 'timestamp', () => {
        // The button will be an instance of ButtonView.
        const button = new editor.buttonView()
        

        button.set( {
            label: 'Timestamp',
            withText: true
        } );

        return button;

    
    } );

};

**I need Javascript method ?? Not Npm all the document about creating custome plugin is in npm, 
Is it possible to add it with javascript** 

vizvasrj avatar Sep 04 '22 12:09 vizvasrj

Hello @vizvasrj, I assume you used our Create a basic plugin guide (https://ckeditor.com/docs/ckeditor5/latest/framework/guides/plugins/creating-simple-plugin-timestamp.html).

Be aware that the custom plugins should be a class extending Plugin class as shown here: https://ckeditor.com/docs/ckeditor5/latest/framework/guides/plugins/creating-simple-plugin-timestamp.html#creating-a-plugin. I would suggest trying to follow that guide and see if that helps you while creating a custom plugin.

Please let me if that helps and, if not, could you provide me with more details about the issue you had? What would you like to achieve?

dufipl avatar Sep 05 '22 12:09 dufipl

That use npm. I need pure javascript. i do not know much about javascript.

i use https://ckeditor.com/ckeditor-5/online-builder/ To build it ckeditor.js and this is my config.

if (navigator.userAgent.match(/Mobile/)) {
    var of_id = "#id_body";
}



let theEditor;
ClassicEditor
    .create(document.querySelector("#id_body"), {
        extraPlugins: [MyCustomUploadAdapterPlugin, 'ImageCaption'],


        toolbar: {
            items: [
                'heading',
                'timestamp',
                '|',
                'bold',
                'italic',
                'link',
                'bulletedList',
                'numberedList',
                '|',
                'horizontalLine',
                'outdent',
                'indent',
                'highlight',
                '|',
                'imageUpload',
                'codeBlock',
                'code',
                'blockQuote',
                'insertTable',
                'mediaEmbed',
                'undo',
                'redo'
            ]
        },
        // language: 'ar',
        // additionalLanguages: 'de',
        // content: 'en',
        language: {
            // The UI will be English.
            ui: document.location.pathname.split('/')[1],
            // ui: 'en',
            // But the content will be edited in Arabic.
            // content: 'ur'
        },
        image: {
            toolbar: [
                'imageTextAlternative',
                'imageStyle:inline',
                'imageStyle:block',
                'imageStyle:side',
                '|',
                'toggleImageCaption',
            ],
            imageName: 'pic'
        },
        table: {
            contentToolbar: [
                'tableColumn',
                'tableRow',
                'mergeTableCells'
            ]
        },
        mediaEmbed: {
            elementName: 'o-embed'
        },
        licenseKey: '',
            
            
            
        } )
            .then( editor => {
                theEditor = editor;
            } )
            .catch(error => {
        console.error(error)
    });
class MyUploadAdapter {

    constructor(loader) {
        // The file loader instance to use during the upload.
        this.loader = loader;
        var fileUpload = document.getElementById("id_upload");
        console.log(fileUpload)

    }

    // Starts the upload process.
    upload() {
        return this.loader.file
            .then(file => new Promise((resolve, reject) => {
                this._initRequest();
                this._initListeners(resolve, reject, file);
                this._sendRequest(file);
            }));
    }

    // Aborts the upload process.
    abort() {
        if (this.xhr) {
            this.xhr.abort();
        }
    }

    // Initializes the XMLHttpRequest object using the URL passed to the constructor.
    _initRequest() {
        const xhr = this.xhr = new XMLHttpRequest();

        // Note that your request may look different. It is up to you and your editor
        // integration to choose the right communication channel. This example uses
        // a POST request with JSON as a data structure but your configuration
        // could be different.
        xhr.open('POST', (document.location.origin) +'/my_uploader/image_upload/', true);
        let csrftoken = Cookies.get('csrftoken');
        xhr.setRequestHeader("X-CSRFToken", csrftoken);
        xhr.responseType = 'json';
    }

    // Initializes XMLHttpRequest listeners.
    _initListeners(resolve, reject, file) {
        const xhr = this.xhr;
        const loader = this.loader;
        const genericErrorText = `Couldn't upload file: ${file.name}.`;

        xhr.addEventListener('error', () => reject(genericErrorText));
        xhr.addEventListener('abort', () => reject());
        xhr.addEventListener('load', () => {
            const response = xhr.response;

            // This example assumes the XHR server's "response" object will come with
            // an "error" which has its own "message" that can be passed to reject()
            // in the upload promise.
            //
            // Your integration may handle upload errors in a different way so make sure
            // it is done properly. The reject() function must be called when the upload fails.
            if (!response || response.error) {
                return reject(response && response.error ? response.error.message : genericErrorText);
            }

            // If the upload is successful, resolve the upload promise with an object containing
            // at least the "default" URL, pointing to the image on the server.
            // This URL will be used to display the image in the content. Learn more in the
            // UploadAdapter#upload documentation.
            resolve({
                default: response.url
            });
        });

        // Upload progress when it is supported. The file loader has the #uploadTotal and #uploaded
        // properties which are used e.g. to display the upload progress bar in the editor
        // user interface.
        if (xhr.upload) {
            xhr.upload.addEventListener('progress', evt => {
                if (evt.lengthComputable) {
                    loader.uploadTotal = evt.total;
                    loader.uploaded = evt.loaded;
                }
            });
        }
    }

    // Prepares the data and sends the request.
    _sendRequest(file) {
        // Prepare the form data.
        const data = new FormData();

        data.append('upload', file);

        // Important note: This is the right place to implement security mechanisms
        // like authentication and CSRF protection. For instance, you can use
        // XMLHttpRequest.setRequestHeader() to set the request headers containing
        // the CSRF token generated earlier by your application.

        // Send the request.
        this.xhr.send(data);

    }
}

// ...

function MyCustomUploadAdapterPlugin(editor) {
    editor.plugins.get('FileRepository').createUploadAdapter = (loader) => {
        // Configure the URL to the upload script in your back-end here!
        return new MyUploadAdapter(loader);
    };
    // editor.button.
}

// ...

// -- TIMESTAMP PLUGIN START


// function MyCustomTimestampPlugin(editor) {
//     editor.ui.componentFactory.add( 'timestamp', () => {
//         // The button will be an instance of ButtonView.
//         const button = new editor.buttonView()
        

//         button.set( {
//             label: 'Timestamp',
//             withText: true
//         } );

//         return button;

    
//     } );

// };

vizvasrj avatar Sep 13 '22 11:09 vizvasrj

Hello @vizvasrj, If you want to use pure JavaScript without the npm, then you have two options:

  • Integrate an existing build to your website using our CDNs (details here: https://ckeditor.com/docs/ckeditor5/latest/installation/getting-started/quick-start.html#running-a-simple-editor and here: https://ckeditor.com/docs/ckeditor5/latest/installation/getting-started/predefined-builds.html#cdn)
  • Integrate build generated by our online builder (https://ckeditor.com/docs/ckeditor5/latest/installation/getting-started/predefined-builds.html#online-builder)

Those options allow you to integrate CKEditor 5 without npm.

I hope that helps.

dufipl avatar Sep 14 '22 14:09 dufipl

Well Never mind thank You by the way

vizvasrj avatar Oct 18 '22 14:10 vizvasrj

Hello @vizvasrj were you able to create a custom plugin with pure js?

lucassouzz avatar Mar 16 '23 00:03 lucassouzz

There has been no activity on this issue for the past year. We've marked it as stale and will close it in 30 days. We understand it may still be relevant, so if you're interested in the solution, leave a comment or reaction under this issue.

CKEditorBot avatar Mar 15 '24 03:03 CKEditorBot

We've closed your issue due to inactivity. We understand that the issue may still be relevant. If so, feel free to open a new one (and link this issue to it).

CKEditorBot avatar Apr 15 '24 03:04 CKEditorBot