jueves, 9 de abril de 2020

30. Vaadin 14. Integrating external Js libraries from npm (2). TinyMce. NOT WORKING!!!!!

0. Introduction

Now that I have tried to use TinyMce in my Vaadin projects, but integrating with Vaadin 14 is rather difficult because the component tries to find themes and skins and cannot find them. This maybe can be due to the shadow dom, which can encapsulate most of the code so that variables and paths get local and cannot be accessed.

The main ideas of this post are from the Vaadin forum.

The steps to follow are:

1. Create a js file to get the function tinymce.init() global so that it can be accessed by the Vaadin component. this file will be put in the frontend folder. Remember that to make a function global, it should be incorporated into the "window" object.
2. Create the component class with the @NpmPackage annotation to import the tinymce module from npm
3. Execute the build process so that the npm_modules folder will be filled with the npm dependencies. If you, instead of executing the build process, execute Run As-> Run on server, then you will get an error that cannot find the "./tinymceEdu/themes/silver.index.js". To solve this error, you should comment the line 18 that tries to import this module by means of the @JsModule annotation.
4. Copy the folder npm_modules/tinymce/skins to src/main/webapp folder and we will get the folder src/main/webapp/skins.
5. Create a folder "tinymceEdu" (or any other name different from "tinymce") in the folder frontend.
6. Copy the folder npm_modules/tinymce/themes to the last folder, getting frontend/tinymceEdu/themes folder
7. Create the main form and include this component

1. The js file

I have called it tinymce-test.js . It will be placed in the "frontend" folder


1
2
3
4
5
import * as TINY from "tinymce";

window.initTinymce = function() {
 tinymce.init({selector:'textarea'});
}


2. The component class



 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package com.gmail.ximo;
import java.util.UUID;
import com.vaadin.flow.component.AttachEvent;
import com.vaadin.flow.component.Tag;
import com.vaadin.flow.component.customfield.CustomField;
import com.vaadin.flow.component.dependency.JsModule;
import com.vaadin.flow.component.dependency.NpmPackage;

@SuppressWarnings("serial")

//Our js file used to make the library functions global
@JsModule("./tinymce-test.js") // New! [1]

//Theme
@JsModule("./tinymceEdu/themes/silver/index.js") // Modified! [2]

//Npm
@NpmPackage(value = "tinymce", version = "5.2.1") // Modified! [3]
@Tag("textarea")
public class TinyMce extends CustomField<String> {
    public TinyMce(){
        this.setId(UUID.randomUUID().toString());
    }

    @Override
    protected String generateModelValue() {
        return getElement().getText();
    }

    @Override
    protected void setPresentationValue(String s) {
        getElement().setText(s);
    }

    @Override
    protected void onAttach(AttachEvent attachEvent) {
        super.onAttach(attachEvent);
        this.getElement().executeJs("window.initTinymce()"); //Modified [4]
        this.setWidth("500px"); // Modified [5]
    }
}

Line 12: references the file" tinymce-text.js" so that we can use the "window.initTinymce()" function declared in this js file. The execution of this function is in line  38.

Line 15: references the copied folder themes from npm_modules/tinymce/themes to frontend/tinymceEdu/themes

Line 18: the reference to the tinymce package from the npm repository

Line 19: the tag used in html

Line 38: The use of the function tinymce.init() which has been "globalized" in the "tinymce-test.js" file passing it to the window object


3. The main view class

Here is the simple code


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.gmail.ximo;

import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.server.PWA;
import javax.annotation.PostConstruct;


/**
 * The main view contains a simple label element and a template element.
 */
@SuppressWarnings("serial")
@Route("")
@PWA(name = "Project Base for Vaadin Flow with CDI", shortName = "Project Base")
public class MainView1 extends VerticalLayout {

    @PostConstruct
    public void init() {
        TinyMce tiny= new TinyMce(); 
        add(tiny);
    }
}

Now you can run it (if you use the start-up project from Vaadin as Run As- Maven Build.. - Goals : "clean package tomee:run" or Run -Run on Server ... if you are using Tomcat server and have configured the pom.xml as in this post).



Happy coding!

No hay comentarios:

Publicar un comentario