Change UI with JavaScript

I want to change dynamically the UI of my servlet when an event occurs, with JavaScript code. I charge my UI in a ‘div’ element of a JSP page, a div with id=“forjs”. I can remove this element from page in my UI with this code:

JavaScript.getCurrent().execute("element = document.getElementById('forjs');parent = element.parentNode;parent.removeChild(element);");

However, after that, I try to charge a new UI with this code but nothing occurs, no element is charged:

String script = "vaadin.initApplication('forjs', {"+
                "'browserDetailsUrl': 'two',"+
                "'serviceUrl': 'two',"+
                "'widgetset': 'com.vaadin.DefaultWidgetSet',"+
                "'theme': 'mytheme',"+
                "'versionInfo': {'vaadinVersion': '7.1.7'},"+
                "'vaadinDir': 'VAADIN/',"+
                "'heartbeatInterval': 300,"+
                "'debug': true,"+
                "'standalone': false,"+
                "'authErrMsg': {"+
                "'message': 'Take note of any unsaved data, and <u>click here</u> to continue.caption': 'Authentication problem'"+
                "},"+
                "'comErrMsg': {"+
                "'message': 'Take note of any unsaved data, and <u>click here</u> to continue.caption': 'Communication problem'"+
                "},"+
                "'sessExpMsg': {"+
                "'message': 'Take note of any unsaved data, and <u>click here</u> to continue.caption': 'Session Expired'"+
                "}"+
                "});";
JavaScript.getCurrent().execute(script);

Why does it not work? I don’t get any error but second UI is not charged and shown. Any ideas?

Next week I will go on holidays but I wait for answers.

Help, please.

Well, okay, there are several mistakes in that script. The good script is this:

String script = "if (!window.vaadin) alert('Failed to load the bootstrap JavaScript: VAADIN/vaadinBootstrap.js');"+
                "vaadin.initApplication('forjs', {"+
                "'browserDetailsUrl': 'two',"+
                "'serviceUrl': 'two',"+
                "'widgetset': 'com.vaadin.DefaultWidgetSet',"+
                "'theme': 'amavaadinapptheme',"+
                "'versionInfo': {'vaadinVersion': '7.1.7'},"+
                "'vaadinDir': 'VAADIN/',"+
                "'heartbeatInterval': 300,"+
                "'debug': true,"+
                "'standalone': false,"+
                "'authErrMsg': {"+
                "'message': 'Take note of any unsaved data, and <u>click here</u> to continue.',"+
                "'caption': 'Authentication problem'"+
                "},"+
                "'comErrMsg': {"+
                "'message': 'Take note of any unsaved data, and <u>click here</u> to continue.',"+
                "'caption': 'Communication problem'"+
                "},"+
                "'sessExpMsg': {"+
                "'message': 'Take note of any unsaved data, and <u>click here</u> to continue.',"+
                "'caption': 'Session Expired'"+
                "}"+
                "});";

Now, the JavaScript function ‘vaadin.initApplication’ is called. I know this because I handle sucessfully JavaScript function callback in way that is explained here: https://vaadin.com/book/vaadin7/-/page/advanced.javascript.html

However, new UI is not charged. Additionally, I’ve specified custom UI providers for both UIs (distinct provider classes), I’ve override all its methods and I’ve toggled off breakpoint for debug mode. I check first UI provider is used but when ‘vaadin.initApplication’ function is called for new UI charge, second UI provider is not used. If I drop my ‘div’ element previously, behaviour is the same. I also try changing value for ‘vaadinDir’ with all posibilities but I haven’t got any positive result.

Can someone help me? Does another function like ‘finishApplication’ exists? Is doing what I want possible?

Any answer, please…

Hi Victor,

interesting approach… but may I ask you why you are trying to do this JavaScript hack? Why don’t you write a simple extension or component with your own Connector and RPC call back to server side? After this you should have full control about what shall happen

I’m not specially interested in JavaScript. I want to avoid page change effect in web browser. First, I’m trying exchange an UI with another UI of same application but I’d like be able to exchange an UI with another UI of another deployment of another server. I’m not a Vaadin client-side expert, I don’t understand what you say about a Connector and a RPC call back to server side. Can you post some sample code?

I have a web project with a JSP and two UI classes: AppUIOne and AppUITwo. There is a div with id=“forjs” in the JSP page, this div shows AppUIOne. In this UI, I have a button and I want to exchange div’s UI (AppUIOne with AppUITwo) when an app user clicks on it. But I don’t want to redirect the page to another URL, I want to avoid page change effect in web browser.

I have tried this code:

JavaScript.getCurrent().execute(script);

Variable ‘script’ value starts with “vaadin.initApplication(‘forjs’, …)”. I know no one problem exists in invocation because I handle sucessfully JavaScript function callback. But this does not work. I’m not specially interested in doing with JavaScript, simply I tried this way. In short, I want to exchange AppUIOne with AppUITwo when app user clicks on AppUIOne button (is this possible?).

I don’t want to show a modal notification but I understand you say me that I can determine another UI for display in the UIProvider. Okay, if I override ‘getUIClass’ method and this method returns AppUITwo.class, AppUITwo is shown, not AppUIOne. But ‘getUIClass’ is only initially invoked, not when app user clicks on button.

I also try this:

getSession().addUI(new AppUITwo());

And this:

getSession().addUIProvider(new AppUITwoProvider());

But in this case, I get this an error caused by:

java.lang.IllegalArgumentException: Can not add an UI that has not been initialized.

If I previously invokes AppUITwo ‘init’ method, I get same error, too.

I hope you understand my problem and you can help me with this. I don’t know if exchanging the UI with another UI when an event occurs is possible. And, if it’s possible, how I could do it.

Hi Victor, I have two quite simple suggestions.

If you really want a hard break between your two UIs you could call a JavaScript call, replacing the content of your

by an AJAX call. I don’t know how exactly you bind the vaadin application into your HTML site unti now. But there must be a piece of code calling the whole vaadin framework. If you replace this with a new call, you could switch.

You also could do a call like this UI.getCurrent().setContent(myNewContent). So you still have ONE UI main class, but it is switching the content (eg. your UI1 content and UI2 content).

Forget my RPC suggestion (https://vaadin.com/book/vaadin7/-/page/gwt.rpc.html), because you want to do this at a button.click event and don’t need this extra way of communication.

You also could use iframes and just reloading the iframe’s content

My final target was exchange UI with another UI of another deployment of another server. It’s not possible with JavaScript because ‘vaadin.initApplication…’ isn’t able to do this, a man from Vaadin tell me that. I can exchange UI with another UI doing a call like UI.getCurrent().setContent(myNewContent) but… of another deployment of another server? I believe this is a dead end. I leave my idea…

Anyway, thanks for your answers!