Add new Uploader to Ckeditor5 - javascript

How is this possible add new uploader functionality to ckeditor5 like upload audio or video?
I tried for using ckeditor5 doc but it is not clear at all.
I using this vue file for using ckeditor5. in this file, I use a customized uploadadapter for my project, but now I don't know how i can upload another type of file like audio and video in this attitude
<script>
import ClassicEditor from '#ckeditor/ckeditor5-build-classic/build/ckeditor';
import MyUploadAdapter from '../adapter/UploadAdapter';
export default {
data() {
return {
instance: null,
article: {
data: '',
},
}
},
mounted() {
this.initialize();
},
methods: {
// Initializing Editor
initialize: function () {
ClassicEditor
.create(document.querySelector("#editor"), this.config)
.then(editor => {
// get initial instance object of editor
this.instance = editor;
// set initial binder of editor on start
editor.model.document.on('change', () => {
this.valueBinder(editor.getData())
});
editor.plugins.get('FileDialogButtonView')
// This place loads the adapter.
editor.plugins.get('FileRepository').createUploadAdapter = (loader, article) => {
return new MyUploadAdapter(loader, this.article);
}
})
.catch(error => {
console.error(error);
});
},
}
},
}
</script>

For Upload file you can use CKFinder.
For the configuration of CKfinder, Please refer this link.
ClassicEditor
.create( editorElement, {
ckfinder: {
uploadUrl: '/ckfinder/core/connector/php/connector.php?command=QuickUpload&type=Files&responseType=json' // here you can set your own file path
}
} )
.then( ... )
.catch( ... );

Related

jsPDF Error: autoTable is not a function in SAP UI5

I am using the jsPDF library for converting a table into a PDF file.
The current code that I have used is giving off an error, that autoTable is not a function.
Here is the code.
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/ui/model/json/JSONModel",
"sap/ui/core/util/Export",
"sap/ui/core/util/ExportTypeCSV"
],
function (Controller, JSONModel, Export, ExportTypeCSV) {
"use strict";
return Controller.extend("c.g.modalproject1.controller.Root", {
onInit: function () {
var oModel1 = new JSONModel("./model/vegetableDataJSON.json");
this.getView().setModel(oModel1, "veg");
console.log("data : ", oModel1);
},
openDialog1: function () {
if (!this.pdialog1) {
this.pdialog1 = this.loadFragment({
name: "c.g.modalproject1.fragments.mTables"
});
}
this.pdialog1.then(function (oDialog) {
oDialog.open();
})
new sap.m.MessageToast.show("Table Loaded");
},
closeDialog: function () {
this.byId("newDialog1").close();
sap.m.MessageToast.show("Table closed ! ");
// var vegTable = this.getView().byId("vegiesMTable");
// vegTable.setGrowing(false);
// vegTable.setGrowingScrollToLoad(false);
},
downloadCSV: function () {
// Show a toast message to indicate that the file is downloading
sap.m.MessageToast.show("Downloading Excel..");
// Create a new Export object with the specified export type and options
var oExport = new Export({
exportType: new ExportTypeCSV({
separatorChar: ","
}),
models: this.getView().getModel("veg"),
rows: {
path: "/vegetablesRootNode"
},
columns: [{
name: "Title",
template: {
content: "{title}"
}
},
{
name: "Type",
template: {
content: "{type}"
}
},
{
name: "Description",
template: {
content: "{description}"
}
},
{
name: "Price",
template: {
content: "{price}"
}
},
{
name: "Rating",
template: {
content: "{rating}"
}
}]
});
// Save the file and handle any errors that may occur
oExport.saveFile().catch(function (oError) {
sap.m.MessageToast.show("Error when downloading data. Browser might not be supported!\n\n" + oError);
}).then(function () {
// Destroy the export object
oExport.destroy();
});
},
downloadPDF:function()
{
sap.m.MessageToast.show("Downloading into PDF started !");
var oModel2 = this.getView().getModel("veg");
console.log("check data = ", oModel2);
var oColumns = ["Title","Type","Description","Price","Rating"];
var oRows = [];
oRows = oModel2.oData.vegetablesRootNode;
console.log(oColumns);
console.log(oRows);
//var pdfDoc = new jsPDF('p', 'pt', 'letter');
var pdfDoc = new jsPDF();
pdfDoc.text(20, 20, "Vegetables Table");
pdfDoc.autoTable(oRows, oColumns);
pdfDoc.save("test.pdf");
//pdfDoc.output("save","t.pdf");
}
});
});
The last function is the code that runs to save the table data into PDF.
Can you please help.
These are the files that are included in my project folder.
Manifest.json
Adding just text, and most of the functionality that is available (via methods) from jsPDF works fine. I have created PDFs with just text from this app as well.
It works fine for adding text and downloads fine. But for Table data, it doesnt work.
I tried various ways but didn't get to solve it at all.
I tried to make a POC with this library and it works :-)
Configure the framework so that it can load the libraries
sap.ui.loader.config({
// activate real async loading and module definitions
async: true,
// load thirparty from cdn
paths: {
"thirdparty/jsPDF": "https://unpkg.com/jspdf#2.5.1/dist/jspdf.umd.min",
"thirdparty/jsPDFautoTable": "https://unpkg.com/jspdf-autotable#3.5.28/dist/jspdf.plugin.autotable"
},
// provide dependency and export metadata for non-UI5 modules
shim: {
"thirdparty/jsPDF": {
amd: true,
exports: "jspdf"
},
"thirdparty/jsPDFautoTable": {
amd: true,
exports: "jspdf",
deps: ["thirdparty/jsPDF"]
}
}
});
You can put that code on top on your Component.js file
Idea is to configure the framework to load libraries from CDN as AMD module with dependencies.
It's a bit tricky in your case and I'm not sure I understand the mechanism; what I imagine is that autoTable is a jsPDF plugin so we need jsPDF (dependency); the plugin overload jsPDF and returns jsPDF object
For sap.ui.loader here the official doc. :
https://sapui5.hana.ondemand.com/sdk/#/api/sap.ui.loader/methods/sap.ui.loader.config
Loads and consumes libraries
sap.ui.require(["thirdparty/jsPDFautoTable"], (jsPDFautoTable) => {
var doc = new jsPDFautoTable.jsPDF();
doc.autoTable({ html: '#my-table' });
doc.save('table.pdf');
});
Either with sap.ui.define or sap.ui.require to load the library on the fly when needed

Destroy dynamically created filepond instance with vanila javascript

I have created filepond instance in my function which shows modal block with file upload feature. Now I need to destroy created instance on closing modal block, because I have case to call thet function for another uses with new filepond instance and parameters. Please advice how can I realize properly destoy dynamically created filepond instance;
Function initializing filepond:
const showUploader = () => {
const pond = FilePond.create( inputElement, {
acceptedFileTypes: ['image/png', 'image/jpeg', 'image/jpg','application/pdf'],
instantUpload: true,
/* other settings */
server: {
url: '/process.php?' + urlParams,
process: {
onload: (response) => {
console.log(response);
},
onerror: (error) => {
console.log(error);
}
},
revert: {
onload: (response) => console.log(response),
onerror: (response) => console.log(response),
},
load: {
onload: response => { console.log(response); },
onerror: response => { console.log(response); },
}
}
});
}
Function where I have to destroy it:
const closeUploader = () => {
//TODO: Destroy created filepond instance
}
Thanks in advance!
Use the FilePond.destroy method.
<intput type="file" name="filepond" required multiple>
<script>
const inputElement = document.querySelector('input[type="file"]');
// create the FilePond instance
FilePond.create(inputElement);
// destroy the FilePond instance by element reference
FilePond.destroy(inputElement);
</script>
You can also call destroy on the instance itself, in your situation that would be pond.destroy().
https://pqina.nl/filepond/docs/patterns/api/filepond-object/#destroying-a-filepond-instance

Vue.js: How do you call component specific methods outside of component?

The goal here is to use OpenTok WebRTC platform for a video chat web app built with vue. Here is an example of OpenTok in Vue.
I'm getting confused on where to call specific methods for the publisher because it is nested within a session.vue component. I want to call methods such as:
1) Stop publishing
2) Change the publisher to source from a video instead of webcam
This is the web API.
Should I write methods that affect the publisher in the child component publisher.vue or should I do that in the parent component which calls publisher?
Publisher.vue
<template>
<div> </div>
</template>
<script>
import OT from "#opentok/client";
export default {
name: "publisher",
props: {
session: {
type: OT.Session,
required: false
},
rlive: Boolean,
opts: {
type: Object,
required: false
}
},
mounted: function() {
// console.log(this.rlive)
console.log("publisher created")
console.log(this.session)
const publisher = OT.initPublisher(this.$el, this.opts, err => {
if (err) {
this.$emit("error", err);
} else {
this.$emit("publisherCompleted");
}
});
this.$emit("publisherCreated", publisher);
const publish = () => {
this.session.publish(publisher, err => {
if (err) {
this.$emit("error", err);
} else {
this.$emit("publisherConnected", publisher);
}
});
};
if (this.session && this.session.isConnected()) {
// console.log("this.session && this.session.isConnected()")
publish();
// console.log(publisher)
}
if (this.session) {
console.log("this.session")
console.log(publisher)
this.session.on("sessionConnected", publish);
}
if(!this.session){
console.log("!this.session")
}
},
beforeDestroy: function(){
console.log("before destroy");
console.log(publisher)
console.log(publish)
//here is where I want to KEEEEEL!
// console.log(publisher)
// console.log(this.session)
}
};
</script>

Problem with vue-google-oauth-2 in Vue.js

I am trying to add a Google Sign-In button to my Vue.js application and I found the vue-google-oauth2 plugin. I installed it and followed exactly the sample.html code to integrate it in my application, this way:
<template>
<div>
<h1>Test</h1>
<button #click="handleClickSignIn" :disabled="!isLoaded">signIn</button>
</div>
</template>
<script>
/**
* You should first need to place these 2 lines of code in your APP ENTRY file, e.g. src/main.js
*
* import GAuth from 'vue-google-oauth2'
* Vue.use(GAuth, {clientId: '4584XXXXXXXX-2gqknkvdjfkdfkvb8uja2k65sldsms7qo9.apps.googleusercontent.com'})
*
*/
export default {
name: 'test',
props: [],
components: {
},
data () {
return {
isLoaded: false
}
},
computed: {
},
methods: {
handleClickSignIn(){
this.$gAuth.signIn(function (user) {
//on success do something
console.log('user', user)
}, function (error) {
//on fail do something
})
}
},
mounted(){
let that = this
let checkGauthLoad = setInterval(function(){
that.isLoaded = that.$gAuth.isLoaded()
console.log('checked', that.isLoaded)
if(that.isLoaded) clearInterval(checkGauthLoad)
}, 1000);
}
}
</script>
The problem is that the isLoaded() method never returns true, with the Google Chrome console telling me every time I press on the button that the google api is not ready, that is the plugin console message printed when the GoogleAuthInstance is false. Could anyone help me?
Use isInit instead of isLoaded as the latter will be/is deprecated.
Add to main.js
import GAuth from 'vue-google-oauth2'
Vue.use(GAuth, {
clientId: '....apps.googleusercontent.com',
scope: 'email',
prompt: 'consent',
fetch_basic_profile: true
})
new Vue({
...
render: (h) => h(App),
}).$mount("#app");

Nightwatch(PageObject) + TypeScript unable to locate elements using # symbol

During execution, unable to link locator using # symbol from elements.
ERROR: Unable to locate element: "#queryInput" using: xpath
Code:
import * as config from 'config';
import { NightWatchClient, PageObject } from 'nightwatch';
const pageConfig = config.get<IPageConfig>('pages.google');
const page: PageObject = {
url: pageConfig.url,
elements: {
queryInput: {
selector: '//input[#name="q"]',
locateStrategy: 'xpath'
}
},
commands: [
{
enterQuery: (client: NightWatchClient, query: string) => {
return client
.waitForElementVisible('//input[#name="q"]', 5000)
//.setValue('//input[#name="q"]', [query, client.Keys.ENTER])
.setValue('#queryInput', [query, client.Keys.ENTER])
.waitForElementVisible('//*[#id="res"]', 5000);
},
},
]
};
export = page;
Complete code
Link
You don't need to pass in the nightwatch client. It is already available to you in the page object class by using this or this.api. Try dumping this to the console in your page object and you will see all the properties that are available to you. This works for JS so it should work the same way in TS.
You can get your selector to work by changing your function to something like the following:
enterQuery: (query: string) => {
return this
.waitForElementVisible('//input[#name="q"]', 5000)
.setValue('#queryInput', [query, client.Keys.ENTER])
.waitForElementVisible('//*[#id="res"]', 5000);
}

Categories