Multiselect with Vue and Laravel - laravel

I need to implement a multiselect in the view in which I am working, the idea is to have several options selected in the same select. I have tried some components that I found on the web but without good results.
The route and the driver method in Laravel work well.
I have to feed the Multiselect from a method that brings the data
If you can give me a hand it would be great, I leave the code
<template>
<div>
<div class="col-sm-12">
<select class="form-control form-control-line">
<option v-for="coin in coins" :key="coin.id" value="coin.id">
{{ coin.name }}
</option>
</select>
</div>
</template>
<script>
export default {
data () {
coins: [],
},
created() {
this.getCoins();
},
methods: {
getCoins(){
let urlCoin = '/dashboard/coins';
axios.get(urlCoin)
.then((response) => {
this.coins = response.data;
})
.catch((err) => {
})
}
}
My Method in the CoinController
class CoinController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
public function coinList() {
$coins = Coin::orderBy('rank', 'asc')
->select('id', 'name', 'rank')
->get();
return response()->json($coins);
}
}
the idea is to do this
Multiselect
I used Laravel 5.6 and Vuejs

You can't use basic select tag to show multiple selected value that you get from server.. because it only support to select one option.. if you want to select multiple like your pict, you have to add more library like vue multiselect
<multiselect v-model="value",
:options="coins",
:multiple="true",
:close-on-select="false",
:clear-on-select="false",
:hide-selected="true",
:preserve-search="true",
placeholder="Pick some"
label="name",
track-by="name",
:preselect-first="true" >
<template slot="tag" slot-scope="props">
<span class="custom__tag">
<span>{{ props.option.language }}</span>
<span class="custom__remove"
#click="props.remove(props.option)">
x
</span>
</span>
</template>
</multiselect>
<script>
export default {
data () {
value: [],
coins: [],
},
created() {
this.getCoins();
},
methods: {
getCoins(){
let urlCoin = '/dashboard/coins';
axios.get(urlCoin)
.then((response) => {
this.coins = response.data;
})
.catch((err) => {
})
}
}

Related

How to get option key from a select using Vue.js with Laravel

I am using Vue.js 2 with Laravel 7.
I must do an insert to the db through a form submit but I am unable to get the option key of a select.
This is the select:
<div class="form-group">
<label for="room">Room:</label>
<select v-model="room" class="form-control" id="room">
<option v-for="room in rooms" :key="room.id">
{{ room.name }}
</option>
</select>
</div>
This is the script:
export default {
props: ['hours'],
mounted() {
console.log('Component mounted.');
this.loadUsers();
this.loadRooms();
},
data: function() {
return {
users: [],
rooms: [],
room: ''
}
},
methods: {
onCreate: function (args) {
let value = this.$refs.textareaObj.value;
alert(value);
},
loadUsers: function() {
axios.get('api/users')
.then((response) => {
this.users = response.data.data;
})
.catch(function(error) {
alert('noviva');
console.log(error);
});
},
loadRooms: function() {
axios.get('api/rooms')
.then((response) => {
this.rooms = response.data.data;
})
.catch(function(error) {
alert('noviva');
console.log(error);
});
},
insertMeeting: function() {
alert(this.room);
}
}
}
In the insert, I need to get the id of the room but I don't know how to do that. The function insertMeeting should alert that id. By the way, in that alert appears only the option value (room.name) but I am interested in the option key (room.id).
Can help?
Bind the option's value to its room's id, which will be stored in the room property bound to its parent, select, via v-modal:
<select v-model="room" class="form-control" id="room">
<option v-for="room in rooms" :value="room.id" :key="room.id">
{{ room.name }}
</option>
</select>
Demo here

How can I populate data which is fetched from API into select option in Laravel using VueJS and axios?

I have tried every way to fetch my API data into a select list. However, I have failed. All the information comes successfully. But whenever I try to show them it doesn't work. Is there any problem in my code?
My routes/web.php file
<?php
Route::get('/','StatusController#index');
My Controller
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class StatusController extends Controller
{
//
public function index(){
return view('status-main');
}
}
My VueJS file
<template>
<div class="container">
<h2>Total Recovered: {{Recovered}}</h2>
<select name="" id="" >
<option value="">Choose</option>
<option v-for="(list,index) in countryList" :key="list.id" :index="index">
{{list}}
</option>
</select>
</div>
</template>
<script>
import axios from 'axios'
export default {
name:'CoronaStatus',
data: function () {
return {
Recovered: "Loading ...",
countryList:[],
// Country:''
}
},
// mounted(){
//
// this.globalStatus();
// },
methods:{
globalStatus:function () {
const options = {
headers: {"x-rapidapi-host": "covid-193.p.rapidapi.com",
"x-rapidapi-key": "ad21211fe4mshba485cda44108adp1712e0jsn54ed45914a9a"}
};
axios
.get("https://covid-193.p.rapidapi.com/countries", options)
.then(response=>response.json())
.then(response => {
// this.Recovered = response.data.Global.TotalRecovered;
this.countryList=response.data;
console.log(this.countryList);
// alert(this.countryList)
})
.catch(err => console.log(err));
}
},
mounted(){
this.globalStatus();
},
}
</script>
<style scoped>
</style>
I have successfully fetched data every time. However, I have managed to fail to populate the select list.
My VueJS file after updating:
<template>
<div class="container">
<select name="country">
<option disabled value="">Choose</option>
<option v-for="country in countryList" :key="country" :value="country">
{{ country }}
</option>
</select>
</div>
</template>
<script>
import axios from 'axios'
export default {
data: () => ({
Recovered: "Loading ...",
countryList: []
}),
methods: {
globalStatus () {
const options = {
headers: {
"x-rapidapi-host": "covid-193.p.rapidapi.com",
"x-rapidapi-key": "ad21211fe4mshba485cda44108adp1712e0jsn54ed45914a9a"
}
}
axios.get('https://covid-193.p.rapidapi.com/countries', options).then(res => {
this.countryList = res.data.response
console.log(this.countryList);
})
}
},
mounted () {
this.globalStatus()
}
}
</script>
<style scoped>
</style>
You really should be consulting the documentation of the API you're using or at least look at the data its returning.
The API responds with something like the following
{
"get": "countries",
"parameters": [],
"errors": [],
"results": 217,
"response": [
"Afghanistan",
"Albania",
"Algeria",
//...
]
}
so you'll want something like the following in your code
axios.get('https://covid-193.p.rapidapi.com/countries', options).then(res => {
this.countryList = res.data.response
})
and in your template
<select name="country">
<option disabled value="">Choose</option>
<option v-for="country in countryList" :key="country" :value="country">
{{ country }}
</option>
</select>
If you're wanting to work with the selection in Vue, you'll also want to bind it using v-model, eg
<select v-model="selectedCountry" name="country">
and in your data...
data: () => ({
Recovered: "Loading ...",
countryList: [],
selectedCountry: ''
})
jsFiddle demo here ~ https://jsfiddle.net/caqx2zmr/

How to Fetch data using Vue Js laravel

How do I fetch data using vue js and laravel . I have created vue component and controller.
Here is my database table structure
<script>
export default {
data(){
return {
kudos : []
}
},
created(){
axios.get('./api/kudos')
.then(response => this.kudos = response.data);
}
}
</script>
What I need to do is fetch the database data to blade file using vuejs .
Could someone guide me step by step?
Controller
Vue Component
Blade File
I think you're looking for something like this?
Controller:
public function searchDatabase( Request $request )
{
$foo = DB::table('bar')
->where([
["description", 'LIKE', "%{$request->input('query')}%"]
])
->limit(5)
->get();
return response()->json($foo);
}
YourComponent.vue
<template>
<div id="wrapper">
<div class="input-group">
<input type="text" placeholder="Search database.." v-model="query" v-on:keyup="autoComplete" class="form-control">
</div>
<div class="panel-footer" v-if="results.length">
<table class="table table-sm">
<tr v-bind:key="result" v-for="result in results">
<td> {{ result.description }} </td>
</tr>
</table>
</div>
</div>
</template>
<script>
export default{
data(){
return {
query: '',
url: '/search/blade/route',
results: []
}
},
methods: {
autoComplete(){
this.results = [];
if(this.query.length > 2){
axios.get('/api/kudos', {params: {query: this.query}}).then(response => {
this.results = response.data;
});
}
}
}
}
</script>
search.blade.php
<your-component></your-component>
Add the name of your data in your response
<script>
export default {
data(){
return {
kudos : []
}
},
created(){
axios.get('./api/kudos')
.then(response => this.kudos = response.data.NameOfYourData);
}
}
</script>

Laravel 5.7 - VUE Component - Property or method "continent_selected" is not defined on the instance but referenced during render

I'm getting this error in a Vue component I'm developing in Laravel 5.7.
Can you tell me what am I missing?
It's just the Input Binding of continent_selected and country_selected that doesn't work, the rest of the code is fine.
Property or method "continent_selected" is not defined
on the instance but referenced during render. Make sure > that this property is reactive, either in the data
option, or for class-based components, by initializing
the property.
This is my code:
<template>
<div>
<div class="form-group continent_id">
<select name="continent_id" v-model="continent_selected" id="continent_id" class="selectpicker" data-live-search="false" title="Pick a continent">
<option v-if="continents.length>0" v-for="continent in continents" v-bind:value="continent.id">
{{ continent.name }}
</option>
</select>
</div>
<div class="form-group country_id">
<select name="country_id" v-model="country_selected" id="country_id" class="selectpicker" data-live-search="true" title="Pick a country">
<option v-for="(country, index) in countries" v-bind:value="country.id" >
{{ country.name }}
</option>
</select>
</div>
<span>Continent Selected: {{ continent_selected }}</span>
<span>Country Selected: {{ country_selected }}</span>
</div>
</template>
<script>
export default {
mounted() {
console.log('Component mounted.');
this.loadData();
},
data() {
return {
continents: [],
countries: [],
continents_selected: '',
country_selected: '',
}
},
methods: {
loadData: function() {
axios.get('/api/continents')
.then((response) => {
// handle success
this.continents = response.data.data;
this.getAllCountries(response.data.data);
})
.catch((error) => {
// handle error
console.log(error);
})
.then(() => {
// always executed
});
},
getAllCountries: function(continents) {
var j = 0;
for (var i = 0, len = continents.length; i < len; i++) {
for (var key in continents[i].active_countries) {
this.countries[j] = {id: continents[i].active_countries[key], name: key};
j++;
}
}
}
},
}
</script>
In your data() you have continents_selected instead of continent_selected. Remove the S after continent and it should work.
Your Vue was trying to use a variable that didn't exist (because of the s), which is why this error occured.

How to filter comments with vue.js?

In my view i have this :
<select class="sort_by">
<option selected disabled>SORT BY</option>
<option value="name" >Name</option>
<option value="date">Date</option>
</select>
In my controller i have this:
$comments = $article->comments()->orderBy('created_at','desc')->get();
In my vue i have this:
loadComments: function () {
articleid = this.article_id;
this.$http.get('/article/'+ articleid +'/allcomments').then(function(response){
// True
data = response.data.comments;
this.$set('all_comments', data);
this.comments= data;
}, function(response){
// False
});
},
What i want is when user select name or date, to change orderBy and then to display it in view without refresh. Any suggestion how can i do that?
EDIT:
In my ready function i have:
this.loadComments();
setInterval(function () {
this.loadComments();
}.bind(this), 20000);
So i cant sort by in vue.js, or can i?
You can use the Lodash sortBy method inside a computed property which acts as a filter. Lodash is included by default in the newest Laravel versions.
Your .vue file could look like this:
(NOTE: This is a Vue 2.0 example, if you are using a previous version of Vue some things can differ)
<template>
<select v-model="sortingBy" class="sort_by">
<option selected disabled>SORT BY</option>
<option value="name">Name</option>
<option value="date">Date</option>
</select>
<div v-for="comment in sortedComments">
// Here your HTML for each comment
<div>
</template>
<script>
export default {
data() {
return{
comments: {},
sortingBy: "name", // Default sorting type
}
},
computed: {
sortedComments: function () {
return _.sortBy(this.comments, [this.sortingBy]);
}
},
mounted() {
this.loadComments();
setInterval(function () {
this.loadComments();
}.bind(this), 20000);
},
methods: {
loadComments: function () {
this.$http.get('/article/' + this.article_id + '/allcomments').then((response) => {
this.comments = response.data;
});
},
}
}
</script>

Resources