Vue JS - Change 2 buttons to a select drop down - vue.js

I have 2 buttons which sorts my array a -z or relevance. They work well. I would like the options to be in a drop-down rather than 2 buttons. How can I achieve this?
This is what I have just now:
<button #click="sortalphabetically">Alphabetically
<button #click="sortbyrelevance">Relevance
methods: {
sortalphabetically() {
this.theResults = [...this.results].sort((a, b) =>
a.title > b.title ? 1 : -1
);
},
sortbyrelevance() {
this.theResults = [...this.results];
},}
I would like a select drop-down instead of the buttons.
<select
class="col-4 col-lg-5"
v-model="sortatoz"
#change="sortIems"
id="sortby"
aria-label="sortby"
>
<option disabled value="" selected>Select</option>
<option value="alphabetically">Alphabetically</option>
<option value="relevance">Relevance</option>
</select>

You need to add a v-model directive to your select
You can then sort depending on the value of the v-model
new Vue({
el: '#app',
data: () => ({
optionSelected: "asc"
}),
methods: {
sort(){
switch (this.optionSelected){
case 'desc':
console.log('here sort desc')
break;
case 'asc':
console.log('here sort asc')
break
}
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.11/vue.js"></script>
<div id="app">
<select v-model="optionSelected" #change='sort'>
<option value="asc">Sort asc</option>
<option value="desc">sort desc</option>
</select>
</div>

Related

Vue JS sort and then return to previous state

I have a set of results in my Vue app. I want to be able to sort them alphabetically after I have searched. I then want them to return to the state before I clicked 'alphabetically' also. In my case its relevancy.
Relevancy is how it loads and before I choose 'Alphabetically'
The alphabetical option works fine but when I change it back to 'relevancy' it doesnt do anything and I dont understand why. To me it should just be 'return this.results();'
Can anyone help please?
<select
class="form-control col-4 col-lg-5"
v-model="sortatoz"
#change="sortItems"
id="sortby"
aria-label="sortby"
>
<option disabled value="" selected>Select</option>
<option value="alphabetically">Alphabetically</option>
<option value="relevance">Relevance</option>
</select>
//sort drop down
sortItems() {
if (this.sortatoz === "alphabetically") {
return this.results.sort((a, b) =>
a.title > b.title ? 1 : -1
);
} else {
return this.results();
}
},
So first of all, you copy your original set into a data variable you going to show inside your HTML.
So whenever you sort, you use this copied variable to sort.
But whenever you want relevance again, you just copy the original again in the copied variable.
new Vue({
el: '#app',
data: {
list: ['A', 'C', 'B'],
copiedList: []
},
mounted () {
this.unsort()
},
methods: {
sort() {
this.copiedList = [...this.list].sort((a, b) =>
a > b ? 1 : -1
);
},
unsort() {
this.copiedList = [...this.list]
}
}
})
<div id="app">
<button #click="sort">Sort</button>
<button #click="unsort">Unsort</button>
<div v-for="element in copiedList">
<div> {{ element }} </div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

How to get Please select to show in a dropdown box in vue

I have this form that has a dropdown box. Everything works fine except if you have "Please Select" selected it saves the value of it which is 0 to the database and because of that when I go to the page that displays the product, the page breaks because it can't find the category.
Here is my code
<template>
<div>
<select class="form-select form-control" v-model="newCategory">
<option value="0" selected>Please Select</option
<option v-for=category in categories" :value=category.id>
{{ category.name }}
</option>
</select>
<button class="btn btn-success" #click="save">Save</button>
</div>
</template>
<script>
export default {
props: ['categories'],
data() {
return {
newCategory: 0
}
},
methods: {
save(){
axios.post('/api/products/create', {
category: this.newCategory
}).then(response => {
this.newCategory = 0;
});
}
}
}
</script>
Just check this.newCategory before you send a request to the server. If it is 0, show a toast or something.
The code should be like this:
save(){
if(this.newCategory === 0) show something and return;
// bottom codes will be shown only in else section
axios.post('/api/products/create', {
category: this.newCategory
}).then(response => {
this.newCategory = 0;
});
}
First you need to make your newCategory field accept null values, because you need to populate it even if you are saving data without selecting option. Then try the following:
<select v-model="newCategory">
<option value="" disabled selected>Select your option</option>
<option v-for=category in categories" :value=category.id>
{{ category.name }}
</option>
</select>
data() {
return {
newCategory: null
}
},

Get each HTML element in a Vue slot from JavaScript

I am creating a custom select component in VueJS 2. The component is to be used as below by the end-user.
<custom-select>
<option value="value 1">Option 1</option>
<option value="value 2">Option 2</option>
<option value="value 3">Option 3</option>
...
<custom-select>
I know the Vue <slot> tag and usage. But how do I get the user provided <option> tags as an array/list so I can get its value and text separately for custom rendering inside the component?
Those <option>s would be found in the default slot array (this.$slots.default), and you could get to the inner text and value of the <option>s like this:
export default {
mounted() {
const options = this.$slots.default.filter(node => node.tag === 'option')
for (const opt of options) {
const innerText = opt.children.map(c => c.text).join()
const value = opt.data.attrs.value
console.log({ innerText, value })
}
}
}
demo
You can achieve it, using v-bind and computed property
new Vue({
el: '#vue',
data: {
selected: '',
values: [
{
code: '1',
name: 'one'
},
{
code: '2',
name: 'two'
}
]
},
computed: {
selectedValue() {
var self = this;
var name = "";
this.values.filter(function(value) {
if(value.code == self.selected) {
name = value.name
return;
}
})
return name;
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="vue">
<div>
<select v-model="selected">
<option v-for="value in values" v-bind:value="value.code">
{{ value.name }}
</option>
</select>
</div>
<strong>{{ selected }} {{ selectedValue }}</strong>
</div>

How to update Vuejs2 page content when changing select option on api rxjs observable api endpoint?

I'm a bit new at Vuejs2 and rxjs. So please be kind ^_^. I have an Observable api endpoint. I want to change the param value "food_type" via a select drop down on the same page. I want it so that when I select an item via the drop down the param value is updated, changing the end point and the data on the page gets reloaded. How can I achieve this?
here is my select drop down….
<div class="col-sm-2 divTableHead hand">
<select name="food_type" id="food_type" class="form-control" v-model="food_type">
<option value="" selected>Feeding</option>
<option value=“A”>One</option>
<option value=“AB”>Two Bee</option>
<option value=“BB”>Bee Bee</option>
<option value=“CB”>Cee Bee</option>
<option value=“CC”>Cee Cee</option>
</select>
</div>
here is what my Observable looks like…
data() {
return {
thisCat: [],
food_type: ''
}
},
subscriptions() {
return {
thisCat: Observable.from(axios.get(`${process.env.KITTY_URL}/api/v1/feedings/?cat__slug&cat__name=${this.$route.params.catName}&food_type=${""}`)
.catch(error => console.log(error)))
.pluck("data","results")
}
},
Thank you -_^
Seems like what you're looking for is a Watcher.
This is most useful when you want to perform asynchronous or expensive
operations in response to changing data.
That's exactly the case!
Check out the example below I prepared for you using the JSONPlaceholder API.
var app = new Vue({
el: '#app',
data: {
postID: '',
loading: false,
postContent: null,
},
watch: {
postID: function () {
this.fetchPost()
}
},
methods: {
fetchPost: function(id) {
this.loading = true;
fetch('https://jsonplaceholder.typicode.com/posts/'+this.postID)
.then(response => response.json())
.then(json => {
this.postContent = {
title: json.title,
body: json.body
}
this.loading = false;
})
},
}
});
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
<select v-model="postID">
<option value="" disabled>Select a post</option>
<option value="1">Post #1</option>
<option value="2">Post #2</option>
<option value="3">Post #3</option>
<option value="4">Post #4</option>
<option value="5">Post #5</option>
</select>
<h2 v-if="loading">Loading...</h2>
<div v-if="postContent" class="post_content">
<h3>{{postContent.title}}</h3>
<p>{{postContent.body}}</p>
</div>
</div>
As you can see, the watcher watches for any changes of that property and perform whatever you told it to do. In this case, call the fetchPost method and perform a fetch.

Dynamically create select options on the fly

I have 2 selects, one with data and other one empty. When first one is selected, I catch it using a switch. Now, depending on the value, I want to create option elements and put them inside empty select.
Let's say I have an array of values
var values = ['Hello', 'world', 'etc']
When selected
selected(event) {
var name;
switch (event.target.value) {
case 'roth':
// append values as options into select, using foreach
// such as:
// <option value="hello">Hello</option>
...
}
}
This is select in my template:
<select class="form-control" :id="selection">
<option selected="" disabled="" value="0"></option>
</select>
You can just define an empty array for options for second select, and push values with your switch/case. Later you can use that values with v-for
For example:
new Vue({
el: '#app',
data: {
selectValues: ['Hello', 'world', 'etc'],
secondarySelectValues: [],
},
methods: {
handleChange: function(e) {
switch (e.target.value) {
case 'Hello':
this.secondarySelectValues = [];
this.secondarySelectValues.push('this', 'is', 'hello');
break;
case 'world':
this.secondarySelectValues = [];
this.secondarySelectValues.push('this', 'is', 'world')
break;
case 'etc':
this.secondarySelectValues = [];
this.secondarySelectValues.push('this', 'is', 'etc')
break;
}
}
}
})
<script src="https://unpkg.com/vue#2.4.2"></script>
<div id="app">
<select class="form-control" #change="handleChange">
<option v-for="selectValue in selectValues" :value="selectValue">{{ selectValue }}</option>
</select>
<select class="form-control secondary">
<option v-for="secondarySelectValue in secondarySelectValues" :value="secondarySelectValue">{{ secondarySelectValue }}</option>
</select>
</div>