How to disable select option in Vuejs - laravel

Good day! I am new in Vuejs. Please help me.
I want to disable the select option after I select and set the select to default value.
for example
<select name="recipient" #change="changeFunc($event)">
<option>--Select--</option>
<option v-for="recipient in recipients" :key="recipient.id" :value="recipient.id" :disabled="recipient.disabled">{{ recipient.name }}</option>
</select>
export default {
data: function() {
return {
recipients: [
{'id':3, 'name':'aaa'},
{'id':5, 'name':'bbb'},
{'id':8, 'name':'ccc'}
],
}
},
method: {
changeFunc(e) {
//TODO disable the select value and set to default value
}
}
}
Please help how to do it. Thank you.

Try the following code
<select name="recipient" v-model="selected" #change="changeFunc($event)">
<option>--Select--</option>
<option v-for="recipient in recipients" :key="recipient.id" :value="recipient.id" :disabled="recipient.disabled">{{ recipient.name }}</option>
</select>
export default {
data: function() {
return {
selected: {},
recipients: [
{'id':3, 'name':'aaa', 'disabled': false},
{'id':5, 'name':'bbb', 'disabled': false},
{'id':8, 'name':'ccc', 'disabled': false}
],
}
},
method: {
changeFunc(e) {
const index = this.recepients.findIndex((el) =>{
if(el.id == this.selected){
return true;
}
});
if(index){
this.recepeints[index].disabled = true;
this.selected = "";
}
}
}
}
The changeFunc() find index of selected value and set disabled to true and reset selected value

You can achieve this with a simple approach by iterating the input array on option change.
this.recipients.forEach(obj => {
obj['disabled'] = (obj.id === this.recipient)
});
Live Demo :
new Vue({
el: '#app',
data: {
recipient: '',
recipients: [
{'id':3, 'name':'aaa'},
{'id':5, 'name':'bbb'},
{'id':8, 'name':'ccc'}
]
},
methods: {
changeFunc() {
this.recipients.forEach(obj => {
obj['disabled'] = (obj.id === this.recipient)
});
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<select v-model="recipient" #change="changeFunc">
<option value="">--Select--</option>
<option v-for="recipient in recipients" :key="recipient.id" :value="recipient.id" :disabled="recipient.disabled">{{ recipient.name }}</option>
</select>
</div>

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

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.

Laravel 5.7, Update <options> in a select drop-down with Vue

I'm writing my first Laravel Vue component and I have this error in console.
[Vue warn]: Computed property "options" was assigned to but it
has no setter.
The code is about two select dropdowns, one with continents and one with countries. I want that when I update the continent the countries get updated.
I just miss to update the options of the second select with the updated values that I have in this.countries.
After the continent change the this.countries variable get updated but the values of the options of the country_id select are not changing.
I've tried adding computed but I get this error.
What am I doing wrong?
<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" v-on:change="getAllCountries(continents)">
<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>
</div>
</template>
<script>
export default {
mounted() {
console.log('Component mounted.');
this.loadData();
},
data() {
return {
continents: [],
countries: [],
continent_selected: '',
country_selected: '',
}
},
computed: {
get: function () {
return this.countries;
},
set: function (newValue) {
this.countries = newValue;
}
},
methods: {
loadData: function() {
axios.get('/api/continents')
.then((response) => {
// handle success
this.continents = response.data.data;
this.getAllCountries(this.continents);
})
.catch((error) => {
// handle error
console.log(error);
})
.then(() => {
// always executed
});
},
getAllCountries: function(continents) {
console.log(this.continent_selected);
console.log(continents);
var j = 0;
this.countries = [];
for (var i = 0, len = continents.length; i < len; i++) {
if (!this.continent_selected){
for (var key in continents[i].active_countries) {
this.countries[j] = {id: continents[i].active_countries[key], name: key};
j++;
}
}
else{
console.log("continent selected: "+ this.continent_selected);
for (var key in continents[i].active_countries) {
if (continents[i].id == this.continent_selected){
this.countries[j] = {id: continents[i].active_countries[key], name: key};
j++;
}
}
}
}
}
},
}
</script>
I have solved my issue that was mainly related to the computed set method of the variable optionCountries.
The dropdown was not updating because it use Bootsrap Select, so in order to show the new options it needs to be refreshed.
I've also figure out that I need to add a timeout to the refresh request.
This is the final 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" v-on:change="getAllCountries(continents)">
<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 optionCountries" v-bind:value="country.id" >
{{ country.name }}
</option>
</select>
</div>
</div>
</template>
<script>
export default {
mounted() {
console.log('Component mounted.');
this.loadData();
},
data() {
return {
continents: [],
countries: [],
continent_selected: '',
country_selected: '',
}
},
computed: {
optionCountries:{
get: function () {
return this.countries;
},
set: function (newValue) {
this.countries = newValue;
setTimeout(() => {
jQuery('.selectpicker').selectpicker('refresh');
}, 500);
}
}
},
methods: {
loadData: function() {
axios.get('/api/continents')
.then((response) => {
// handle success
this.continents = response.data.data;
this.getAllCountries(this.continents);
})
.catch((error) => {
// handle error
console.log(error);
})
.then(() => {
// always executed
});
},
getAllCountries: function(continents) {
var j = 0;
this.countries = [];
for (var i = 0, len = continents.length; i < len; i++) {
if (!this.continent_selected){
for (var key in continents[i].active_countries) {
this.countries[j] = {id: continents[i].active_countries[key], name: key};
j++;
}
}
else{
for (var key in continents[i].active_countries) {
if (continents[i].id == this.continent_selected){
this.countries[j] = {id: continents[i].active_countries[key], name: key};
j++;
}
}
this.optionCountries = this.countries;
}
}
}
},
}
</script>
In this line you are setting the value of options attribute:
this.options = this.options;
, but, this property is computed:
computed: {
options: function(event) {
return this.countries
}
},
In this case you can:
create a computed setter: https://v2.vuejs.org/v2/guide/computed.html#Computed-Setter
computed: {
options: {
get: function () {
return this.countries;
},
set: function (newValue) {
this.countries = newValue;
}
}
},
Set the value directly:
this.countries = this.options;

Vuejs + Laravel array issue

My problem is I'm trying to loop and array from Axios query into my blade template, query is giving me no errors but tells me is undefined multiple times on my select tag.
I have a simple Axios query from my Laravel Controller:
public function consultaPersonas()
{
$consulta = persona::all();
if(!$consulta) {
$consulta = ['error' => 'No hay registros'];
}
return $consulta;
}
this query will bring me this little array:
[
{"cedula":"15678453","nombre":"LUIS CHACON","edad":30},
{"cedula":"2536524","nombre":"MARIO ORTEGA","edad":21},
{"cedula":"25632541","nombre":"VANESSA ALCALA","edad":24}
]
This is the Select Tag i want to loop:
<select class="form-control" v-model="nombre">
<option v-for="nom in nombre">#{{ nombre }}</option>
</select>
Here's my Vuejs code:
var app = new Vue({
el: '#root',
data: {
cedula: '',
nombre: [],
},
watch: {
cedula: function() {
this.nombre = ''
if (this.cedula.length == 1) {
this.buscarCedula()
this.nombre = "Consultando cédula...";
}
}
},
methods: {
buscarCedula: _.debounce(function() {
axios.get('http://localhost/miapp/public/personas/mostrar')
.then(function(response) {
let datos = response.data;
let validar = datos.error;
if (!validar) {
app.nombre =
datos.cedula + ' - ' +
datos.nombre + ' - ' +
datos.edad;
} else {
app.nombre = validar;
}
})
.catch(function(error) {
app.nombre = error;
})
}, 500)
}
What am I doing wrong? Thanks.
js:
created():
axios.get('http://localhost/miapp/public/personas/mostrar')
.then(function (response){
this.nombre = response.data;
}).catch(function (error) {
console.log(error);
})
html:
<select class="form-control" v-model="nombre">
<option v-for="nom in nombre">#{{ nom.nombre }}</option>
</select>
Next, you transfer from the created method call axios to methods, and in created call this method. This initializes your initial data
I find out what was wrong,
I had two problems, one was my view tags variables, this is the right way since i need to loop through my nom object with his index like this:
<select class="form-control" v-model="nombre">
<option v-for="nom in nombre">#{{ nom.cedula }}</option>
</select>
the second problem was my return at my vuejs file, i was returning one single output into a loop, this is the right way:
var app = new Vue({
el: '#root',
data: {
cedula: '',
nombre: [],
},
watch: {
cedula: function() {
this.nombre = ''
if (this.cedula.length == 1) {
this.buscarCedula()
this.nombre = "Consultando cédula...";
}
}
},
methods: {
buscarCedula: _.debounce(function() {
axios.get('http://localhost/miapp/public/personas/mostrar')
.then(function(response) {
if (!response.data.error) {
return app.nombre = response.data;
} else {
return app.nombre = response.data.error;
}
})
.catch(function(error) {
app.nombre = error;
})
}, 500)
}
)};

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