Bind to nested element's function in Polymer.js - javascript

I am using Polymer.js, and I am creating an input element with a dropdown suggestions list (like google's search bar).
Basically, I have a core-input, and a core-dropdown, containing a core-menu. I have added two core-a11y-keys to observe arrow keys pressed on the core-input, in order to move the selected item in the core-menu.
I am trying to bind the core-a11y-keys' "on-keys-pressed" event directly to core-menu's selectNext(), and selectPrevious(), but I can't get it to work.
<template>
<link rel="stylesheet" href="suggest-input.css">
<div class="suggest-input-wrapper">
<paper-shadow layout start-justified horizontal center id="feedSearchInput" class="input-shadow">
<input id="searchInput" is="core-input" on-input="{{searchChanged}}" flex placeholder="{{placeholder}}">
<paper-icon-button icon="search" class="feed-search-icon"></paper-icon-button>
<core-dropdown autoFocusDisabled id="suggestionsDropDown" class="suggestions-dropdown">
<core-menu class="suggestions-menu" id="suggestionsMenu">
<template repeat="{{suggestion in suggestionList}}">
<paper-item class="suggestion-item">
<template if="{{suggestion.icon}}">
<core-icon src="{{suggestion.icon}}"></core-icon>
</template>
<template if="{{!suggestion.icon}}">
<core-icon icon="search"></core-icon>
</template>
<h5>{{suggestion.caption}}</h5>
</paper-item>
</template>
</core-menu>
</core-dropdown>
</paper-shadow>
</div>
// First Trial
<core-a11y-keys target="{{searchInput}}" keys="down" on-keys-pressed="{{suggestionsMenu.selectNext}}"></core-a11y-keys>
<core-a11y-keys target="{{searchInput}}" keys="up" on-keys-pressed="{{suggestionsMenu.selectPrevious}}"></core-a11y-keys>
// Second Trial
<core-a11y-keys target="{{searchInput}}" keys="down" on-keys-pressed="{{$.suggestionsMenu.selectNext}}"></core-a11y-keys>
<core-a11y-keys target="{{searchInput}}" keys="up" on-keys-pressed="{{$.suggestionsMenu.selectPrevious}}"></core-a11y-keys>
// Third Trial
<core-a11y-keys target="{{searchInput}}" keys="down" on-keys-pressed="{{this.$.suggestionsMenu.selectNext}}"></core-a11y-keys>
<core-a11y-keys target="{{searchInput}}" keys="up" on-keys-pressed="{{this.$.suggestionsMenu.selectPrevious}}"></core-a11y-keys>
I know I can use custom event handlers, and than call selectNext() and selectedPrevious(), but knowing if it can be done, and how, could help in the future.

Try
target="{{$.searchInput}}"

Related

change the dropEffect of a drag

I am using ngx drag and drop which is using the default HTML5 dnd api.
I have a list of object, when I move them, my event and the drop effect are type "copy"
I am trying to find a way to make the event be a "move" instead because that what is the drag and drop action supposed to be, and I want my OnMove event to fire
I tried change when I start the drag
onDragStart(event:DragEvent, card:KanbanCard) {
event.dataTransfer.dropEffect = "move";
event.preventDefault();
}
But this doesn't work
<div class="kanban-column-container">
<p class="title"><strong>{{column.name}}</strong></p>
<button mat-button (click)="addCard();">Add Card</button>
<div class="list"
dndDropzone
(dndDrop)="onDrop($event)">
<!-- PLACEHOLDER for drag & drop. Removed on DOM LOAD AUTOMATICALLY -->
<div class="card-placeholder" dndPlaceholderRef>
placeholder
</div>
<div *ngFor="let card of _cards"
[dndDraggable]="card"
(dndEffectAllowed)="move"
(dndStart)="onDragStart($event, card)"
(dndCanceled)="onDragCanceled($event, card)"
(dndMoved)="onMoved($event)"
(dndEnd)="onDragEnd($event, card)"
[hidden]="card.hidden">
<kanban-card-component [card]="card"></kanban-card-component>
</div>
</div>
Basicly u did it wrong.
first of it suppose to be [] and not () cos its not a function.
secound if you want to put a value it soppuse to be like you put and Object so this way will work.
<div class="kanban-column-container">
<p class="title"><strong>{{column.name}}</strong></p>
<button mat-button (click)="addCard();">Add Card</button>
<div class="list"
dndDropzone
(dndDrop)="onDrop($event)">
<!-- PLACEHOLDER for drag & drop. Removed on DOM LOAD AUTOMATICALLY -->
<div class="card-placeholder" dndPlaceholderRef>
placeholder
</div>
<div *ngFor="let card of _cards"
[dndDraggable]="card"
[dndEffectAllowed]="'move'" <-- like this
(dndStart)="onDragStart($event, card)"
(dndCanceled)="onDragCanceled($event, card)"
(dndMoved)="onMoved($event)"
(dndEnd)="onDragEnd($event, card)"
[hidden]="card.hidden">
<kanban-card-component [card]="card"></kanban-card-component>
</div>
</div>

Styling Material Vue AutoComplete suggestion drop down

Background
I am using the Material Vue AutoComplete component to provide TypeAhead functionality to my users in a vue application.
When the Chrome browser is minimized in width to check for responsiveness I noticed the suggestion container gets smaller in width but, the text inside of the suggestion container does not break in the box. Instead, the sentence that is being displayed runs off the box to the right of the screen.
Problem
I can not figure out how to add styles to correct the before mentioned issue.
Example
<div class="md-layout md-gutter">
<div class="md-layout-item md-small-size-100">
<md-autocomplete
v-model="currentCustomer"
:md-options="customers"
#md-changed="getCustomers"
#md-opened="getCustomers"
#md-selected="getSelected"
:md-fuzzy-search="false"
>
<label>Search Customers...</label>
<template slot="md-autocomplete-item" slot-scope="{ item, term }">
<md-highlight-text :md-term="term">{{ item.email }}</md-highlight-text>
</template>
<template slot="md-autocomplete-empty" slot-scope="{ term }">
No customers matching "{{ term }}" were found. <a #click="addSearchedCustomer(term)">Create </a>this customer.
</template>
</md-autocomplete>
</div>
Specifically this line runs off the screen when there are no search results,
<template slot="md-autocomplete-empty" slot-scope="{ term }"> No customers matching "{{ term }}" were found. <a #click="addSearchedCustomer(term)">Create </a>this customer.</template>
Image Example
Link AutoComplete
UPDATE
What I have tried
When I inspect the AutoComplete with Chrome Dev Tools, I expand the div and this is what it looks like,
Suggestion Container Div -
Question
Looking at the documentation I can not seem to find a way to handle this. How can I apply styles to this suggestion box so it will break the text as the screen gets smaller?
The templated slot does not appear to respond to word-wrap styling (but other styles like color do work).
One way, a bit hacky, is to use a <label style="white-space: pre-wrap;"> to get a muli-line label, and use a directive to set the height.
template
<md-autocomplete v-model="value" :md-options="colors">
<label>Color</label>
<template slot="md-autocomplete-item" slot-scope="{ item, term }">
<span class="color" :style="`background-color: ${item.color}`"></span>
<label v-wrapit
style="white-space: pre-wrap;"
>{{item.name}}</label>
</template>
<template slot="md-autocomplete-empty" slot-scope="{ term }">
<label v-wrapit
style="white-space: pre-wrap;"
>No colors matching "{{ term }}" were found</label>
</template>
directive
<script>
export default {
name: 'AutocompleteTemplate',
directives: {
wrapit: {
inserted: function (el, binding, vnode) {
el.style.height = `${el.scrollHeight}px`
el.style.color = 'red'
console.log('el', el.scrollHeight, el.offsetHeight, el)
}
}
},
data: () => ({
value: null,
colors: [
{ name: 'Aqua blue blue blue blue blue', color: '#00ffff' },
{ name: 'Aquamarine blue', color: '#7fffd4' },
]
}),
style
This style sets overall list width. It is non-scoped because the menu appears outside <div id="app">
<style>
.md-menu-content {
width: 200px !important;
}
</style>
Here is a CodeSandbox to play with.

How to make the bootstrap table rows selectable and remain the selected rows on filter?

I want to have a bootstrap table and already added input checkboxes to select them as well as a filter to get all selected items (which is totally fine).
After selecting a row, the dataset property "selected" should be set to 1 or true.
But i want to remain all the selected values also when i filter (which should already be fixed by persisting the "selected" attribute in my dataset shouldn't it?)
Currently i can check the checkbox and the checkbox value itself is changed too, but the row.value variable remains the same even if i use v-model for row.value (2-way-databinding)
So. How can i change the value of an attribute in a bootstrap table?
<b-table show-empty
stacked="md"
:items="items"
:fields="fields"
:current-page="currentPage"
:per-page="perPage"
:filter="filter"
:sort-by.sync="sortBy"
:sort-desc.sync="sortDesc"
#filtered="onFiltered"
>
<template slot="selected" slot-scope="row">
<input type="checkbox" id="checkbox" v-model="row.value">
{{row.value}}
</template>
<template slot="name" slot-scope="row">{{row.value}}</template>
<template slot="sapNumber" slot-scope="row">{{row.value}}</template>
<template slot="createDate" slot-scope="row">{{ moment(row.value).format('dd DD.MM.YY, hh:mm:ss')}}</template>
<template slot="master" slot-scope="row">
<!-- We use #click.stop here to prevent a 'row-clicked' event from also happening -->
<b-button size="sm" #click.stop="info(row.item, row.index, $event.target)" class="mr-1">
Info modal
</b-button>
<b-button size="sm" #click.stop="row.toggleDetails">
{{ row.detailsShowing ? 'Hide' : 'Show' }} Details
</b-button>
</template>
<template slot="row-details" slot-scope="row">
<b-card>
<ul>
<li v-for="(value, key) in row.item" :key="key">{{ key }}: {{ value}}</li>
</ul>
</b-card>
</template>
</b-table>
The solution was quite simple.
Just change this part
<template slot="selected" slot-scope="row">
<input type="checkbox" id="checkbox" v-model="row.value">
{{row.value}}
</template>
to this one
<template slot="selected" slot-scope="data">
<input type="checkbox" id="checkbox" v-model="data.item.selected">
</template>
So the scope of this column does not effect the iterators dataset (which is "row" in my case) but the root data set of the data attribute.

Polymer Load Product Page data from JSON

Working with an e-commerce store application with polymer
I'm loading products array using polymer core-ajax and using core-animated pages to display product thumbnail and product detail page (full view) but I only wanted to load the product details when clicking on each product thumb, How can I do this
Find the HTML
<div id="article-content" >
<template is="auto-binding" id="page-template" >
<core-ajax
id="ajaxpolo" auto
url="./json/products.json"
handleAs="json"
on-core-response="{{handleResponse}}" response="{{headerList}}" on-core-response="{{postsLoaded}}">
</core-ajax>
<core-animated-pages id="fpages" flex selected="{{$.polo_cards.selected}}" on-core-animated-pages-transition-end="{{transitionend}}" transitions="cross-fade-all slide-from-right">
<section vertical layout>
<div id="noscroll" fit hero-p>
<div id="container" flex horizontal wrap around-justified layout cross-fade >
<section on-tap="{{selectView}}" id="polo_cards" >
<template repeat="{{item in headerList}}">
<div class="card" vertical center center-justified layout hero-id="item-{{item.id}}" hero?="{{$.polo_cards.selected === item.id || lastSelected === item.id }}" > <span cross-fade hero-transition style="">{{item.name}}</span></div>
</template>
</section>
</div>
</div>
</section>
<template repeat="{{item in headerList}}">
<section vertical layout>
<div class="view" flex vertical center center-justified layout hero-id="item-{{item.id}}" hero?="{{$.polo_cards.selected === item.id || $.polo_cards.selected === 0}}" >
<core-icon-button class="go_back" icon="{{$.polo_cards.selected != 0 ? 'arrow-back' : 'menu'}}" on-tap="{{goback}}"></core-icon-button>
{{item.name}} <span cross-fade class="view-cont" style="height:1000px; overflow:scroll;"></span></div>
</section>
</template>
</core-animated-pages>
</template>
first you would set the auto attribute of core ajax to false. auto="false" that would stop core-ajax from grabbing data by it's self. then set up a on-tap or on-click attribute on the element you want to be the click / tap handler. on-tap="{{getThem}}" then create the function.
getThem: function () {
this.$.ajaxpolo.go();
}
that should get it. hope it helps.
edit: you will want to grab a few more things with your event.
on the click / tap handler add the id of the item you wish to get to a generic attribute. (stay away from normal attributes. ie id, title and so forth) dataId I will call it.
<div on-tap="{{getThem}}" dataId="{{product_id}}"></div>
then in your function you get a few more things with the event as i said before.
getThem: function (event, detail, sender) {
var id = sender.attributes.dataId.value;
// do something with id
}
i just realized i may have misunderstood when you were talking about php. sorry.

Get node inside template if statement

On my polymer-based website I created a custom element in that I am loading data via ajax. Depending on the current state of data-loading i created some <template if="{{}}"> elements to display the right content. It looks something this way:
<polymer-element name="modules-item" attributes="moduleID categories">
<template >
<service-get-module module="{{module}}" moduleID="{{moduleID}}"></service-get-module>
<paper-shadow z="1">
<core-toolbar>
<span flex hero-id="title" hero itemprop="name">{{module.title}}</span>
</core-toolbar>
</paper-shadow>
<paper-progress id="moduleLoadingProgress"></paper-progress>
<template if="{{moduleID == null}}">
<p>Modul not available</p>
</template>
<template if="{{moduleID != null && module == null}}">
<p>Module is loading...</p>
</template>
<template if="{{moduleID != null && module != null}}">
<div id="moduleContainer">
<!-- Content //-->
</div>
<template>
</template>
<script>
Polymer({
module: null,
moduleID: null,
ready: function(){
console.log(this.$.moduleContainer);
}
</script>
</polymer-element>
That works great, but if I try to access the <div id="moduleContainer"> I don't get it... I just read so many posts but did not get any solution. May anybode help me? :)
Here is the link to the live website: http://www.test.gruppenstunde.eu/
UPDATE
After working a little longer with polymer I found out, that it's easier to use the hidden?-Attribute, to casual hide content. Example:
<div hidden?="{{moduleID != null}}">Module not available</div>
You can't access elements within <template if="{{..}}"> or <template repeat="{{..}}"> (dynamically created) using the $ accessor. You need to use querySelector(...) and you can the field only when the if expression evaluates to true (the element is actually created/shown)
to get access to that element you can put that template in a div and give the div a id.
<div id="mod">
<template if="{{moduleID != null && module != null}}">
<div id="moduleContainer">
<!-- Content //-->
</div>
<template>
</div>
then you can
var el = this.$.mod.querySelector("#moduleContainer");

Categories