momentjsvaadinvaadin8vaadin-charts

Include moment.js in vaadin charts 4.0 to set axis format


Hello I am using Vaadin 8 and Vaadin charts 4.0 and am trying to format one of the data axis of the chart to different date time formats depending on user format input and locale. I try to inject the moment.js library and get a reference exception saying that moment variable does not exist. I have tried 2 different approaches which I list below:

(1) Use the @JavaScript annotation to inject moment.js.

@JavaScript({"https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js", "https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.13/moment-timezone-with-data-2012-2022.min.js"})
@WebServlet(urlPatterns = "/*", name = "IeUIServlet", asyncSupported = true)
@VaadinServletConfiguration(ui = IeUI.class, productionMode = true, heartbeatInterval = 500, closeIdleSessions = false, widgetset = "softcom.ievaadin.AppWidgetSet")

public static class IeUIServlet extends VaadinServlet implements SessionInitListener {//, SessionDestroyListener {

    @Override
    protected void servletInitialized() throws ServletException {
        super.servletInitialized();

        // Add any system level init here
        //Main.initSystem();

    }

    @Override
    public void destroy() {
        super.destroy(); //To change body of generated methods, choose Tools | Templates.

        Main.destroy();
    }

    @Override
    public void sessionInit(SessionInitEvent event) throws ServiceException {
        event.getSession().getSession().setMaxInactiveInterval(-1);
    }
}

And the one where set the formatter

YAxis ya = new YAxis();
String js = "function() {";
js += "try {"
                        + "var g = moment.tz(\"2014-06-01 12:00\", \"America/New_York\");"
                        + "alert(g);"
                        + "return g;}"
                        + "catch(e) {"
                        + "alert(e);}}";
ya.getLabels().setFormatter(js);

(2) I try to append the script tag at the head in the function itself.

String js = "attempt {"
                        + "var script = document.createElement('script');"
                        + "script.src = \"https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js\";"
                        + "document.head.appendChild(script);"
                        + "} catch(e) {"
                        + "alert('first one'); }"
                        + "try {"
                        + "var b = moment().format();"
                        + "return b;"
                        + "} catch (e) {"
                        + "alert(e); }";

                JavaScript.getCurrent().execute(attempt);
String js = "function() {";
js += "try {"
                        + "var g = moment.tz(\"2014-06-01 12:00\", \"America/New_York\");"
                        + "alert(g);"
                        + "return g;}"
                        + "catch(e) {"
                        + "alert(e);}}";
ya.getLabels().setFormatter(js);

Any help would be appreciated.


Solution

  • You can inject the script tag in the head of the document by registering a BootstrapListener in your IeUIServlet:

            @Override
            protected void servletInitialized() {
             getService().addSessionInitListener(event -> {
              event.getSession().addBootstrapListener(new BootstrapListener() {
               @Override
               public void modifyBootstrapPage(BootstrapPageResponse response) {
                response.getDocument().head().append("<script src=\"https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js\"></script>");
                response.getDocument().head().append("<script src=\"https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.13/moment-timezone-with-data-2012-2022.min.js\"></script>");
               }
    
               @Override
               public void modifyBootstrapFragment(BootstrapFragmentResponse response) {
    
               }
              });
             });
            }
    

    And preprend $wnd to moment in your javascript, like this:

    var g = $wnd.moment.tz(\"2014-06-01 12:00\", \"America/New_York\");