Popup forms in Vaadin 10+

I’m looking at migrating of a large Vaadin 8 project to V10+, trying to get a grip on the hurdles involved. The current project makes frequent use of BrowserWindowOpener to pop up a form to present, often print a page of transient information. Is there similar functionality in 10+?

Hi,

I tried:

 Page page = UI.getCurrent().getPage();

        page.executeJavaScript("window.open('https://www.example.com')");

…but it does not work… the same method with “console.log” works fine. Is Flow blocking access to window object?

window.open is the way to go, but it will be blocked by browsers if it’s not called as a direct consequence of a user action. Therefore you will need to do the click handling on the client side. I made a quick test, which seems to work:

browser-opener.html

<link rel="import" href="../bower_components/polymer/polymer.html">

<dom-module id="browser-opener">
    <template>
        <div id="content" on-click="navigate"></div>
    </template>

    <script>
        class BrowserOpener extends Polymer.Element {
            static get is() {
                return 'browser-opener';
            }

            static get properties() {

            }
            navigate() {
                window.open(this.url, "_blank");
            }
        }
        customElements.define(BrowserOpener.is, BrowserOpener);
    </script>
</dom-module>

BrowserOpener.java

@Tag("browser-opener")
@HtmlImport("src/browser-opener.html")
public class BrowserOpener extends PolymerTemplate<BrowserOpener.BrowserOpenerModel> {

    @Id
    Div content;

    /**
     * Creates a new BrowserOpener.
     */
    public BrowserOpener() {
    }

    public void setUrl(String url) {
        getModel().setUrl(url);
    }

    public void setContent(Component component) {
        this.content.removeAll();
        this.content.add(component);
    }

    /**
     * This model binds properties between BrowserOpener and browser-opener.html
     */
    public interface BrowserOpenerModel extends TemplateModel {
        String getUrl();
        void setUrl(String url);
    }
}

Usage example:

		BrowserOpener bo = new BrowserOpener();
        bo.setContent(new Button("click this button to open"));
        bo.setUrl("https://www.vaadin.com");

This is a nice example indeed! But I’ve noticed it seriously deviates from best practices when it comes to accessibility.
Using an anchor or a button instead of a div in <div id="content" on-click="navigate"></div> would be much better because browsers would make sure the element behaves correctly for keyboard focus, mouse hover, cursor, screen readers, etc.

Here is how to make this element accessible:

<link rel="import" href="bower_components/polymer/polymer-element.html">

<dom-module id="browser-opener">

  <template>
    <a id="content" on-click="navigate" href$="[[url]
]"></a>
  </template>

  <script>
    class BrowserOpener extends Polymer.Element {
      static get is() {
        return 'browser-opener';
      }

      static get properties() {
        return {
          url: String
        };
      }
      
      navigate(e) {
        e.preventDefault();
        window.open(this.url, "_blank");
      }
    }
    customElements.define(BrowserOpener.is, BrowserOpener);
  </script>

</dom-module>