looping through nested array in alpinejs - html

Nested loop doesn't work. I've checked several times and can't find the problem. My code is :
<script defer src="https://unpkg.com/alpinejs#3.x.x/dist/cdn.min.js"></script>
<div x-data="{ groups:
[{
name:'size',
options:['s','m']
},
{
name:'color',
options:['red','blue']
}]
}">
<template x-for="group in groups">
<h2 x-text="group.name"></h2>
<div>
<template x-for="option in group.options" :key="option">
<div x-text="option"></div>
</template>
</div>
</template>
</div>
Any help is appreciated. Thank you.

Your div placement is wrong.
<script src="https://unpkg.com/alpinejs#3.x.x/dist/cdn.min.js"></script>
<div
x-data="{ groups:
[{
name:'size',
options:['s','m']
},
{
name:'color',
options:['red','blue']
}]
}"
>
<template x-for="group in groups">
<div>
<h2 x-text="group.name"></h2>
<template x-for="option in group.options">
<div x-text="option"></div>
</template>
</div>
</template>
</div>

Related

VUE: How to multiple component partials in one file?

home.vue
<template>
<app-navbar>
<logo title="navbar"></logo>
<div class="navbar-collapse">
<link href="#first" title="first link"></link>
<link href="#second" title="second link"></link>
<link href="#third" title="third link"></link>
</div>
</app-navbar>
</template>
<script>
export default {
name: "Home",
components: {
AppNavbar: () => import('#/components/navbar.vue')
}
}
</script>
navbar.vue
<script>
export default {
name: "AppNavbar",
props: {
title: {
type: String,
default: "navbarDemo"
},
href: {
type: String,
default: "#"
}
},
template: `
<div class="navbar-container">
<component :is="logo">
<div class="navbar-brand">{{ title }}</div>
</component>
<ul>
<component :is="link">
<li class="item">
<a :href="href" class="link">{{ title }}</a>
</li>
</component
</ul>
</div>
</div>
`
};
</script>
I WANT THIS
<div class="navbar-container">
<div class="navbar-brand">navbar</div>
<div class="navbar-collapse">
<ul>
<li class="item">
first link
</li>
<li class="item">
second link
</li>
<li class="item">
third link
</li>
</ul>
</div>
</div>
What am I doing wrong? Is component used differently? I want to use a component and have another component in it in one file (I don't want to have 20 files here just for navbar). Then compose the structure in this way. Possible?
I'm trying a similar HTML structure as here: link
Here is what you need:
home.vue
<app-navbar :links="links">
<template #logo>
<img src=""/>
</template>
</app-navbar>
data() {
return {
links: [
{ href: '#first", title: 'first link' },
{ href: '#second", title: 'secondlink' },
{ href: '#third", title: 'thirdlink' },
]
}
}
navbar.vue
<template>
<div class="navbar-container">
<div class="navbar-brand">
<slot name="logo" />
</div>
<div class="navbar-collapse">
<ul>
<li v-for="link in links" :key="link.href">
<a :href="link.href">{{ link.title }}</a>
</li>
</ul>
</div>
</div>
</template>
<script>
export default {
props: {
links: Array
}
}
</script>
The logo element is passed through a slot (https://fr.vuejs.org/v2/guide/components-slots.html).
You understood <component> wrongly :p <component> do not declare a component, it's only a way to use a component when its name might change.
Instead of writing
<comp1 v-if="test" /> <comp2 v-else /> you could write <component :is="test ? 'comp1" : 'comp2' />. But comp1 and comp2 components still need to be declared somewhere and imported.
Did you check https://v2.vuejs.org/v2/guide/components.html#Dynamic-Components ?
EDIT: If you want to customize links with scoped-slots:
home.vue
<app-navbar :links="links">
<template #logo>
<img src=""/>
</template>
<template #link="{ href, title }">
<a :href="href">{{ title }}</a>
</template>
</app-navbar>
data() {
return {
links: [
{ href: '#first", title: 'first link' },
{ href: '#second", title: 'secondlink' },
{ href: '#third", title: 'thirdlink' },
]
}
}
navbar.vue
<template>
<div class="navbar-container">
<div class="navbar-brand">
<slot name="logo" />
</div>
<div class="navbar-collapse">
<ul>
<li v-for="link in links" :key="link.href">
<slot name="link" :href="link.href" :title="link.title" />
</li>
</ul>
</div>
</div>
</template>
<script>
export default {
props: {
links: Array
}
}
</script>
So the looped links are passed through the slot so the parent is handling the rendering

How can I "refresh" iron-swipeable-container after a change of data in firebase

My code with swipable-container and dom-repeat of firebase-data
<iron-swipeable-container id="teamchat">
<paper-card class="swipe item blue">
<template is="dom-repeat" items="[[tcmmessages]]" as="tcmmessage">
<div class="card-content">
<b>[[tcmmessage.teamname]]</b><br>
[[tcmmessage.beitrag]]<br>
<span class="chatmetadata">von [[tcmmessage.username]]
• [[tcmmessage.update]] • [[tcmmessage.uptime]] </span>
</div>
</template>
</paper-card>
</iron-swipeable-container>
I have defined a listener
listeners: {
'teamchat.iron-swipe': '_onTeamChatSwipe'
},
and remove the firebase-data with '_onTeamChatSwipe'.
That work fine!
But when there is new firebase-data, how can I bring the iron-swipeable-container back again without refreshing the entire page? I don't find a solution.
It looks like you've created just one paper-card that contains multiple messages. When the card is swiped away, your code has no template to refill the container.
Did you actually mean to create a card for each message? That would require moving paper-card inside the template repeater like this:
<iron-swipeable-container id="teamchat">
<template is="dom-repeat" items="[[tcmmessages]]" as="tcmmessage">
<paper-card class="swipe item blue">
<div class="card-content">
<b>[[tcmmessage.teamname]]</b><br>
[[tcmmessage.beitrag]]<br>
<span class="chatmetadata">von [[tcmmessage.username]]
• [[tcmmessage.update]] • [[tcmmessage.uptime]] </span>
</div>
</paper-card>
</template>
</iron-swipeable-container>
When tcmmessages refills (via Firebase), the iron-swipeable-container automatically repopulates with a paper-card per message.
Here's a demo of similar code that shows that behavior:
<head>
<base href="https://polygit.org/polymer+1.4.0/components/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="polymer/polymer.html">
<link rel="import" href="paper-card/paper-card.html">
<link rel="import" href="iron-swipeable-container/iron-swipeable-container.html">
<link rel="import" href="iron-flex-layout/iron-flex-layout-classes.html">
</head>
<body>
<x-foo></x-foo>
<dom-module id="x-foo">
<style include="iron-flex">
paper-card {
margin-bottom: 16px;
}
</style>
<template>
<iron-swipeable-container class="container">
<template is="dom-repeat" items="[[items]]">
<paper-card heading="{{item}}" class="layout vertical">
<div class="card-content">
Swipe me left or right
</div>
</paper-card>
</template>
</iron-swipeable-container>
</template>
<script>
HTMLImports.whenReady(function() {
Polymer({
is: 'x-foo',
properties : {
items: {
type: Array,
value: function() {
return [1,2,3];
}
}
},
_clearListAfterDelay: function(delay) {
this.async(function() {
this.set('items', []);
}, delay);
},
_refillListAfterDelay: function(delay) {
this.async(function() {
this.push('items', 4);
this.push('items', 5);
}, delay);
},
ready: function() {
this._clearListAfterDelay(1000);
this._refillListAfterDelay(2000);
}
});
});
</script>
</dom-module>
</body>
codepen

Polymer paper-tab select first tab programmatically

Our paper-tabs are generated dynamically, how can we select the first tab by default and also fire the change event so that the iron page content is visible.
<paper-tabs id="scrollableTabs" selected={{selected}} scrollable >
<template is="dom-repeat" items="[[liveQueues]]" as="queue" >
<paper-tab on-click="listLiveTokens" >[[queue.queueName]]</paper-tab>
</template>
</paper-tabs>
list: function() {
this.loading=!this.loading;
this.$.list.url = "http://apicall";
var tmp = this.$.list.generateRequest();
console.log(tmp)
},
this script fetches the tab content from the api call
<iron-pages selected="{{selected}}">
<template is="dom-repeat" items="[[liveQueues]]" as="queue" >
<paper-material elevation="1">
<iron-list items="[[queueTokens]]" as="token">
<template>
<div>
<div class="item" tabindex="0">
<span class="avatar" >[[token.tokenNumber]]</span>
<a href$="{{_getDetailsLink(token.tokenId,token.tokenNumber,token.userName,token.statusType,token.userMobile,token.joinDate)}}">
<div class="pad">
<div class="primary">[[token.userName]]</div>
<div class="secondary">[[token.userMobile]]</div>
<div class="secondary dim">[[token.notes]]</div>
<div class="secondary dim">[[token.joinTime]]</div>
</div>
</a>
<iron-icon icon$="[[iconForItem(sminq)]]"></iron-icon>
</div>
</div>
</template>
</iron-list>
</paper-material>
</template>
</iron-pages>
An event will fire every time the dom-repeat changes. You could listen to changes and set selected to 0.
<template is="dom-repeat" items="[[liveQueues]]" as="queue" on-dom-change="setSelected">
In your prototype you define the function.
setSelected: function() {
this.$.scrollableTabs.selected = 0;
}
Note that the function is called every time you update liveQueues and you may not want to reset the tabs every time.
The iron pages should update automatically, if you have data-binding to selected.
Well, I think that ready function is the way to initialize !
ready: function() {
this.selected = 0;
}

Polymer How can I get core-item>core-button to access parent core-list model

I'm learning polymer and I've run into an issue where I have a core-list iterating on a datasource templating a paper-item that houses a core-icon-button.
<core-list id="list" fit>
<template>
<paper-item flex class="row {{ {selected: selected} | tokenList }}">
<core-icon-button id="settings"
icon="settings"
on-tap={{settingTap}}>
</core-icon-button>
{{model.Name}}
</paper-item>
</template>
</core-list>
The problem I am having is that on my buttons' on-tap function I need the parent items' model. Is there a "polymer way" to do what I am describing? Or do I have to extend
<polymer-element name='cust-list'>
<template>
<style>
</style>
<core-list id="list" fit data={{models}}>
<template>
<paper-item flex class="row {{ {selected: selected} | tokenList }}">
<core-icon-button id="settings" icon="settings" on-tap={{settingTap}}></core-icon-button>
{{model.name}}
</paper-item>
</template>
</core-list>
</template>
<script>
Polymer('cust-list', {
models: [{name: "test1"}, {name: "test2"}],
settingTap: function(e,d,s) {
console.log(s.templateInstance.model.model);
}
});
</script>
</polymer-element>
<cust-list></cust-list>

Rendering of polymer element created using template repeat

In the below code we are able to create 7 div tags dynamicaly, if we want to change the style of third div how to do it?
<template repeat="{{ item in items }}">
<div id="in">q{{item}}<t>{{user.question[item].time}}<t>{{user.question[item].score}} </div>
<br><br>
</template>
the project link in git hub :quiz element
You can do a quick hack
<template repeat="{{ item, i in items }}">
<div class="{{i}} question">q{{item}}<t>{{user.question[item].time}}<t> {{user.question[item].score}} </div>
<br><br>
</template>
And you can use the class name to access it.
You can use a contitional expression with the tokenList filter built in with polymer:
<script src="//cdnjs.cloudflare.com/ajax/libs/polymer/0.3.3/platform.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/polymer/0.3.3/polymer.js"></script>
<polymer-element name="question-list">
<template>
<style>
.thirdQuestion {
border: 1px solid red;
}
</style>
<template repeat="{{ item, index in items }}">
<div class="{{ {thirdQuestion: index === 2} | tokenList }} question">
{{item}}
</div>
<br>
<br>
</template>
</template>
<script>
Polymer({
items: [
"item 1",
"item 2",
"item 3",
"item 4",
"item 5",
"item 6",
"item 7"
]
});
</script>
</polymer-element>
<question-list></question-list>
You can do this easily with pseudo-selectors in CSS.
.question:nth-of-type(3){...}
Here is a live example.