polymer equivalent to ng repeat - javascript

I am rewriting a page that is currently using an Angular 1 framework to polymer 1 (or 2). I don't know what the equivalent of ng-repeat is in polymer. This is what I have right now in Angular 1.
<div class="consultant" ng-repeat="consultant in consultants | limitTo:i">
<p>{{consultant.displayName}}</p>
<p ng-if="consultant.phoneNumber != undefined" >☎ {{consultant.phoneNumber}}</p>
<br ng-if="consultant.phoneNumber == undefined" />
<p class="email" ng-if="consultant.email != undefined" ><span class="icon-envelope"></span> {{consultant.email}}</p>
<br ng-if="consultant.email == undefined" />
</div>

What you are looking for is dom-repeat and probably dom-if
In your case this could look something like this:
<template is="dom-repeat" items="[[consultants]]" as="consultant">
<div class="consultant">
<p>[[consultant.displayname]]</p>
<template is="dom-if" if="[[consultant.phoneNumber]]">
<p>☎ [[consultant.phoneNumber]]</p>
</template>
<template is="dom-if" if="[[!consultant.phoneNumber]]"><br></template>
<template is="dom-if" if="[[consultant.email]]">
<p class="email">
<span class="icon-envelope"></span>
[[consultant.email]]
</p>
</template>
<template is="dom-if" if="[[!consultant.email]]"><br></template>
</div>
</template>

Related

can not loop through $slots object in Vue 3 to pass all slots from parent to child

I can not loop through the $slots object in Vue 3 to pass all slots from parent to child, the $slots object seems empty in the child component.
How can I loop through the $slots object to pass all parent slots to the child component?
I get this error when I run the code:
TypeError: Cannot read properties of null (reading 'key')
Here is a sandbox about my problem and you can uncomment line 5 to see the complete result:
https://codesandbox.io/s/blazing-bush-g7c9h?file=/src/pages/Index.vue
GitHub sample:
https://github.com/firibz/vue3slots
parent:
<system-input filled v-model="text" label="input">
<template v-slot:before>
<q-icon name="mail" />
</template>
</system-input>
child:
<div class="row justify-center">
<q-input v-model="componentValue" v-bind="$attrs" style="width: 250px">
<template v-for="(_, slot) of $slots" v-slot:[slot]="scope">
<slot :name="slot" v-bind="scope"/>
</template>
</q-input>
<q-separator class="full-width" color="secondary" />
<div class="bg-negative full-width q-pa-lg">slots: {{ $slots }}</div>
<div class="bg-warning full-width q-pa-lg">slots: {{ $slots.before }}</div>
</div>
You have to use Object.keys($slots) in order to use slots on v-for.
<q-input v-model="componentValue" v-bind="$attrs" style="width: 250px">
<template v-for="(slot, index) of Object.keys($slots)" :key="index" v-slot:[slot]>
<slot :name="slot"></slot>
</template>
</q-input>

Quasar file picker change text color of selected file name in q-file

Quasar File Picker component to change the text color of selected file name in <q-file>.
the text file selected is test.odt, how can I change it's text color for example Red?
<q-file
standout
class="registration-field text-red"
bg-color="blue-2"
v-model="registrationNumber"
color="red"
>
<template v-slot:prepend>
<q-icon name="o_insert_photo" size="24px" color="blue" />
</template>
<template v-slot:append>
<div class="attachment text-grey-14">File</div>
</template>
</q-file>
I've tried using style props color="red" and it's not working.
anyone know how?
You can Use the file slot and add text-red class and it works.
<q-file
standout
class="registration-field text-red"
bg-color="blue-2"
v-model="registrationNumber"
color="red"
>
<template v-slot:prepend>
<q-icon name="photo" size="24px" color="blue"/>
</template>
<template v-slot:append>
<div class="attachment text-grey-14">File</div>
</template>
<template v-slot:file="{ index, file }">
<div class="ellipsis text-red relative-position">
{{ file.name }}
</div>
<q-tooltip>
{{ file.name }}
</q-tooltip>
</template>
</q-file>
Codepen- https://codepen.io/Pratik__007/pen/wvWzOoV

Same slot content for multiple template slots

In vuejs, is there a way to set the same content for multiple slots without copy pasting?
So this:
<base-layout>
<template slot="option">
<span :class="'flag-icon-' props.option.toLowerCase()" />{{ countriesByCode[props.option] }}
</template>
<template slot="singleLabel">
<span :class="'flag-icon-' props.option.toLowerCase()" />{{ countriesByCode[props.option] }}
</template>
</base-layout>
Could be written that way:
<base-layout>
<template slot="['option', 'singleLabel']">
<span :class="'flag-icon-' props.option.toLowerCase()" />{{ countriesByCode[props.option] }}
</template>
</base-layout>
Thanks a lot.
You could try using v-for for that.
<base-layout>
<template :slot="slotName" v-for="slotName in ['option', 'singleLabel']">
<span :class="'flag-icon-' props.option.toLowerCase()" />{{ countriesByCode[props.option] }}
</template>
</base-layout>
See working example.

neon-animated-pages with embedded dom-repeat element

We are building a survey mechanism where we can have the user create their own set of questions, the type, etc. The users can show up a single element at a time. Or a group of questions. I use the neon-animated-pages to go from one singular question to another.
-- index.html --
<iron-pages attr-for-selected="data-route" selected="{{route}}">
<section data-route="home">
<test-survey surveyid="99999999-9999-9999-9999-999999999999" submissionid='00000000-0000-0000-0000-000000000000'}' ></test-survey>
</section>
<section data-route="users">
<paper-material elevation="1">
</paper-material>
</section>
<section data-route="user-info">
<paper-material elevation="1">
</paper-material>
</section>
<section data-route="contact">
<paper-material elevation="1">
</paper-material>
</section>
</iron-pages>
--test-survey.html--
<div class="vertical layout">
<div class="flex">
<neon-animated-pages id="views" class="flex" selected="0" entry-animation="slide-from-right-animation" exit-animation="slide-left-animation">
<test-template items="{{survey.Questions}}" id="surveyquestions">
</test-template>
</neon-animated-pages>
<paper-toast
id="toast"
text="Saved successfully.">
</paper-toast>
</div>
</div>
Since needing to be able to group questions together, we moved the following code to another file, stand alone so it can be called from a place where single questions are asked. Or from a place where it will take a list of questions as a group and show them within one section.
--test-template.html--
<template>
<template is="dom-repeat" id="surveyquestions" items="{{items}}" sort="_sort">
<template is="dom-if" if="{{isFormat(item.Type, 'Single-Select')}}" >
<question-singleselect question="{{item}}"></question-singleselect>
</template>
<template is="dom-if" if="{{isFormat(item.Type,'Open-Ended')}}">
<question-openended question="{{item}}"></question-openended>
</template>
<template is="dom-if" if="[[isFormat(item.Type,'Multi-Select')]]">
<question-multiselect question="{{item}}"></question-multiselect>
</template>
<template is="dom-if" if="[[isFormat(item.Type,'Section')]]">
<question-section question="{{item}}"></question-section>
</template>
<template is="dom-if" if="{{isFormat(item.Type,'Numerical')}}">
<question-numerical question="{{item}}"></question-numerical>
</template>
</template>
</template>
--test-chrome.html--
<template>
<paper-card heading="{{question.Title}}" id="paper-card-{{question.Id}}">
<div class="card-content {{question.Type}}">
<div class="questionanswers">
<content select=".questionanswers"></content>
</div>
</div>
<div class="card-actions">
<paper-button class="raised primary" on-tap="prevAction" id="prevButton_{{question.Id}}" hidden$="{{_hidePrev(question.Type)}}">Previous</paper-button>
<paper-button class="raised primary" on-tap="nextAction" id="nextButton_{{question.Id}}" hidden$="{{_hideNext(question.Type)}}">Next</paper-button>
<paper-button class="raised primary" on-tap="saveAction" id="saveButton_{{question.Id}}" hidden$="{{_hideSave(question.Type)}}">Submit</paper-button>
</div>
</paper-card>
</template>
Once I put the list of question-types into a separate form, it stopped working. It listed all the questions on one page, instead of navigating from one question to the next. It works if the section of test-template.html is back in the test-survey.html

Use JSON to create polymer core-menu/core-submenu

I am running into some problems when using JSON to create a polymer menu.
I have a JSON structure, somewhat like [{"name":foo, "children": [{"name":"bar"}]}, {"name": "arr", "children": []]
I would like to render this as: <core-menu><core-submenu label="foo"><core-item label="bar"></core-submenu><core-item label="arr"></core-menu>
I have attempted to do this with code that looks somewhat like:
<polymer-element name="x-menu-item" attributes="node">
<template>
<template if="{{ node.children.length == 0 }}">
<core-item label="{{ node.name }}" link_path="{{ node.link_path }}">
</core-item>
</template>
<template if="{{ node.children.length > 0 }}">
<core-submenu icon="expand-more" label="{{ node.name }}" valueattr="link_path">
<template repeat="{{ child_node in node.children }}">
<x-menu-item node="{{ child_node }}"></x-menu-item>
</template>
</core-submenu>
</template>
</template>
<script>
Polymer('x-menu-item', {
});
</script>
</polymer-element>
<polymer-element name="x-menu" attributes="nodes">
<template>
<core-menu>
<template repeat="{{child_node in nodes}}">
<x-menu-item node="{{child_node}}"></x-menu-item>
</template>
</core-menu>
</template>
<script>
Polymer('x-menu', {});
</script>
</polymer-element>
But this doesn't work for me at all: the problem seems to be that it is setting the 'core-selected' class on the x-submenu and not on the core-item or core-submenu tags that it contains.
How do I either: define this using nothing but raw core-menu/core-submenu/core-item tags (mutate innerHTML? appendChild?) or propagate the classes and clicks properly so I can expand my menu?
The answer turns out to be to use <template id/ref> to recurse inside <x-menu> without using <x-menu-item>.
Complete example:
<polymer-element name="x-menu" attributes="nodes">
<template>
<core-menu>
<template id="submenu" repeat="{{node in nodes}}">
<template if="{{ node.children.length == 0 }}">
<core-item label="{{ node.name }}" link_path="{{ node.link_path }}">
</core-item>
</template>
<template if="{{ node.children.length > 0 }}">
<core-submenu icon="expand-more" label="{{ node.name }}" valueattr="link_path">
<template ref="submenu" repeat="{{node in nodes}}></template>
</core-submenu>
</template>
</template>
</core-menu>
</template>
<script>
Polymer('x-menu', {
created: function() {
this.nodes = [];
}
});
</script>
</polymer-element>
This neatly sidesteps all the problems I was having in the original, as <core-submenu> and <core-item> are a direct child of <core-menu> here.

Categories

Resources