I am trying to make a text show or not based on conditions called in a function.
I have the following snippet :
<dom-module id="lfr-defis">
<template>
<style is="custom-style" include="iron-flex iron-flex-alignment"></style>
<style is="custom-style">
h4{
margin-top: 10px;
margin-bottom: 0px;
}
paper-card{
margin-top: 5px;
}
p{
margin-top: 5px;
margin-bottom: 0px;
}
</style>
<div>
<paper-icon-button icon="add" on-tap="newDefi" style="float: right"></paper-icon-button>
</div>
<div style="margin-top: 5px">
<template is="dom-repeat" items="[[defis]]">
<paper-card style="width: 100%">
<div class="card-content">
<div class="layout horizontal">
<paper-input label="Jeu" class="flex" always-float-label value="{{item.gameName::change}}"></paper-input>
<div style="margin:5px"></div>
<paper-input label="Incentive" class="flex" always-float-label value="{{item.incentiveName::change}}"></paper-input>
</div>
<label for="datetime"><b>Date : </b></label><datetime-input id="datetime" value="{{item.date::change}}"></datetime-input>
<h4>Défi FR</h4>
<div class="layout horizontal justified">
<paper-input value="{{item.fr.name::change}}" class="flex">
<iron-icon icon="label" slot="prefix"></iron-icon>
</paper-input>
<div style="margin:5px"></div>
<paper-input value="{{item.fr.amount::change}}" type="number">
<div slot="prefix">$ </div>
</paper-input>
<div style="margin:5px"></div>
<paper-input value="{{item.fr.rank::change}}" type="number">
<iron-icon icon="editor:format-list-numbered" slot="prefix"></iron-icon>
</paper-input>
</div>
<h4>Concurrent direct</h4>
<div class="layout horizontal justified">
<paper-input value="{{item.concurrent.name::change}}" class="flex">
<iron-icon icon="label" slot="prefix"></iron-icon>
</paper-input>
<div style="margin:5px"></div>
<paper-input value="{{item.concurrent.amount::change}}" type="number">
<div slot="prefix">$ </div>
</paper-input>
<div style="margin:5px"></div>
<paper-input value="{{item.concurrent.rank::change}}" type="number">
<iron-icon icon="editor:format-list-numbered" slot="prefix"></iron-icon>
</paper-input>
</div>
<template is="dom-if" if="{{!hasAllFields(item)}}">
<p style="color:red">Tous les champs doivent être renseignés</p>
</template>
<template is="dom-if" if="{{!validRank(item.fr.rank, item.concurrent.rank)}}">
<p style="color:red">Un des rangs doit être égal à 1</p>
</template>
<template is="dom-if" if="{{!validAmount(item.fr.rank, item.concurrent.rank, item.fr.amount, item.concurrent.amount)}}">
<p style="color:red">Le montant du 1er doit être supérieur à l'autre</p>
</template>
</div>
<div class="card-actions">
<paper-icon-button title="Sauvegarder" icon="save" on-tap="save" data-item$="{{item}}" style="color:deepskyblue"></paper-icon-button>
<paper-icon-button title="Annuler" icon="cancel" on-tap="cancel" data-item$="{{item}}" style="color:lightcoral"></paper-icon-button>
<paper-icon-button title="Supprimer" icon="delete" on-tap="delete" data-item$="{{item}}" style="float:right"></paper-icon-button>
<paper-icon-button title="Archiver" icon="archive" on-tap="archive" data-item$="{{item}}" style="float:right; color:gray"></paper-icon-button>
</div>
</paper-card>
</template>
</div>
</template>
<script src="defis.js"></script>
</dom-module>
Javascript :
class Defis extends Polymer.Element {
static get is() {
return 'lfr-defis';
}
static get properties() {
return {
defis: {
type: Array,
value: []
}
}
}
constructor() {
super();
}
newDefi() {
this.push('defis', {
id: + new Date(),
date: + new Date(),
fr: {},
concurrent: {}
});
}
save(event) {
const item = this.getItem(event);
const index = this.defis.findIndex(d => d.id === item.id);
if(index !== -1){
this.defis[index] = item;
}
else{
this.push('defis', item);
}
}
cancel(event) {
const item = this.getItem(event);
const index = this.defis.findIndex(d => d.id === item.id);
if(index !== -1){
this.set('defis.' + index, item);
}
}
delete(event) {
const item = this.getItem(event);
const index = this.defis.findIndex(d => d.id === id);
this.splice('defis', index, 1);
}
archive(event) {
const item = this.getItem(event);
const index = this.defis.findIndex(d => d.id === id);
this.splice('defis', index, 1);
}
getItem(event) {
return JSON.parse(event.target.dataset.item);
}
hasAllFields(item, trigger) {
return item.gameName && item.incentiveName && item.date &&
item.fr.name && item.fr.amount && item.fr.rank &&
item.concurrent.name && item.concurrent.amount && item.concurrent.rank;
}
validRank(rankA, rankB) {
return rankA && rankA === '1' || rankB && rankB === '1';
}
validAmount(rankA, rankB, amountA, amountB) {
return rankA > rankB && parseInt(amountA) < parseInt(amountB) ||
rankA < rankB && parseInt(amountA) > parseInt(amountB) ||
rankA === rankB && parseInt(amountA) === parseInt(amountB);
}
isValid(item) {
return this.hasAllFields(item) && this.validRank(item.fr.rank, item.concurrent.rank) &&
this.validAmount(item.fr.rank, item.concurrent.rank, item.fr.amount, item.concurrent.amount);
}
}
customElements.define(Defis.is, Defis);
The problem I have is that the hasAllFields(item)
function is called only once on page load, and not when I change the values in my <paper-input>
fields (which would be the expected behaviour). Therefore, since the function returns false
on load, the message is shown, however it is never updated, thus doesn't hide when all my fields are filled.
I've seen that it might be related to the use of the item
element in a <dom-repeat>
but I couldn't find any solution to this.
If you want Polymer to update subproperties in DOM, then you need to add those subproperties to the method call. Polymer isn't smart enough to understand when subproperies are updated.
<template is="dom-if" if="{{!hasAllFields(item.gameName, item.incentiveName, tem.date, item.fr.name, item.fr.amount, item.fr.rank, ), item.concurrent.name, item.concurrent.amount, item.concurrent.rank}}">
Another way is to add an observer, that checks the same properties as above, that updates an int property every time the properties change, and then you pass that int into hasAllFields
, for example hasAllFields(inputUpdatedInt)
. A third way would be to add an listener on input and then do a hard reset on debris with this.set('debris', []
before setting the new values because that will actually change item
that you're checking against now.