Thad
Thad

Reputation: 975

Dismissing modal paper-dialog fails remove opaque backdrop

When my modal paper-dialog is attached to my-app.html, dismissing it fails to clear the opaque backdrop. But when the dialog is attached to a page in my-app.html, the backdrop is removed on dismissal.

I have a modal paper-dialog that I want to share among many pages so I place it in my-app. I've placed in my-app so:

<iron-pages role="main" selected="[[routeData.page]]" 
    attr-for-selected="name" selected-attribute="visible" 
    fallback-selection="404">
  <my-login name="" route="[[subroute]]"></my-login>
  <my-todos name="my-todos" route="[[subroute]]"></my-todos>
  ...
  <my-404-warning name="404"></my-404-warning>
</iron-pages>

<paper-dialog id="errorDlog" modal>
  <h2>Error</h2>
  <p>[[o_error]]</p>
  <div class="buttons">
    <paper-button dialog-confirm autofocus>Close</paper-button>
  </div>
</paper-dialog>

To show the dialog using a custom event triggered from any of my pages, I follow Polymer's instructions to bind my listener to the window (see "Add and remove listeners imperatively". Using this technique, I open the dialog from my-login with window.dispatchEvent(new CustomEvent('o_error', {detail: 'login error'}));. But when dialog is dimissed, the backdrop remains opaque.

However, if I add an id to my-login and in ready() call this.$.loginForm.addEventListener('o_error', e => this._errorListener(e));, I open the dialog from my-login with this.dispatchEvent(...). Now dismissing the dialog does clear the opaque backdrop.

So, I have a workaround, but I don't think I should have to addEventListener() to every page.

Upvotes: 0

Views: 185

Answers (2)

user10065062
user10065062

Reputation: 1

if (active) {
    this.listenToOverlayChanges();
 } else {
    this.unlistenOverlayChanges();
 }

Upvotes: 0

Thad
Thad

Reputation: 975

I found the source of the error, and the solution. First, I am using Node.js and Express, and (mostly) following Wendy Ginsberg's recommendation on structure. It appears that the server route

app.get('*', function(req, res){
  res.sendFile("index.html", {root: '.'});
});

fires twice--once for the missing page, and once for the 404 route itself. The iron-overlay-backdrop is overwritten and the lost iron-overlay-backdrop appears to be what the dialog is trying to close. (Note, I say "appears" because I can't see this come and go in DevTools. I'm guessing based on the effect).

My solution has been to create an <error-dialog> element containing my <paper-dialog> and the EventListener, and place <error-dialog> in index.html:

<body>
  <my-app></my-app>
  <error-dialog></error-dialog>
  <noscript>
    Please enable JavaScript to view this website.
  </noscript>
</body>

Now I can show this dialog from anywhere in my application with

let msg = ...
const dlog = document.querySelector('error-dialog');
dlog.dispatchEvent(new CustomEvent('o_error', {detail: msg, bubbles: true, composed: true}));

Overall I like Node.js, but it presents some challenges. For example, do not lazy-load your Polymer 404 page if you're using Node.js & Express: The Node.js console will show a 200 status for the nonexistent page, and an empty <div> where your 404 message should be.

Upvotes: 0

Related Questions