polymer 2.0. How to open dialog in parent element from child? - polymer

I am using Polymer Starter Kit 2.I created a paper-dialog and event in my-app.html:
<paper-dialog id="animated" entry-animation="scale-up-animation" exit-animation="fade-out-animation" with-backdrop>
<h2>Dialog Title</h2>
</paper-dialog>
---------------------------------------------------------------
feedback(){
this.$.animated.open();
}
And now I want to open a this dialog from child View1 from iron-pages. How can I do it?

You could either raise an event in the child element and open the dialog when you receive it or pass a callback function to the child that gets called whenever you want to open the dialog.
Events documentation:
https://www.polymer-project.org/2.0/docs/devguide/events

Related

Polymer message box with default button

Using Polymer 2 and paper-dialog I have created message boxes for my application. For the usual information boxes with only an OK button I would like the enter key to trigger the same handler as the button does. Any idea how to accomplish this?
Note that I also implemented an InputBox and there I used the on-keydown event of the single input element. But for an information box there is no text input element - only static text and an OK button.
You could use a keydown-handler on the paper-dialog itself, and have that handler trigger the button's click-handler:
<paper-dialog on-keydown="_onDialogKeyDown">
<button id="myButton" on-click="_submit">OK</button>
</paper-dialog>
// in Polymer element
_onDialogKeyDown(e) {
if (e.keyCode === 13) {
this.$.myButton.click();
}
}
demo

lazyRegister: max possible with nested elements or iron pages?

Polymer 1.0
Is it possible to lazyRegister: max with:
1) nesting elements in parentmy-app element?
2) nesting elements in iron-pages?
I have a console.log statement in element single-listing that fires when attached is ran... which does it right away when the app loads. So, lazyRegister is not working for me.
<script>
// Setup Polymer options
window.Polymer = {
dom: 'shadow',
lazyRegister: 'max'
};
...
<my-app></my-app>
my-app.html:
<!-- Main content -->
<iron-pages attr-for-selected="data-route" selected="{{route}}">
<user-login data-route="user-login"></user-login>
<my-view1 data-route="my-view1" form-loading="{{isLoading}}"
listings="[[listings]]" tabindex="-1"></my-view1>
<single-listing data-route="single-listing"></single-listing>
<my-view3 data-route="my-view3"></my-view3>
</iron-pages>
single-listing.html:
attached: function() {
this.async(()=> {
console.log('foo') })
}
Is it possible to lazyRegister: max with nesting elements [...]?
Yes, this is possible, as can be seen in this Plunker.
Plunker note: There's a delay in Plunker before registering x-el, so wait a few seconds after "Hello world" appears before checking the console, which should display x-el attached:
lazyRegister is not working for me
I think you might be misunderstanding the purpose of that flag, and when registration occurs. The flag defers element registration until the element is created. You can create an element declaratively (i.e., by writing "<lazy-element>" in HTML) or imperatively (i.e., document.create('lazy-element'); in JavaScript).
In your example, you've declared the element, which effectively creates it, so the registration occurs when the host of the element is created. In the following example snippet, <lazy-element> is created when <my-app> is created, which is when <my-app>'s definition is imported.
<!-- my-app.html -->
<my-app>
<iron-pages>
<lazy-element></lazy-element>
</iron-pages>
</my-app>
If you want to defer element creation until the page is selected, you could lazy-load the element's import using one of the following methods (and remove lazyRegister flag, as it would be redundant):
this.importHref('lazy-element.html') (See how Polymer Starter Kit does it)
<iron-lazy-pages>
<lazy-imports>

Polymer Component not independent from each other?

Given this simplified component:
<dom-module id="poly-component">
<template>
<paper-button raised onclick="dialog.open()">Button</paper-button>
<paper-dialog id="dialog"><h1>Paper Dialog Here!</h1></paper-dialog>
</template>
<script>
Polymer({
is: 'poly-component'
})
</script>
which does nothing more than open the dialog on clicking the button.
This module works when it used once on a page.
But when it is inserted twice
[...]
<dom-module id="polyTest-app">
<template>
<h2>Hello [[prop1]]</h2>
<poly-component></poly-component>
<poly-component></poly-component>
</template>
[...]
it doesn't work anymore.
A click on the button leads to a:
(index):1 Uncaught TypeError: dialog.open is not a function
Am I missing something?
The code for this example can be found here: Example Code on GitHub
Your code cannot work because you're not binding the event handler correctly.
A built-in handler like onclick tries to execute the bit of code in global scope where dialog doesn't exist. Hence the error.
Here's how you can rewrite your code
<dom-module id="poly-component">
<template>
<paper-button raised on-click="_dialogOpen">Button</paper-button>
<paper-dialog id="dialog"><h1>Paper Dialog Here!</h1></paper-dialog>
</template>
<script>
Polymer({
is: 'poly-component',
_dialogOpen: function() {
this.$.dialog.open();
}
})
</script>
</dom-module>
First, notice how onclick changes to on-click - the Polymer event handling notation. PS. tap event is advised.
Second, you can only access other elements from code. Not directly in bindings. Hence the _dialogOpen function.
UPDATE
Ok, I know what's happening. When there is only one element with a given id, the browsers let's you use it simply by that id in global scope.
When you use Shady DOM, which I assume you do, two instances of your poly-component element render two <dialog id="dialog">. At this point window.dialog is not available anymore.
Again, with Polymer it's safer to use the this.$ notation aka Automatic node finding to reference elements in local DOM.

Issue with two-way binding inside dom-repeat in Polymer 1.0

I have a simple template like this
<template is="dom-repeat" items="[[items]]">
<paper-button active="{{item.selected}}" toggles raised>
<span>[[item.selected]]</span>
</paper-button>
</template>
If I activate the first paper-button in the list by tapping it and then call
this.set('items.0.selected', !this.items[0].selected);
It gets deactivated.
But then if I try the exact steps above again, the button doesn't get deactivated, which makes the button state and the selected value out of sync.
Why is it doing this? The issue can be replicated over here.
Interesting question. So I tried to use a single paper-button binding to a single item instance and it turned out to be working fine, which got me thinking that it might have something to do with path binding inside an array.
So I then added a tap handler to the paper-button and every time it's tapped, do a notifyPath on the selected subproperty path with the value of itself -
this.notifyPath('items.0.selected', this.items[0].selected);
And it works.

Polymer paper-ripple and on-mouseover

I am trying to implement my own custom tooltip element, which displays the tooltip when the on-mouseover event is fired. However, this does not work:
<div class="message>
<custom-tooltip text="{{time}}">
<div>{{message}}</div>
</custom-tooltip>
<paper-ripple fit></paper-ripple>
</div>
because the paper-ripple is "above" the custom-tooltip and therefore not passing on any of its events. I'm not sure if this is a polymer specific issue, or if it just my inexperience with DOM event propagation, but any help would be appreciated.