I'm using polymer 2.0-preview.
I have <paper-dropdown-menu> like this:
<paper-dropdown-menu label="Your devices..." style="margin: 0;">
<paper-listbox slot="dropdown-content" selected="1">
<paper-icon-item>
<iron-icon icon="hardware:phone-android" slot="item-icon"></iron-icon>
<paper-item-body two-line>
<div>PLAY LGE LG-H440n</div>
<div secondary>Last sync: Jan 9, 2014</div>
</paper-item-body>
</paper-icon-item>
<paper-icon-item value="PLAY ASUS Nexus7 2012 WIFI">
<iron-icon icon="hardware:tablet-android" slot="item-icon"></iron-icon>
<paper-item-body two-line>
<div>PLAY ASUS Nexus7 2012 WIFI</div>
<div secondary>last sync: Jan 9, 2014</div>
</paper-item-body>
</paper-icon-item>
</paper-listbox>
</paper-dropdown-menu>
When I select for example first item, what I get is
PLAY LGE LG-H440nLast sync: Jan 9, 2014
what I want is
PLAY LGE LG-H440n
I need to display only first line. I tried to set value to <paper-icon-item> but it doesn't work. How can I do it without creating my own component? Is it even possible?
Ok, I've got it. As per docummentation in paper-dropdown-menu.html file:
<paper-input
type="text"
invalid="[[invalid]]"
readonly
disabled="[[disabled]]"
value="[[selectedItemLabel]]"
placeholder="[[placeholder]]"
error-message="[[errorMessage]]"
always-float-label="[[alwaysFloatLabel]]"
no-label-float="[[noLabelFloat]]"
label="[[label]]">
...
/**
* The derived "label" of the currently selected item. This value
* is the `label` property on the selected item if set, or else the
* trimmed text content of the selected item.
*/
selectedItemLabel: {
type: String,
notify: true,
readOnly: true
}
I need to set label on my <paper-icon-item> element.
Related
I'm trying to pass slot into the slot but child component which requires passed down slot doesn't see it.
In the child (TheTable) I have table component from Core UI for Vue (CDataTable) which requires certain slots which I want to pass from a parent:
<CDataTable
class="overflow-auto"
:items="this.items"
:fields="fieldData"
:sorter="{ external: true, resetable: true }"
:sorter-value="this.sorterValue"
:table-filter="{ external: true, lazy: false, placeholder: 'Enter here', label: 'Search:'}"
:responsive="false"
:loading="this.loading"
:hover="true"
:items-per-page-select="true"
:items-per-page="this.perPage"
#pagination-change="paginationChanged"
#update:sorter-value="sorterUpdated"
#update:table-filter-value="filterUpdated"
>
<slot name="requiredTableFields"></slot>
</CDataTable>
In the parent component I have:
<TheTable
v-bind:fields="fields"
v-bind:endpoint-url="endpointUrl"
>
<template slot="requiredTableFields">
<td slot="name" slot-scope="{item}">
<div>{{ item['attributes.email'] }}</div>
<div class="small text-muted">
{{ item['attributes.firstname'] }} {{ item['attributes.lastname'] }}
</div>
</td>
<td slot="registered" slot-scope="{item}">
<template v-if="item['attributes.created_at']">{{ item['attributes.created_at'] }}</template>
<template v-else>Not setup yet</template>
</td>
</template>
</TheTable>
Is there any way to make it work?
Cheers,
Casper
Merging the underlying slots into a single requiredTableFields slot isn't going to work because there's no (easy) way to break the child slots back out once they've been merged.
Instead you can just keep the slots separate:
<TheTable ...>
<template v-slot:name="{ item }">
<td>
...
</td>
</template >
<template v-slot:registered="{ item }">
<td>
...
</td>
</template>
</TheTable>
This is passing two scoped slots, name and registered, into TheTable.
Assuming you don't want to hard-code the slot names into TheTable you'd then need to iterate over the $scopedSlots to include them dynamically.
<CDataTable ...>
<template v-for="(x, slotName) in $scopedSlots" v-slot:[slotName]="context">
<slot :name="slotName" v-bind="context" />
</template>
</CDataTable>
Some notes on this:
x is not used, we just need to loop over the slot names.
The 'data' associated with the scoped slot is referred to as context and is just passed on.
If the slots weren't scoped slots it'd be slightly different. We'd iterate over $slots instead and remove all the parts that refer to context.
There is a : at the start of the :name attribute as we want to pass a dynamic name. It is an unfortunate coincidence that one of the slots in the original question is also called name, potentially leading to some confusion here.
The v-bind="context" part is analogous to the JavaScript spread operator, if that makes it any clearer. Think of it as attributes = { name: slotName, ...context }.
Below is a complete example illustrating this technique outlined above. It doesn't use CDataTable but the core principle for passing on the slots is exactly the same.
const Comp2 = {
template: `
<div>
<h4>Left</h4>
<div><slot name="top" item="Red" /></div>
<h4>Right</h4>
<div><slot name="bottom" item="Green" /></div>
</div>
`
}
const Comp1 = {
template: `
<div>
<comp2>
<template v-for="(x, slotName) in $scopedSlots" v-slot:[slotName]="context">
<slot :name="slotName" v-bind="context" />
</template>
</comp2>
</div>
`,
components: {
Comp2
}
}
new Vue({
el: '#app',
components: {
Comp1
}
})
<script src="https://unpkg.com/vue#2.6.11/dist/vue.js"></script>
<div id="app">
<comp1>
<template v-slot:top="{ item }">
<button>Slot 1 - {{ item }}</button>
</template>
<template v-slot:bottom="{ item }">
<button>Slot 2 - {{ item }}</button>
</template>
</comp1>
</div>
I have a dropdown like this :
<div>
<paper-dropdown-menu label="Speciality">
<paper-listbox id="selectSpeciality" slot="dropdown-content" attr-for-selected="name" selected="{{doctor.speciality}}" class="dropdown-content">
<template is="dom-repeat" items="[[specs]]">
<paper-item name="[[item]]">[[item]]</paper-item>
</template>
</paper-listbox>
</paper-dropdown-menu>
</div>
And data like this :
How to sorting by alpabetical ?
Thanks
You have to order the categories obtained instead of showing them directly, you can create a function that sorts them or better save them already sorted.
Per the template below, I am trying to keep words from breaking using CSS white-space tags. The problem is Polymer seems to automatically close the open tags I am using as the wrapper. Any help?
<template is="dom-repeat" items="{{getHiddenStrArr(diffObj.value)}}" as="char" >
<template is="dom-if" if="{{!index}}">
<together>[
</template>
<template is="dom-if" if="{{!isASpace(char)}}">
<span class="added-char">{{char}}</span>
</template>
<template is="dom-if" if="{{isASpace(char)}}">
]</together>
<span class="added-char"> </span>
<together>[
</template>
<template is="dom-if" if="{{isEndOfList(diffObj.value, index)}}">
]</together>
</template>
</template>
Resulting HTML:
I know the logic is correct as I used "[" and "]"to represent what the tags are doing visually. Such as:
[ - - - - ] [ - - - ] [ - - ! ]
Polymer: 1.0.3
More routing: 1.0.0
Having some issues with Polymer "more-routing". Those are -
1) Get this log on console -
[dom-bind::_annotatedComputationEffect]: compute method `urlFor` not defined
2) First level routing works (even though I get those error/warning messages). But second level routing (i mean nested routing) does not work. On "users" page pressing the name doesn't take me to "user-info" page. In fact the name does not appear as a link, it appears as a text. Here is my code -
My "routing.html"--
<link rel="import" href="../bower_components/more-routing/more-routing.html">
<more-routing-config driver="hash"></more-routing-config>
<more-route name="home" path="/"></more-route>
<more-route name="users" path="/users">
<more-route name="user-info" path="/:name"></more-route>
</more-route>
<more-route name="contact" path="/contact"></more-route>
My "index.html" ---
<more-route-selector>
<paper-menu class="list" on-iron-select="onMenuSelect">
<a route="home" href="{{urlFor('home')}}">
<iron-icon icon="home"></iron-icon>
<span>Home</span>
</a>
<a route="users" href="{{urlFor('users')}}">
<iron-icon icon="info"></iron-icon>
<span>Users</span>
</a>
<a route="contact" href="{{urlFor('contact')}}">
<iron-icon icon="mail"></iron-icon>
<span>Contact</span>
</a>
</paper-menu>
</more-route-selector>
<more-route-selector selectedParams="{{params}}">
<iron-pages>
<section route="home">
<paper-material elevation="1">
<bortini-home></bortini-home>
</paper-material>
</section>
<section route="users">
<paper-material elevation="1">
<h2 class="paper-font-display2">Users</h2>
<p>This is the users section</p>
Rob
</paper-material>
</section>
<section route="user-info">
<paper-material elevation="1">
<h2 class="paper-font-display2">
User:<span>{{params.name}}</span>
</h2>
<div>This is <span>{{params.name}}</span>'s section</div>
</paper-material>
</section>
<section route="contact">
<paper-material elevation="1">
<h2 class="paper-font-display2">Contact</h2>
<p>This is the contact section</p>
</paper-material>
</section>
</iron-pages>
</more-route-selector>
With 1.0 (perhaps earlier), Polymer stopped supporting expressions inside data-bindings (Migration Guide - Data binding). Thankfully, you can still call a function in a binding (called a "computed binding").
From what I can tell, the urlFor() method must be slightly too complex to work as a computed binding (the params object isn't a dependent property). I was able to make it work by wrapping urlFor() in a simpler function - one that works as a computed binding - something like this:
<more-routing-config driver="path"></more-routing-config>
<more-route name="users" path="/users">
<more-route name="user-info" path="/:name"></more-route>
</more-route>
<template is="dom-bind">
Rob
</template>
<script>
var template = document.querySelector('template');
template.makeUrl = function(route, name) {
return MoreRouting.urlFor(route, {name:name});
};
</script>
You can also pass variables in your computed binding, as long as they're dependent properties, like the item in a repeating template
<template is="dom-bind">
<template is="dom-repeat" items="{{users}}">
{{item.name}}
</template>
</template>
<script>
var template = document.querySelector('template');
template.makeUrl = function(route, user) {
return MoreRouting.urlFor(route, {name:user.name});
};
</script>
Here's my problem:
I have a paper-dialog with a input field and a dropdown. Here's the code (jade):
paper-action-dialog#createMatch(ng-heading="'Create Match' | translate", transition="core-transition-bottom", style="width: 600px")
p
| {{"Choose your match options" | translate}}
p
paper-input#matchNameInput(floatinglabel="",ng-label="'Match Name' | translate", required="", ng-error="'You must enter a match name.' | translate",style="padding: 0")
p
paper-dropdown-menu#gameModeInput(ng-label="'Game mode' | translate")
paper-dropdown.dropdown
core-menu.menu
paper-item(ng-repeat="(id, name) in GameModeN" value="{{id}}") {{name}}
paper-button(affirmative="") {{"Cancel" | translate}}
paper-button.primary-btn(affirmative="", autofocus="") {{"Create" | translate}}
Here's the converted HTML if it burns your eyes too much:
<paper-action-dialog id="createMatch" heading="Create Match" transition="core-transition-bottom" style="width: 600px">
<p>Choose your match options</p>
<p>
<paper-input id="matchNameInput" floatinglabel="" label="Match Name" required=""></paper-input>
</p>
<p>
<paper-dropdown-menu id="gameModeInput" label="Game Mode">
<paper-dropdown class="dropdown">
<core-menu class="menu">
<paper-item value="value">Item</paper-item>
</core-menu>
</paper-dropdown>
</paper-dropdown-menu>
</p>
<paper-button affirmative="">Cancel</paper-button>
<paper-button affirmative="" autofocus="" class="primary-btn">Create</paper-button>
</paper-action-dialog>
I've tried using position:absolute and nearly every combination of position types on the menu and its parents. Nothing seems to work. Perhaps this is because it's in a shadow dom? How can I get the menu to float over everything else?
The layered attribute should do this
<paper-dropdown class="dropdown" layered="true">
<core-menu class="menu">
<paper-item value="value">Item</paper-item>
</core-menu>
</paper-dropdown>