How to get multiple v-for values inside a b-form-select in VUEJS - vuejs2

I am trying to get values for the b-form-select from an array inside the array but not able to get it.
I have a code like this:
<span v-for="(user, index) in Users" :key="index">
<span v-for="(userName, index) in user.details" :key="index"> {{userName.name}}</span>
</span>
I am getting the user name here, but I want to display it inside an b-form-select.
I have a code for the b-form-select but it is not helping.
<b-form-select
v-model="user_name"
>
<option
:value="userName.id"
v-for="userName in Users.details"
:key="userName.id"
>{{ userName.name }}
</option
>
</b-form-select>
ANy solution to it?

Your code on top is iterating over user.details from a Users array while the second code block is iterating over Users.details. Do you spot the difference? If you want to iterate over all details you'd need to collect them from Users first. For example,
const details = Users.map(user => user.details)
Or else grab the user you want from Users and iterate over user.details the same way as you do in the spans.

Related

Vue Material Checkbox Checked

I have tried / guessed at every combination of v-bind/v-model/:checked/:value I can think of, but I can't get these damn checkboxes checked on load:
Using Vue Material / Vue3:
<div v-if="items.length">
<div
v-for="(value,key,index) in this.items"
:key="index"
:ref="'icon'+items[key].id">
<md-checkbox
:id="'TDS'+key"
v-model="items[key].complete"
true-value="1"
#change="doDo(items[key].id)"
class="md-primary m-0"
>
{{ items[key].item }} {{items[key].complete}}
</md-checkbox>
</div>
</div>
The bit I can't figure out is how to make the checkbox checked if items[key].complete=1 when data is loaded.
You are already inside the loop
v-model="value.complete"
Same goes for all other bindings.
And your data should not be accessed with this in your template
v-for="(value,key,index) in items"
This one should already work, if you receive your data properly, it may update itself due to reactivity. Maybe try v-model="!!items[key].complete" just to be sure that your value is coerced to a Boolean.

Vue default value dynamic select options

I've tried my best to keep the following code as concise as possible.
The goal of this code: get tickets (products) via an api (data.json in this example) and display them in a table for users to buy.
The part I'm struggling with? Each product has a number which represents the maximum amount that can be bought per user. I'm showing these values dynamically in options, which works. To give you a better understanding, here is the code:
https://codesandbox.io/s/headless-currying-gocrw?fontsize=14&hidenavigation=1&theme=dark
Everything works as expected and wanted, but what truly would be great is to add a leading zero to the option numbers. Now when a user selects some tickets and changes his mind he won't be able to do so.
EDIT:
If you look at the code via URL above, it is indeed now fixed (thanks to the +1 solution and using the index as my values). Now I'd like to have 0 selected as the default value. I'm not really sure on how to achieve this.
The for-loop looks like this:
<select v-model="selectedTickets[product.id]">
<option v-for="(maximum, n) in Number(product.product_meta.maximum) + 1" :value="n" :key="n">
{{ n }}
</option>
</select>
Data function looks like this:
data() {
return {
selectedTickets: {},
products: null
};
}
You should add:
<option value="0"> 0 </option>
Before your v-for loop on options, so it would look like this:
<select v-model="selectedTickets[product.id]">
<option value="0"> 0 </option>
<option
v-for="(maximum, n) in Number(product.product_meta.maximum)"
:value="maximum"
:key="n"
>
{{ maximum }}
</option>
</select>
Now, that first option would be the default one, and user would be able to go back anytime.
One other thing that you can do is just to add +1 to product.product_meta.maximum and use n for :value instead of maximum.
The best option, though, would be to create one method called getSelectableOptions(product) that will return the array of selectable options for given product, for example [0, 1, 2, 3, 4, 5] and then you can loop through it, that way your code will be cleaner.
Hope this helps!
You can add a clear button at the bottom to reset all the selection
<button #click="selectedTickets={}">Reset</button>
It is also possible to implement individual clear buttons for each select input like the following:
<select v-model="selectedTickets[product.id]">
<option
v-for="(maximum, n) in Number(product.product_meta.maximum)"
:value="maximum"
:key="n"
>
{{ maximum }}
</option>
</select>
<button
#click="resetSelection(product.id)"
v-if="product.id in selectedTickets"
>
Clear
</button>
Then create a method in the methods section
resetSelection: function(productId) {
delete this.selectedTickets[productId];
}
This will clear individual selects.

How to render the value of v-for based on the condition(v-if) provided in vue.js

I'm trying to implement the condition provided in the code. My last attempt was like in the one in the code.
<ul class = "details" v-for = "(value, propertyName) in items[this.index]" :key = "value.id">
<li v-if="{{propertyName}} == 'IndustryIdentifiers'">Data not available</li>
<li v-else>{{value}}</li>
</ul>
How can the following be implemented:
v-if="{{propertyName}} == 'IndustryIdentifiers'"
The {{ }} syntax is used to wrap a JavaScript expression that should be output as text. It isn't necessary to use the braces to access data in other contexts. In the case of a v-if the attribute value is already an expression and there's no need to include any special characters to pull in data values.
So it'd be just v-if="propertyName === 'IndustryIdentifiers'":
<ul class="details" v-for="(value, propertyName) in items[this.index]" :key = "value.id">
<li v-if="propertyName === 'IndustryIdentifiers'">Data not available</li>
<li v-else>{{ value }}</li>
</ul>
Here I'm assuming that item[this.index] is an object rather than an array, which is implied by the way you've written your loop.
You could also write it like this:
<ul class="details" v-for="(value, propertyName) in items[this.index]" :key = "value.id">
<li>{{ propertyName === 'IndustryIdentifiers' ? 'Data not available' : value }}</li>
</ul>
You should also be able to remove the this. from the index unless it's also declared locally.
I also wonder whether you're intentionally creating a separate list for each value, with each list only containing a single item. Difficult to know exactly what you're trying to achieve but I would guess that you want the loop inside the <ul> rather than on the <ul>. If you only have a single <li> (as in my second example) then you could move the v-for onto the <li>. If you want to stick to having two <li> elements with v-if/v-else then you'll need to wrap them in a <template> tag to hold the v-for.

Angular2 *ngIf inside *ngFor

In angular 2 I want to loop through an array and show options in drop-down on the basis of some conditions. According to my search I can place a condition in ng-container directive above loop. How can I do that inside loop. (Please note that If I place what inside loop a blank space will be shown instead of option).
Thanks!
<md-autocomplete #package="mdAutocomplete" [displayWith]="displayPackage">
<md-option (onSelectionChange)="packageSelection($event, package) *ngFor="let package of (reactivePackages | async)"" [value]="package">
{{ package.packageName }}
{{package.serviceId}}
{{service.serviceId}}
</md-option>
</md-autocomplete>
You can loop through the array using ng-container and can use ngif on md-options like this:
<md-autocomplete #package="mdAutocomplete" [displayWith]="displayPackage">
<ng-container *ngFor="let package of (reactivePackages | async)">
<md-option (onSelectionChange)="packageSelection($event, package)" [value]="package" *ngIf="your-condition" >
{{ package.packageName }} {{package.serviceId}} {{service.serviceId}}
</md-option>
</ng-container>
</md-autocomplete>
Hope this helps.

How to conditionally display client-side data with Aurelia

Is there a way in Aurelia to say 'If x == this, then show this'?
To be specific, I have an array of data that looks something like this:
[
{objectID: 1, customDataArray: [1,2,3,4], customDataType: { cdt: "Troops" }}
]
This array obviously has multiple rows that look like the one above where it's passing me an array of custom values that I need to reference. Those values could be the IDs of different 'groups' in our system. That's why we are passing in an object the contains what type of custom data it is. e.g. "Troops"
So what's happening is on Activate, I'm fetching all this data from my API and storing it in a variable. Well based on whether the custom data type is "Troops" or something else, I want to show a different input label. For example, if it is "Troops," I want to show a label that says "input troop id's" and so on.
Also, sometimes the customDataType isn't required so it comes in as null. So in that case, I want to show something different. Not sure how to handle this one..
The if custom attribute or the show custom attribute would work. Unfortunately, we don't have a switch or else type of setup.
<label if.bind="p.customDataType.cdt === 'Troops'">Input Troop Ids</label>
<label if.bind="p.customDataType.cdt !== 'Troops'">Something Different</label>
You could try if if.bind could be useful for this, as below:
<ul>
<li repeat.for="obj of data" if.bind="obj.customDataType">
<span>${obj.customDataType.cdt}</span> -
<strong repeat.for="cda of obj.customDataArray">${cda}, </strong>
</li>
<li repeat.for="obj of data" if.bind="!obj.customDataType">
<span>No CustomDataType</span>
<strong repeat.for="cda of obj.customDataArray">${cda}, </strong>
</li>
</ul>
Here is a plunker that shows this in action: https://gist.run/?id=21991c490810a4acf2e38cec99614bbd