Vaadin and Javscript mixed

Hi,

My company is evaluating Vaadin and we have few check points. One point where, I need your help is this:

I have created a Vaadin application, say a splitPanel with a list of links on the left side. On clicking one of the links I need to open a Javascript editor in the right panel(legacy code, which cant be changed at this point). I have achieved this using CustomLayout, where in I define a ‘div’ and on the click of the link on the left side, I call a Javascript function which then computes the full HTML for the editor and adds it to the innerHTML of the div defined by CustomLayout. This works smoothly.

Now my next target is use a Vaadin component say a Vaadin button inside my editor. I tried two approaches:

  1. In my innerHTML, I created a div with location attribute. Then once this editor is loaded, I go back to my Java class handling the right view and I create a component and try to add it to the customLayout on the specified location. But nothing happens. However if in the inputStream of CustomLayout I create a div with location attribute, then it works fine. But this doesnt suffice my requirement. The way I want is I should be able to create divs in my editor with location attributes and on these divs create Vaadin components.
  2. Secondly, I see that there is this API called Embedded where in I can embed Vaadin application in static HTML pages. But how do I use it in my case. I already have a Vaadin application, and inside that I have embedded a JavaScript editor and now want to embed a Vaadin component inside this editor.

Can you pl. help me to figure this out.

About the second part, it is the other way around. You embed static HTML, images, PDFs etc. into your Vaadin application, not Vaadin application into HTML. Information on embedding a Vaadin application can be found at https://vaadin.com/book/-/page/application.embedding.html, but I actully don’t know how it will react as you have a Vaadin application inside a static page, inside a Vaadin application. Quite a weird setup.

This is probably partly related to
issue #5774
: CustomLayout does not support replacing the template after the layout has been painted.

Attached to the ticket, there is a version of CustomLayout that does support replacing the HTML - that could give you a model for how to handle parts of your problem on the client side even though not solving your problem directly.

Hi Jens,

Thanks for the prompt reply. I know its a weird requirement and in all likelihood we will never use such a scenario. But since we are evaluating the product we are just investigating various check points. Few critical check points such as emebedding JS editor in Vaadin framework, interaction between Vaadin and JS etc have also been evaluated and to our pleasant surprise, can all be achieved rather smoothly. Now I am just stuck on this last point for which I raised the post. I am not sure whether that is actually doable or not and hence wanted to know a defnitive answer so that I can close this check point.

Hi Henri,

Thanks so much for the reply. I will explore the lead mentioned in your reply and will get back to you with my findings, soon.

Hi Henri,

I looked up the URL you mentioned but unfortunately it doesn’t quite help me, as I am not trying to replace the template contents. What I am actually doing is this:
Initially I create CustomLayout like this,

CustomLayout cl = new CustomLayout(new ByteArrayInputStream("<div location='textfield1'></div><div id='instance_main'></div>".getBytes()));

Here ‘instance_main’ div is my container div where I load the editor. Then I go ahead and add this layout. Once I have finished, I then call the Javascript function to build innerHTML for the ‘instance_main’ div and set it there. This innerHTML contains another div with a location attribute say ‘textfield2’. At this point my editor is nicely built in the div and works fine. Now once the editor is loaded, I fire an event which is listened to by the class which created the custom layout. Here, I do this:


			TextField tf = new TextField();
			cl.addComponent(tf, "textfield1");
			TextField tf1 = new TextField();
			cl.addComponent(tf1, "textfield2");

Now for location ‘textfield1’, it paints the Vaadin TextField correctly. But for location ‘textfield2’, it does nothing. This is what my problem is. I am trying to get it to paint a textField in the second div with location ‘textfield2’, a div I defined in my Javascript code.

Is this possible? If yes where am I going wrong?

While your problem is not exactly the same as the patched version of CustomLayout tries to solve (you update the DOM on the client side rather than the static template from the server), many parts of the approach to take are probably the same.

The fundamental problem that the attached classes solve is scanning the DOM for new locations

locationToElement.clear();
scanForLocations(getElement());

and moving components to their new locations (if available) - the version I pointed to does this by moving the already rendered components to a temporary invisible layout before updating the template received from the server and moving them to the correct locations in the new template/DOM after it has been loaded.

If your case, you want to block reapplying the template but make sure the DOM is rescanned whenever new components are received from the server (or when your other javascript tells to rescan the page or …), and then move all widgets to the correct locations in the new DOM. What might be tricky is if your Javascript modifies the locations in the DOM where you already have Vaadin widgets - in that case, they might need to be moved somewhere safe (e.g. to the invisible element) before modifying the DOM, so you might need to e.g. expose two methods from VUpdatableCustomLayout to your Javascript editor - one for starting an edit and one for when finished.