Vue multiselect not getting id and name - laravel

I have used vue multiselect in my form and I have made the options dynamic as autocomplete by axios post . I am returning only id and name from the controller to js file but it is displaying all the properties of option
This is My form
<multiselect v-model="form.books" :options="options" :loading="isLoading" :internal-search="false" #search-change="getData" :multiple="true" :close-on-select="false" :hide-selected="true" :limit="5" :internal-search="false"></multiselect>
This is my vue js file
Vue.component('coupon-form', {
mixins: [AppForm],
data: function() {
return {
form: {
name: '' ,
description: '' ,
valid_from: '' ,
valid_till: '' ,
discount: '' ,
enabled: false,
books:[],
},
isLoading: false,
options: [],
}
},
methods: {
getData(query){
this.isLoading = true;
axios.post('/admin/books/find/'+query)
.then((response) => {
console.log(response);
this.options = response.data;
this.isLoading = false;
})
.catch((error) => {
this.isLoading = false;
});
}
}
});
This is my controller
public function find($books)
{
$search = $books;
$books = Book::select('id','name')
->where('id','like',"%$search%")
->orWhere('name','like',"%$search%")
->orWhere('sku','like',"%$search%")
->orWhere('sale_price','like',"%$search$")
->limit(5)->get();
return $books;
}
}
As we can see I am selecting the id and name of the Book Model but I am getting many properties of Book like this
And I want to show the name in the options and in the v-model I want to have id
How to do that

You need new field in your data and watcher for value so try something like this:
<multiselect v-model="selected"...></multiselect>
data () {
selected: []
...
},
watch: {
selected (newValues) {
this.form.books = newValues.map(obj => obj.id)
}
}
I think that is what you need.
I found a lot of issues about that and package doesn't have prop for that.
You can read more on there: link1, link2
Good luck!

DB::table('books')->select('id,name')->where('id','like',"%$search%")
->orWhere('name','like',"%$search%")
->orWhere('sku','like',"%$search%")
->orWhere('sale_price','like',"%$search$")
->limit(5)->get();

<template>
<div>
<multiselect v-model="yourForm.bindThis" :options="options" :custom-label="showItems" placeholder="Select one" :label="options.name_of_a_column_from_record" :track-by="options.id_of_record" :multiple="true"></multiselect>
</div>
</template>
<script>
import Multiselect from 'vue-multiselect';
data(){
return{
options: [],
yourForm: {
bindThis: '',
}
}
},
methods:{
showItems({data}){
return `${data.name_of_a_column_from_record}`;
}
}
</script>
Let me know if it did the magic

Add track-by and label props.
<multiselect
v-model="form.users"
:options="scholars"
:multiple="true"
:searchable="true"
label="name"
track-by="id"
>
</multiselect>

Related

TypeError: _this2.categoryOptions.find is not a function

I'm trying to create a select option that will show the category when it's been saved. The problem I'm having is that I'm getting this error in my console
[Vue warn]: Error in render: "TypeError: _this2.categoryOptions.find is not a function"
Here is my code
<template>
<div>
<select class="form-control" v-model="addCategory" name="category">
<option v-for="category in categoryOptions" :value="category.id">{{ category.name }}</option>
</select>
</div>
</template>
<script>
export default {
props: ['product', 'categories'],
data() {
return {
addCategory: null,
categoryOptions: []
}
},
mounted() {
axios.get('/admin/products/'+this.product.id+'/category').then((response) => {
this.categoryOptions = response.data;
});
},
computed: {
categoryOptions(){
let options = [];
options.push({id:0, text: "Please select one"});
let filteredCategory = this.categories.filter(category => {
return this.categoryOptions.find(selected => categoryOptions.category_id === category.id) == null;
});
filteredCategory.forEach(sc => {
options.push({id: sc.id, text: sc.name});
});
return options;
}
},
}
</script>
Replace:
let filteredCategory = this.categories.filter(category => {
return this.categoryOptions.find(selected => categoryOptions.category_id === category.id) == null;
});
per
let filteredCategory = this.categories.filter(category => {
return this.categoryOptions.find(selected => selected.category_id === category.id) == null;
});
note that you just forgot to replace categoryOptions with selected. But to ensure that the component is loaded, I advise you to make the props categories required, and ensure that it is persisted for the component before rendering.
<script>
export default {
props: {
'product',
'categories': {
type: [Array, Object],
required: true,
},
},
...
}
</script>
Another tip if you use the chrome browser, is to use a very cool extension which is Vue.js devtools to follow the status of your application.

Auto fill input field after Select dropdown list [ Laravel, Vuejs ]

I want to create something that search in Product table and i select in dropdown its will display data in order table like pic below?
how can i archieve that? Anyone give me any hint?
thanks in advances...
In my Vuetify
i used vue-select package
<v-col md="6" cols="12">
<label class="font-weight-bold">Select Product</label>
<v-select v-model="search" label="name" :options="purchases"></v-select>
</v-col>
In my script file
<script>
export default {
created() {
this.fetchData()
},
data() {
return {
form: {},
search: '',
items: [],
purchase_status: ['Received', 'Partial', 'Pending', 'Ordered'],
}
},
methods: {
fetchData() {
this.$axios.$get(`api/product`)
.then(res => {
this.items = res.data;
console.log(this.items)
})
.catch(err => {
console.log(err)
})
},
uploadFile(event) {
const url = 'http://127.0.0.1:3000/product/add_adjustment';
let data = new FormData();
data.append('file', event.target.files[0]);
let config = {
header: {
'content-Type' : 'image/*, application/pdf'
}
}
this.$axios.$post(url,data,config)
.then(res => {
console.log(res);
})
}
}
}
</script>
When you select a product in the dropdown, you'll get product_id. Use this product_id and call API to get data for the orders table.

Pagination in Vuex Store

I have cloned this awesome shopping cart repo from https://github.com/vueschool/learn-vuex, and i get data like this:
ProductList.vue
<template>
<div>
<ul>
<li v-for="product in products">
- {{product.name}} - {{product.price}}
</li>
</ul>
</div>
</template>
<script>
methods: {
...mapActions({
fetchProducts: 'products/fetchProducts'
})
}
</script>
export default new Vuex.Store({
state: {
products: {},
},
actions: {
fetchProducts({commit},data) {
axios.get(`api/product`).then((response) => {
commit('updateProducts', response.data);
})
},
mutations: {
updateProducts (state, products) {
state.products = products
}
}
});
I'm trying to paginate results and need help in that direction, do i need to create a pagination state or new module in the vuex store, thanks in advance.
Try following
I use one of the RenderlessLaravelVuePagination component for pagination.
<pagination :data="products" #pagination-change-page="getProducts"></pagination>
and remaining code is below
export default {
name: 'ProductList',
mounted() {
this.getProducts();
},
methods: {
getProducts(page = 1){
this.$store.dispatch('getProducts',{
page: page
});
},
}
Hope this works for you.
You need to define meta object in order to store the meta data returning from your axio post. Then, you can use that meta object in your vue.
Do something like this:
export default new Vuex.Store({
state: {
products: {},
productsMeta: {}
},
actions: {
getProducts({commit},data) {
axios.get(`api/product`).then(response => {
this.productsMeta = response.meta;
}).commit('updateProducts', response.data);
})
},
mutations: {
updateProducts (state, products) {
state.products = products
}
}
});

Display passed image in template, in VUE

So I have this code:
<template>
<div id="search-wrapper">
<div>
<input
id="search_input"
ref="autocomplete"
placeholder="Search"
class="search-location"
onfocus="value = ''"
#keyup.enter.native="displayPic"
>
</div>
</div>
</template>
<script>
import VueGoogleAutocomplete from "vue-google-autocomplete";
export default {
data: function() {
return {
search_input: {},
pic: {}
};
},
mounted() {
this.autocomplete = new google.maps.places.Autocomplete(
this.$refs.autocomplete
);
this.autocomplete.addListener("place_changed", () => {
let place = this.autocomplete.getPlace();
if (place.photos) {
place.photos.forEach(photo => {
let pic=place.photos[0].getUrl()
console.log(pic);
});
}
});
},
methods: {
displayPic(ref){
this.autocomplete = new google.maps.places.Autocomplete(
this.$refs.autocomplete);
this.autocomplete.addListener("place_changed", () => {
let place = this.autocomplete.getPlace();
if (place.photos) {
place.photos.forEach(photo => {
let pic=place.photos[0].getUrl()
console.log(pic);
});
}
})
},
}
}
I want to pass the "pic" parameter, resulted in displayPic, which is a function, into my template, after one of the locations is being selected.
I've tried several approaches, but I'm very new to Vue so it's a little bit tricky, at least until I'll understand how the components go.
Right now, the event is on enter, but I would like it to be triggered when a place is selected.
Any ideas how can I do that?
Right now, the most important thing is getting the pic value into my template.
<template>
<div id="search-wrapper">
<div>
<input style="width:500px;"
id="search_input"
ref="autocomplete"
placeholder="Search"
class="search-location"
onfocus="value = ''"
v-on:keyup.enter="displayPic"
#onclick="displayPic"
>
<img style="width:500px;;margin:5%;" :src="pic" >
</div>
</div>
</template>
<script>
import VueGoogleAutocomplete from "vue-google-autocomplete";
export default {
data: function() {
return {
search_input: {},
pic:""
};
},
mounted() {
this.autocomplete = new google.maps.places.Autocomplete(
this.$refs.autocomplete,
{componentRestrictions: {country: "us"}}
);
},
methods: {
displayPic: function(){
this.autocomplete.addListener("place_changed", () => {
let place = this.autocomplete.getPlace();
if (place.photos) {
place.photos.forEach(photo => {
this.pic=place.photos[0].getUrl()
});
}
})
},
}
}
</script>

vue-multiselect with both tagging and async, stops working

I'm using vue-multiselect and I would like the user to be able to search tags in the database using async and if they don't find what they want, enter their own tag. This means I'm using tagging and async. It works as expected until I add a tag not found in the , then the aysnc no longer searches. If I remove the added tag, then it does the async search again..
<template>
<div>
<label class="typo__label" for="ajax">Async multiselect</label>
<multiselect v-model="selectedTags" id="tags" label="name" track-by="code" placeholder="Type to search" open-direction="bottom" :options="tags" :taggable="true" #tag="addTag" :multiple="true" :searchable="true" :loading="isLoading" :internal-search="false" :clear-on-select="true" :close-on-select="false" :options-limit="300" :limit="3" :limit-text="limitText" :max-height="600" :show-no-results="false" :hide-selected="true" #search-change="asyncFind">
<template slot="clear" slot-scope="props">
<div class="multiselect__clear" v-if="selectedTags.length" #mousedown.prevent.stop="clearAll(props.search)"></div>
</template><span slot="noResult">Oops! No elements found. Consider changing the search query.</span>
</multiselect>
<pre class="language-json"><code>{{ selectedTags }}</code></pre>
</div>
</template>
<script>
import axios from 'axios';
import Multiselect from 'vue-multiselect'
export default {
components: {
Multiselect
},
props: {
userId: {
type: Number,
required: true
},
tagGroup: {
type: String,
required: true
}
},
data () {
return {
selectedTags: [],
tags: [],
isLoading: false
}
},
methods: {
addTag (newTag) {
const tag = {
name: newTag
}
this.tags.push(tag)
this.selectedTags.push(tag)
},
limitText (count) {
return `and ${count} other tags`
},
asyncFind (query) {
if( query.length > 3 ) {
this.isLoading = true
axios.get('/api/tags/'+this.tagGroup+'/'+query).then(response => {
this.tags = response.data.results.map(a => {
return { name: a.name.en };
});
})
}
},
clearAll () {
this.selectedTags = []
}
}
}
</script>
I'm using the component twice within another component:
<user-tags v-bind:tagGroup="'industry'" :typeahead-activation-threshold="2" :userId="user.id" :isSearchable="true"></user-tags>
<user-tags v-bind:tagGroup="'expertise'" :typeahead-activation-threshold="2" :userId="user.id" :isSearchable="true"></user-tags>

Resources