Polymer core-list delete item - polymer

How could I remove an Item in a core-list or clear the list?
I retrieve my list from a Database. When I select an Item, the Item would be deleted in the Database and my list refreshed.
But the last Item could not deleted, because my list doesn' t refresh without an entry in the Database.
How could I remove the last entry.
<core-list
on-core-activate="{{selectBookedItem}}"
id="listNewBookedItems"
data="{{ajaxResponseBookedItem}}">
<template>
<div id="bbb" class="newBookedItem {{ {selected: selected} | tokenList }}">
<div id="itemFontSmall">Preis: {{artikelpreis}}</div>
</div>
</template>
</core-list>
Polymer('element-posmain', {
// Remove Code
});

Assuming ajaxResponseBookedItem is observable then you should be able to just remove the item from the list that corresponds to ajaxResponseBookedItem and core-list should pick it up. Ie remove from the model and let the view update itself
This works for me at least in the dart version

Related

ng select not working with parent div ng-repeat

If I am using exact text for comparison in ng-init or ng-selected then it works fine for eg. ng-init="status='OPEN'" but this is not working when I am using loop variable data.status. Any suggestion?
<div ng-repeat="user in filtered = userList | filter:search">
<select ng-selected="{{user.status == item.id}}" ng-options="item.name for item in item track by item.id" ng-model="status" name="status">
</select>
</div>
$scope.item = [
{id: 'OPEN', name: 'OPEN'},
{id: 'RESCHEDULE', name: 'RESCHEDULE'},
{id: 'CANCEL', name: 'CANCEL'},
{id: 'CLOSED', name: 'CLOSED'}
];
It's a little unclear what exactly it is you are trying to do, and I think you may be trying to do a lot in one go when you should break it down more. One things that does stand out is that you are using ng-selected wrong.
Firstly you don't need to wrap the conditional in handlebars {{ }}. (That implies a 2 way binding to a JavaScript object, and makes no sense in this context).
Secondly, the ng-selected directive can't be applied on a select element, only on an option element.
To do what I think you are trying to do (pre-select an option) depends on how you are working. Here are a couple of ways
2 way binding
Remember that the data that you are binding to with ng-model is bound with a 2 way binding which means that the selection will match the underlying data. In this case you shouldn't need to do anything fancy in the template.
<div ng-repeat="user in userList">
<select ng-options="item.name for item in itemList track by item.id" ng-model="user.selectedItem">
</select>
</div>
Instead you just handle it in your controller:
//This shows a static example. Change to whatever is appropriate, probably in a for loop etc
$scope.userList[1].selectedItem = $scope.itemList[1]
ng-repeat inside the select
Alternatively you may want to take the approach of using ng-repeat inside your select element. This then allows you to specify the behaviour more closely on an option by option basis.
<div ng-repeat="user in userList">
<select ng-model="user.selectedItem">
<option ng-repeat="item in itemList" ng-selected="user.status === item.id">
</select>
</div>
(N.b. I have edited some of your variable names for clarity eg. changed 'item' to 'itemList')

dynamically edit template of iron-list

At first, i know, there are many questions about iron-list. But mostly about editing items and not whole template inside iron-list..
My code is really extremely complicated and posting it is pointless. I am working on data-tables which are using iron-list. I have element called diamond-listing and inside this diamond-listing i have iron-list.
You can image this like: Parent element define <template> with some content inside it, and child element (diamond-listing) will render this template as a table
Of course diamond-listing is used multiple times in my application and always with different template. For example: page users have columns with userID, userName etc.. and on page stations there are columns stationID, address etc.. with different number of columns. Every pagea has it's own <template> which i am trying to propagate to diamond-listing. For example:
<diamond-listing as="user" id="permissionsTable" type="pagination" pagination-items-per-page="6" header-data="{{headerData}}" address="/user/" loading="{{loading}}">
<div id="test" slot="content">
<template>
<div class="diamond-row" on-tap="_openUrl" info$="/user/[[user.id]]">
<diamond-item text="{{user.username}}"></diamond-item>
<diamond-item text="{{user.partner.name}}"></diamond-item>
</div>
</template>
</div>
</diamond-listing>
What i managed to do is to make it work in shadow dom using <slot> and simply rewrite <template> inside <iron-list>, but here we are.. For example using Firefox, which doesn't support webcomponents, there isn't <template> as a child of <iron-list> (because there is no shadow-dom) so there is no way how to update <template> and render iron-list.
What i tried:
1) Find template inside iron-list and use removeChild and appendChild functions.
var test = this.querySelector("#test template");
this.$$("#diamondList").removeChild(this.$$("#diamondList template"));
this.$$("#diamondList").appendChild(test);
Without success.
2) Define in HTML empty iron-list without any template inside it. And then in javascript add template dynamically. Without success. ( iron-list is crying it requires template)
3) Create dynamically iron-list using document.createElement
var test = this.querySelector("#test template");
var list = document.createElement("iron-list");
list.appendChild(test);
list.as = this.as;
list.items = [{"username":"test","partner":{"name":"Test partner","id":1}}];
list.id = "diamondList";
result: same as 2) ...
Is there a way, how to update template which is used to render all items in iron-list?
Or create iron-list with defined template inside JS ?
Or somehow do it with dom-repeat ? I won't have more than 10 items in listing, since it's fully pagination listing. ( this is propably simplest solution, but i don't know how to render <template> for every iteration
Here is one general answer, don't know if it will work for your case:
In Polymer, recommended way of manipulating the DOM is by manipulating the data, not by removeChild or appendChild.
For example,
if you have list of users as: var users_array = [....];
create the iron-list as:
<iron-list date="users_array">
<template>
...
<template>
</iron-list>
adding and removing elements in users_array will affect the iron-list
immediately.
Use a dom-if or use hidden inside the iron-list.
<iron-list items="[[items]]">
<template>
<template is="dom-if" if="[[item.isType1]]">
<!-- item1 -->
</template>
<template is="dom-if" if="[[item.isType2]]">
<!-- item2 -->
</template>
</template>
</iron-list>

Polymer bind object dom-repeate

I run on loop on the list (this is array). and for every I create icon-status with property item.status.
I want that is item.status changed for some reason also the property to the icon will change.
<template is="dom-repeat" items="{{list}}">
<paper-item>
<paper-item-body>
<div class="horizontal layout font-md">
//this is also dont bind on change
<icon-status state={{item.status}} size=7></icon-status>
<div class="flex"></div>
//this is not bind on change
<div class="gray">{{item.status}}</div>
</div>
</paper-item-body>
</paper-item>
</div>
</div>
</template>
I tried using timeout change the status of the items and the view does not update.
How can I bind this?
Thanks
To add binding support for list:
To update the value in the current element, use this.set('list.0.status', 'newStatus');
To update the value in a parent element, add list as a property on the current element:
list: { type: Array, notify: true }
Consider changing your template binding from two-way to one-way as the data is only flowing in one direction, <template is="dom-repeat" items="[[list]]">

Getting the index of a selected item from a polymer core-list

I'm trying to scroll a simple core-list with a keyboard key.
This is the core-list:
post-list.html
<core-list data="{{posts}}" selectionEnabled="true" selection="{{selectedPost}}" on-core-select="{{selectedHandler}}" fit >
<template repeat>
<post-card post="{{model}}" index="{{index}}" ></post-card>
</template>
I need to get the index of the selected post-card, increment it and pass it to the selectItem and scrollToItem methods of the core-list.
The problem I'm facing is... how do i get the index?
I searched for an easy way to get the it both in core-list and in core-selection without success.
Unfortunately the core-list attribute "selection" from core-list is the data of the current selected record (so I can't get the index attribute from it).
Am I missing something?
Is there any solution that doesn't involve handling the index directly in the post-card component?
Thanks.
Core-list item is core-selection which handling selection event. You could try to use core-select event which you could get the index of selected item. So it could be like this
selectedHandler: function(e, detail, sender) {
var i=this.$.selection.indexOf(detail.item);
this.scrollToItem(i+1);
}

Bind event to element in a template repeat

Is it possible to get the elements that will be/were rendered from a <template repeat>?
I have a component called poly-list, implemented below:
<poly-list dataList="{{ data.in }}" id="inList"
style="overflow: hidden; min-width: 324px; display: inline-block;">
<template>
<div> <!-- on-click event here -->
<paper-input-no-error value="{{ [0] }}"
class="in-paper-input"
on-change="{{ inChanged }}" id="0"></paper-input-no-error>
<paper-input-no-error value="{{ [1] }}"
class="in-paper-input"
placeholder="Value" id="1"></paper-input-no-error>
</div>
</template>
</poly-list>
I then activate the template in the domReady callback:
this.template.model = this.data;
this.template.setAttribute('repeat', '');
I need a way to get each individual element that the template will put into the DOM. I need to do this in order to add an event listener to each component that is rendered. I also want this to be encapsulated in my poly-list components so components implementing poly-list will not need to setup the event itself.
I need to add the event to the top level element in the template repeat. In this case it is the div. I commented where I mean in the code above. Event bubbling could work but would not be reusable due to the fact that I do not know how for in the element will be that triggered the event thus making it impossible to say the top level element is always 1 parent element above as in the example above.
Is there an event that will return each element as it is rendered or something similar?
"Is it possible to get the elements that will be/were rendered from a template repeat?"
Yes, but only after Template Repeat has finished. Then you can select the elements by automatic node finding: this.$
There is an example here: How can I know that Template Repeat has finished?
Can't you just use Polymer's declarative event binding?
<poly-list ...>
<template>
<div on-click="{{ clickHandler }}">
<paper-input-no-error ...></paper-input-no-error>
<paper-input-no-error ...></paper-input-no-error>
</div>
</template>
</poly-list>
(with a method on your outer element's prototype called clickHandler)
With regards to bubbling, there probably is some way which you could get it to work.