How to sort alphabetical dropdown data on polymer - polymer

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.

Related

Select only first item from two-line paper-dropdown-menu

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.

How can I repeat a piece of HTML multiple times without ngFor and without another #Component?

I want to repeat a piece of HTML, multiple times in my template.
But I want it to be repeated at different places on my page. This means that ngFor is not the solution as the pieces would be repeated directly one after the other.
A 'working solution' would be to define a specific #Component for my repeated HTML, and do something like that :
<p>Whatever html</p>
<my-repeated-html></my-repeated-html>
<h4>Whatever</h4>
<my-repeated-html></my-repeated-html>
But I find it overkill to create a dedicated component for doing something like that, it has no functional meaning and is only required by the HTML structure I want to set up.
Is there really nothing in ng2 template engine to allow me to define an "inner template" and use it wherever I need it in the current template?
update Angular 5
ngOutletContext was renamed to ngTemplateOutletContext
See also https://github.com/angular/angular/blob/master/CHANGELOG.md#500-beta5-2017-08-29
original
The recently added ngTemplateOutlet might be what you want
<template [ngTemplateOutlet]="templateRefExpression" [ngOutletContext]="objectExpression"></template>
It can currently be used like
<template #templateRef>
<pre>{{self | json }}</pre>
</template>
<template [ngTemplateOutlet]="templateRef"></template>
A template can also be passed to a child component to be rendered there
#Component({
selector: 'some-child',
providers: [],
template: `
<div>
<h2>Child</h2>
<template [ngTemplateOutlet]="template" ></template>
<template [ngTemplateOutlet]="template" ></template>
</div>
`,
directives: []
})
export class Child {
#ContentChild(TemplateRef) template:TemplateRef;
}
to be used like
<some-child>
<template>
<pre>{{self | json }}</pre>
</template>
</some-child>
stackblitz example
Another Plunker example
that uses data passed as
<template [ngTemplateOutlet]="..." [ngOutletContext]="templateData"
This way ngOutletContext can be used in the template like
<template let-image="image">
{{image}}
where image is a property of templateData
If $implicit is used
<template [ngTemplateOutlet]="..." [ngOutletContext]="{$implicit: templateData}"
the ngOutletContext can be used in the template like
<template let-item>
{{item}}
<campaign-channels-list (onItemSelected)="_onItemSelected($event)" [customTemplate]="customTemplate" (onDragComplete)="_onDragComplete($event)" [items]="m_blockList"></campaign-channels-list>
<template #customTemplate let-item>
<a href="#" [attr.data-block_id]="item.blockID">
<i class="fa {{item.blockFontAwesome}}"></i>
<span>{{item.blockName}}</span>
<i class="dragch fa fa-arrows-v"></i>
<span class="lengthTimer hidden-xs">
{{item.length | FormatSecondsPipe}}
</span>
</a>
</template>
and in rx component:
<div class="sortableList">
<li (click)="_onItemSelected(item, $event, i)" *ngFor="let item of m_items; let i = index" class="listItems list-group-item" [ngClass]="{'selectedItem': m_selectedIdx == i}">
<template [ngTemplateOutlet]="customTemplate" [ngOutletContext]="{$implicit: item}">
</template>
</li>
</div>
pay attention to:
[ngOutletContext]="{$implicit: item}"
as well as
<template #customTemplate let-item>

Can't wrap outer tags in dom-repeat. Polymer seems to automatically close them

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 more-routing

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>

Float a paper-dropdown above other content

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>