Vue default value dynamic select options - vue.js

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.

Related

Vue select tag on change not firing when selecting the same option

I have a select tag that should trigger function when an option is selected.
<select id="selector" class="form-control" #change="executeAction" v-model="selectedAction">
<option value="" selected disabled>Select action</option>
<option value="view">View Details</option>
<option value="edit">Edit</option>
<option value="delete">Delete</option>
</select>
methods: {
executeAction() {
console.log('action is se', this.selectedAction);
},
}
Now, what I expected was:
When selecting the same option for the second time (For example: View Details), it should log the selected option.
What I got:
It's not firing at all, I need to select other option so that I can reselect the View Details again.
What I tried:
Using watch, and the result was the same.
Using #input instead of #change, still result was same.
Usin v-on: instead of #, still no luck.
Is this a bug? or wrong implementation?
Anyways, would be great to have an answer to this.

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

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.

Set the value for <select> without using 'v-model'

I would like to have something like the following Vue template, but it does not work with the property selectedVal. What is the correct property name?
<select :selectedVal="myList" multiple>
<option value="abc">ABC</option>
</select>
For <input> the prop to bind is value, but for <select> it does not seem to be documented anywhere. I am looking for the name of the correct prop to bind.
I answered because it's difficult to quote code snippet in a comment.
I think you asked this question after looking into the document here, which showed an elegant way to define selected items.
<select v-model="selected">
<option v-for="option in options" v-bind:value="option.value">
{{ option.text }}
</option>
</select>
Actually, I doubt if there's a v-bind prop performs like this because value is an attribute of input and option, but selected is not an attribute of select but an attribute of option and I can't find any alternatives in select.
Also, after browsing the source code of Vue.js, I didn't see vue did much for binding an attribute (code here and here) rather than pushing values of v-bind into the element's attrs list.
export function addAttr (el: ASTElement, name: string, value: string) {
(el.attrs || (el.attrs = [])).push({ name, value })
}
On the other hand, select seems to be an special case in v-model (see code here).
So, I provided the solution in the comment by binding selected to option instead of select.

#Html.DropDownListFor - How to set different color for a single item in list?

I wish to have one item in my DDL to be a different color (red). However the list comes from a table and is not hard coded in the page like
<option value="Option 1">Option 1</option>
but rather as
#Html.DropDownListFor(r => r.Journal.Frequency, Model.JournalFrequencyList, "Select a Frequency", new { #class = "form-control" })
Is there a way to make just one item a different color?
You can update your styles/css to make one item red color. Now you did not specify which specific item you want. With jQuery, you can select a specific option and set the color of that to red.
Assume your razor view renders a SELECT element like this
<SELECT id="fancySelect">
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</SELECT>
And if you want to set the color of the option which has value attribute set to "2", you can use the below code
$(function(){
$("#fancySelect option[value='2']").css('color','red');
//you can also apply a css class if needed
});
If you want to update a different option, update your jQuery selector to get that.
EDIT : As per the comment
is there any way to use the text as opposed to the value? Example
change if text is "Deleted"
You can update your jQuery selector to get the option with a specific text.
$("#fancySelect").find("option:contains('Deleted')").css('color','red');
I suggest you rely on option value than the text, you can set the value as a code which you can program against.

Using .change() to addClass with select list

I'm trying to make a hidden field show by adding a class when the "other" option is selected from a pull-down list. But I'm not quite sure the correct way to do it.
I have the input hidden and when option is chosen I want to add the class "view" which adds display block making the hidden field visible.
Here is a fiddle showing what I have so far, any help would be much appreciated: http://jsfiddle.net/maikunari/NX795/
$(document).ready(function(){
$("#select-box").change(function(){
if($(this).val() == "other"){
$("#text-field").show();
} else {
$("#text-field").hide();
}
});
});
<select id="select-box">
<option value="Email Newsletter">Email Newsletter</option>
<option value="Yellow Pages ">Yellow Pages </option>
<option id="other-select" value="other">Other</option>
</select>