Polymer 1.0 skip nodes with ExcludeLocalNames - javascript

I try to migrate from Polymer 0.5 to 1.0 and got the following question:
Does anybody know, how to ignore nodes inside a paper-menu? In 0.5 you could set the attribute excludedLocalNames to ignore some of them, but in 1.0 it seems to have changed.
In the IronSelectableBehavior, there is still the property excludedLocalNames, so i thought it must be still working. Has anybody a working example?
The following code was my first attemp to create a submenu with that feature, but the submenu is not ignored by the parent:
<paper-menu selected="{{route}}" attr-For-Selected="entry" excludedLocalNames="paper-menu">
<paper-icon-item entry="home">
<iron-icon icon="home" item-icon></iron-icon>
Übersicht
</paper-icon-item>
<paper-icon-item entry="page1">
<iron-icon icon="label" item-icon></iron-icon>
Page1
</paper-icon-item>
<template is="dom-if" if="{{computeEquals(route,'page1')}}">
<paper-menu class="submenu" selected="{{routePage1}}" attr-For-Selected="entry1">
<paper-icon-item entry1="basics">
<iron-icon icon="icons:assignment" item-icon></iron-icon>
Basics
</paper-icon-item>
<paper-icon-item entry1="tools">
<iron-icon icon="icons:apps" item-icon></iron-icon>
Tools
</paper-icon-item>
</paper-menu>
</template>
<paper-icon-item entry="page2">
<iron-icon icon="label" item-icon></iron-icon>
Page2
</paper-icon-item>
</paper-menu>
Because there is no more submenu-element in 1.0, I tried that way to put a menu inside of a menu. But if I click on a submenu-item, the parent-menu changes his focused item...
Has anybody an idea how to use the excludeLocalNames-attribute?
Edit
Here are links to the documentations:
IronSelectableBehavior
paper-menu

Don't use excludedLocalNames in 1.0. Instead, set the selectable property on the selector to the names of the nodes you would like to allow selection for. Basically, it's a whitelist instead of a blacklist (which is a lot more reliable, too).
For example:
<paper-menu selectable="paper-item,div">
<paper-item>You can select me!</paper-item>
<div class="menu-item">You can select me, too.</div>
<paper-icon-item icon="user">You can't select me.</paper-icon-item>
<header>I'm not selectable either.</header>
</paper-menu>

Related

enable router calls on el-submenus in Element-UI

I'm trying to set up a Navbar in Element-UI with a nested submenu. In additions to opening the submenu, I want the router to go to the index attribute of the submenu. This doesn't happen; clicking on a submenu doesn't activate the router - it only works for el-menu-item and not el-submenu, as far as I can tell.
Here's my code:
<el-submenu index="2">
<template slot="title"><feather type="edit"></feather></template>
<el-submenu :index="subject.label" v-for="subject in subjects">
<template #click="setSubject(subject.label)" slot="title">{{ subject.label }}</template>
<el-submenu :index="spec.label" v-for="spec in subject.children">
<template slot="title">{{ spec.label }}</template>
<el-menu-item :index="prac.label" v-for="prac in spec.children">{{ prac.label }}</el-menu-item>
</el-submenu>
</el-submenu>
</el-menu-item>
I tried adding a click event to <el-submenu :index="subject.label" v-for="subject in subjects">'s template called setSubject. It fails to execute when clicked. Can anyone help me figure this out?

What is the purpose of <template> usage in Vuetify?

I want to use Vuetify 2.0 in my project and currently reading about v-stepper component which is used to display progress through numbered steps.
In the playground example provided I see that they are using <template> element to wrap content of v-stepper component. HTML looks something like this (note: I removed unnecessary details):
<v-stepper>
<template v-for="n in steps">
<v-stepper-content
:key="`${n}-content`"
:step="n"
>
</v-stepper-content>
</template>
</v-stepper>
Notice the <template> tag used. What is the purpose of it? When should I use it as opposed to just putting the <v-stepper-content> directly inside of <v-stepper>?
I've read a bit about element on MDN but I am not sure how to use it specifically with Vuetify (or more generally with Vue.Js or just pure HTML/CSS/JS for that matter).
a <template> in the context of a v-for loop is an organizational item.
It does not get rendered by the browser. It is there to help with more complex rendering situations, where you don't want to limit yourself to a single element
In most cases you have a pretty straight forward mapping of items, each item in an array gets a <li> element. If this is the case, you're not likely to use this.
Here is an example of a problem where it might help...
Let's say you want to loop through an array of objects, and render a v-btn if the object is a button, and a v-image if the object is an image.
without template...
<span v-for="item in items">
<v-btn v-if="item.isBtn"></v-btn>
<v-img v-else-if="item.isImg"></v-img>
</span>
The problem is that each item will be wrapped in the span.
<span>
<v-btn/>
</span>
<span>
<v-img/>
</span>
<span>
<v-btn/>
</span>
If you, however, use the template element, the wrapping element is no longer there.
<template v-for="item in items">
<v-btn v-if="item.isBtn"></v-btn>
<v-img v-else-if="item.isImg"></v-img>
</template>
and you will get...
<v-btn/>
<v-img/>
<v-btn/>
You can also have it return multiple items in one instance of the loop.
in the vue docs at https://v2.vuejs.org/v2/guide/list.html#v-for-on-a-lt-template-gt
it shows an example of rendering more than one item per iteration:
<ul>
<template v-for="item in items">
<li>{{ item.msg }}</li>
<li class="divider" role="presentation"></li>
</template>
</ul>
There are some other cases where this might be helpful but not likely something you come across on a daily basis.
TL;DR;
Vue doesn't render the <template> element. It helps organize code chunk without the need of a single child element when looping
part 2.
When should I use it as opposed to just putting the directly inside of ?
Because the structure of vertical and horizontal steppers is different, the vuetify authors used it in the playground to allow users to toggle it. The first level of template (<template v-if="vertical">) is used do determine whether the next level should render the v-stepper-step elements as vertical or as horizontal. The second level is used to do the iterating of items.
example:
vertical (step and content are siblings):
<template>
<v-stepper v-model="e6" vertical>
<v-stepper-step :complete="e6 > 1" step="1">
Select an app
<small>Summarize if needed</small>
</v-stepper-step>
<v-stepper-content step="1">
<v-card color="grey lighten-1" class="mb-12" height="200px"></v-card>
<v-btn color="primary" #click="e6 = 2">Continue</v-btn>
<v-btn text>Cancel</v-btn>
</v-stepper-content>
<v-stepper-content step="2">...</v-stepper-content>
<v-stepper-step :complete="e6 > 3" step="3">...</v-stepper-step>
</v-stepper>
</template>
horizontal (each step is separate):
<template>
<div>
<v-stepper>
<v-stepper-header>
<v-stepper-step step="1">Select campaign settings</v-stepper-step>
<v-divider></v-divider>
<v-stepper-step step="2">Create an ad group</v-stepper-step>
<v-divider></v-divider>
<v-stepper-step step="3">Create an ad</v-stepper-step>
</v-stepper-header>
</v-stepper>
<v-stepper value="2" class="mt-12">
...
</v-stepper>
<v-stepper value="3" class="mt-12">
...
</v-stepper>
</div>
</template>

how to implement a custom Abort-Button in a vaadin-upload 3.0.0 "Custom File List"

vaadin-upload 3.0.0 "Custom File List" still uses javascript code from vaadin-upload-file.html even though I provide my own HTML in the Shadow Root slot.
I'm not sure if this "works-as-designed", "is-a-bug" or I might not understand Shadow Root v1 slots.
I'm trying to customize a vaadin-upload with a "Custom File List" similar to as described here https://vaadin.com/elements/vaadin-upload/html-examples/upload-advanced-demos
<vaadin-upload id="fileEventsDemo" files="{{files}}">
<div slot="file-list">
<h4>Files</h4>
<ul>
<template is="dom-repeat" items="{{files}}" as="file">
<li>
<strong>[[file.name]]</strong>
[[file.status]]
</li>
</template>
</ul>
</div>
</vaadin-upload>
According to my understanding of Shadow Root v1 this should replace the fallback content in vaadin-upload.htmlwhich uses a <vaadin-upload-file> element
<slot name="file-list">
<div id="fileList" part="file-list">
<template is="dom-repeat" items="[[files]]" as="file">
<vaadin-upload-file file="[[file]]"></vaadin-upload-file>
</template>
</div>
</slot>
So I assumed that <vaadin-upload-file> somehow disappears and I don't have to take care of it and only my HTML will be considered. I actually assumed that there never would be DOM instances of vaadin-upload-file at all. (Though it is imported <link rel="import" href="vaadin-upload-file.html"> by vaadin-upload.html)
But still I can set breakpoints in various JavaScript functions in vaadin-upload-file.html like _formatProgressValue(progress) or _fileAborted(abort) and they are called when the user interacts with the component.
This is especially tricky with _fileAborted(abort) which triggers a file-remove event. Because it will end up in this vaadin-upload.html method.
_removeFile(file) {
this.splice('files', this.files.indexOf(file), 1);
}
When I try to implement my own file list <my-file-list> with a button to "Abort" (triggering a file-abort event) similar to the one in vaadin-upload-list.html
<vaadin-upload ...
<div slot="file-list" id="fileList">
<template is="dom-repeat" items="[[files]]" as="file">
<my-upload-file file="[[file]]"></my-upload-file>
</template>
</div>
</vaadin-upload>
then this.splice('files', this.files.indexOf(file), 1); is called multiple times. From my event from as well as from and indexOf might be negative.
Then multiple items are disappearing from the file list, not only the one that should be removed.
I'm using Ubuntu and Chrome Version 65.0.3311.3 (Official Build) dev (64-bit) for the debugging. The project uses Polymer 2.3.1 and vaadin-upload 3.0.0

app-header doesn't hide Polymer 2.0

I've got a problem since I migrate to Polymer 2.0, my app-header doesn't want to hide but for exemple app-drawer does with the same attribute value. Here is my code:
<app-header slot="header" fixed shadow effects="waterfall" hidden$=[[!storedUser.loggedin]]>
<app-toolbar>
<div class="header--menu header--menu__size">
<paper-button drawer-toggle>
<iron-icon icon="menu" drawer-toggle></iron-icon>
</paper-button>
</div>
<div class="header--title" main-title>Test</div>
<div class="header--setting header--setting__size">
<paper-button on-tap="_logout">
<custom-icon iconset="ci-login" icon="normal"></custom-icon>
<span>[ [[localize('logout')]] ]</span>
</paper-button>
</div>
</app-toolbar>
</app-header>
If you want more info / code don't hesitate.
Thanks
Remove the property fixed from app-header.
Check the documentation for all available properties app-header

Polymer modeling template within template

I'm trying to create dropdown select (appearing if radio button is selected) in Polymer, that triggers another dropdown select on-iron-select.
All of this lives within a parent template:
<dom-module id="likes-cars">
<template id="maintemplate">
<paper-radio-button checked="{{likesCars}}" id="thebutton">I like cars.</paper-radio-button>
<template is="dom-if" if="{{likesCars}}">
<paper-dropdown-menu label="Your favourite car make">
<paper-menu class="dropdown-content" on-iron-select="modelfunc">
<paper-item>Make 1</paper-item>
<paper-item>Make 2</paper-item>
</paper-menu>
</paper-dropdown-menu>
</template>
<template id="menutemp">
<paper-dropdown-menu label="Your favourite car model">
<paper-menu class="dropdown-content" >
<template is="dom-repeat" items="{{models}}"id="modelstemplate" >
<paper-item>{{item}}</paper-item>
</template>
</paper-menu>
</paper-dropdown-menu>
</template>
</template>
And my Polymer script once the iron-select occurs is:
<script>
Polymer({
is:"likes-cars",
modelfunc: function() {
this.$.menutemp.model={}
this.$.modelstemplate.model={models:["Model 1","Model 2"]}
}
});
</script>
This results in the error:
Uncaught TypeError: Cannot set property 'model' of undefined
What is the best way to select and model "modelstemplate" with an array passed in?
Do I need to model the template around it("menutemp") separately?
I think you're misunderstanding how Polymer's data binding works a bit.
When you bind to something using the [[property]] or the {{property}} notation in a custom element, you're binding to the custom element's properties, no matter if you actually define the properties when calling the Polymer() function.
So when you say your dom-if and your paper-radio-button are bound to likesCars and that the dom-repeat is bound to models they're bound to this.likesCars and this.models.
So all you need to do in your modelfunc function is to set this.models to an array of Strings you want to show as items for the second menu. With this considered, the template enveloping the second menu is actually unnecessary.
Here's a jsbin with a working example based on your code, I added a selectedMake property too so that you can actually set different arrays to the second menu depending on what was selected on the first menu.
I hope this helped

Categories

Resources