Set selected option selected inside a loop Vue.js - javascript

Im looping over a list of objects and I'm trying to have the status of the object be selected by default.
<template>
<table class="table is-striped">
<thead>
<tr>
<th>
Client
</th>
<th>
Status
</th>
</tr>
</thead>
<tbody>
<tr v-for="client in filteredClients">
<td>
<router-link :to="{ name:'client-show' , params:{clientId: client.uuid}}"
v-on:click.native="selectClient(client)">
{{ client.name }}
</router-link>
</td>
<td>
<div class="select is-rounded">
<select v-model="selectedStatus" #change="statusChange($event, client)">
<option v-for="status in statuses" > {{status}}</option>
</select>
</div>
</td>
</tr>
</tbody>
</table>
</template>
<script>
export default {
props: [
'filteredClients'
],
data: function() {
return {
statuses: [ 'Started', 'Awaiting Payment', 'Paid', 'Onboarding', 'Live']
}
},
computed: {},
mounted() {},
methods: {}
}
</script>
Here i have all the statuses that i need to display but im having a hard time getting a selected value to be selected for each object that im looping over through.

you need to $emit the status change to parent Component so that new status will be assigned to specific client object. (no mutation of props in child)
<select :value="client.status" #change="$emit('change', $event.target.value, client.uuid)">
<option v-for="status in statuses" :selected="status == client.status">{{status}}</option>
</select>
and on your parent Component, capture this emit and assign it to the client
<ParentComponent #change="(status, uuid) => clients.find(c => c.uuid === uuid).status = status">
// child with props: filteredClients
</ParentComponent>

Related

How to restrict dropdown select option for that particular row

I am using nuxt.js to develop a web application ,in that i have on page that page responsible for the custom forms ,please refer the following image
In this page if i click on increment decrement buttons it will create another row upto this part it's working fine,now if i select any column dropdown in first row it's selecting but it's automatically updating all rows column dropdown ,can you please help me to fix this issue ..?
<template>
<div class="pt-5 table-responsive">
<h3>Conditions</h3>
<table class="table table-bordered table-hover">
<thead class="thead-light">
<tr>
<th scope="col">#</th>
<th scope="col">Column</th>
<th scope="col">Condition</th>
<th scope="col">Input Field</th>
<th scope="col" class="text-right">Add/Remove</th>
</tr>
</thead>
<tbody>
<tr v-for="(input, index) in inputs" :key="index">
<td>{{ index + 1 }}</td>
<td>
<select v-model="fields" class="form-select form-control">
<option
v-for="conditionField in conditionFields"
:key="conditionField.id"
>
{{ conditionField.name }}
</option>
</select>
</td>
<td>
<select v-model="condFies" class="form-select form-control">
<option
v-for="typeCondition in typeConditions"
:key="typeCondition.id"
>
{{ typeCondition.name }}
</option>
</select>
</td>
<td>
<base-input placeholder="Type here"></base-input>
</td>
<td class="text-right">
<base-button type="secondary" #click="addRow(input)"
><i class="ni ni-fat-add"></i>
</base-button>
<base-button type="secondary" #click="removeRow(index, input)"
><i class="ni ni-fat-delete"></i>
</base-button>
</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
export default {
data() {
return {
inputs: [{}],
fieldInputs: [{}],
conditions: [],
forms: [],
selectedForm: [],
loadedForm: [],
conditionFields: [],
selectFields: [],
condFies: [],
fields: [],
selFields: [],
report: [],
typeConditions: [],
}
},
methods: {
getQueryConditions() {
try {
const axios = this.$axios.create()
axios
.get(
'queryconditions'
// , {
// transformRequest: (headers) => {
// delete headers.common['Organization-Id'];
// }
// }
)
.then((response) => {
this.conditions = response.data.data
this.conditions.forEach((element) => {
if (element.type.includes('condition')) {
console.log(element)
this.typeConditions = this.conditions
}
})
})
} catch (e) {
console.log('error', e)
}
},
},
}
</script>

Vue select affecting other selector's currently selected choice [duplicate]

This question already has answers here:
use v-model inside a v-for loop
(5 answers)
Closed 2 years ago.
I have a table that displays a certain Nova resource. For each row, I have a selector that would allow me to perform one action from a dropdown. The problem is, let's say I have 3 rows. Each row would have the same selector. Let's say the selector has options A, B, and C. If I go to the first row and select option B, the other selectors also change their currently selected value to B. I'm assuming this is because all of the selectors have the same v-model binding, but I'm not sure how to get around this.
This is the code for the table and the selector:
<table id="favorites">
<tr>
<th>ID</th>
<th>Title</th>
<th>Source</th>
<th>Description</th>
<th>Date of Creation</th>
<th>Posted Status</th>
<th>Actions</th>
</tr>
<tr v-for="(favorite, index) in favorites" :key="index">
<td>{{favorite.id}}</td>
<td>{{favorite.title}}</td>
<td>{{favorite.source}}</td>
<td>{{favorite.description}}</td>
<td>{{favorite.created_at}}</td>
<td>
<div v-if="favorite.posted_status === 2">
<button class="button-posted button4">Posted</button>
</div>
<div v-else>
<button class="button-not-posted button4">Not Posted</button>
</div>
</td>
<td>
<select #change="toggle_posted(favorite)" v-model="selected_state" class="form-control form-control-lg">
<option selected disabled>Choose an action </option>
<option v-for="(state, index) in posted_states" :key="index" :value="state.id">{{state.name}}</option>
</select>
</td>
</tr>
</table>
I want to separate the selectors so that they don't mirror each other. It's also worth noting that while the other selectors change, they don't actually call the toggle_posted method. Only the selector I chose does.
A straight-forward way to fix this would be adding a selected_state attribute for each list item in favorites:
new Vue({
el:"#app",
data: () => ({
favorites: [
{ id:1, title:'1', source:'1', description:'1', created_at:'1', posted_status: 1, selected_state:null },
{ id:2, title:'2', source:'2', description:'2', created_at:'2', posted_status: 2, selected_state:null }
],
selected_state: null,
posted_states: [
{ id:1, name:'1' }, { id:2, name:'2' }
]
}),
methods: {
toggle_posted(favorite) {
console.log(favorite)
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<table id="favorites">
<tr>
<th>ID</th>
<th>Title</th>
<th>Source</th>
<th>Description</th>
<th>Date of Creation</th>
<th>Posted Status</th>
<th>Actions</th>
</tr>
<tr v-for="(favorite, index) in favorites" :key="index">
<td>{{favorite.id}}</td>
<td>{{favorite.title}}</td>
<td>{{favorite.source}}</td>
<td>{{favorite.description}}</td>
<td>{{favorite.created_at}}</td>
<td>
<div v-if="favorite.posted_status === 2">
<button class="button-posted button4">Posted</button>
</div>
<div v-else>
<button class="button-not-posted button4">Not Posted</button>
</div>
</td>
<td>
<select #change="toggle_posted(favorite)" v-model="favorite.selected_state" class="form-control form-control-lg">
<option selected disabled>Choose an action </option>
<option v-for="(state, index) in posted_states" :key="index" :value="state.id">{{state.name}}</option>
</select>
</td>
</tr>
</table>
</div>

How can I retrieve data from an array which is inside another array and display it in the table?

Using Vue.js , I am able to retrieve and display id,description and location, but why in the tasks column I only have [object Object] in all the rows ?!
(tasks is an array inside jobs array)
<template>
<div>
...
<table class="table table-hover">
<thead>
<tr>
<th v-for="column in columns">
...
</th>
</tr>
</thead>
<tbody>
<tr v-for="work in jobs">
<td>{{work["id"]}}</td>
<td>{{work["description"]}}</td>
<td>{{work["location"]}}</td>
<td v-for="tasks in jobs" >{{work["tasks"]}}</td>
</tr>
</tbody>
</table>
<script>
export default{
data : function() {
return{
columns: ['id', 'description', 'location', 'tasks'],
jobs: '',
update: this.getData()
}
},
methods: {
//to get data from the backend API
getData() {
this.$http
.get('http://localhost:3001/api', (data) => {
this.jobs = data["jobs"]
})
}
}
</script>
You are iterating over jobs and not each task inside the job's tasks
You should do something like -
<tr v-for="work in jobs">
<td>{{work["id"]}}</td>
<td>{{work["description"]}}</td>
<td>{{work["location"]}}</td>
<td v-for="task in work.tasks" >{{task["id"]}} -
{{task["description"]}} - {{task["location"]}}</td>
</tr>
Or however you want to display there. But the idea should be to iterate on the tasks array inside each work object
You'll need to explicitly extract the fields that you want to show from tasks. Also, the syntax for the nested v-for would be something like task in work.tasks, so that your task points to each task inside of your tasks array for each work:
<tr v-for="work in jobs">
<td>{{work["id"]}}</td>
<td>{{work["description"]}}</td>
<td>{{work["location"]}}</td>
<td v-for="task in work.tasks">
{{task["id"]}} <br>
{{task["description"]}} <br>
{{task["location"]}}
</td>
</tr>

i am coding ..todo task manger in Angular2.... having to update select option value ....in localStorage

Here is my problem regarding to-do task management.
I want to update an option value in select selector when the (change) event is triggered.
there are 2 Component
//app.component.ts
//array object
this.dataArr[this.counter] = {id: this.task_ID, name: this.t_name, msg: this.t_msg, date: this.task_date};
//console.log(this.counter);
console.log(this.dataArr[this.counter]);
//local storage
if (typeof(Storage) !== "undefined") {
localStorage.setItem("taskM", JSON.stringify(this.dataArr.reverse())); //put object array in reverse order to show latest object at top position
this.myObj = JSON.parse(localStorage.getItem("taskM"));
}
in this component I want to change and save select option value to localStorage
//task-form.component.ts.
import { Component, OnInit, Input, Output } from '#angular/core';
import { AppComponent } from './app.component';
#Component({
selector: 'task-data',
template: `<h3>List of Task</h3>
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>Task Id</th>
<th>Task Title</th>
<th>Description</th>
<th>Date</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let hero of taskMM">
<td> {{ hero.id }} </td>
<td> {{ hero.name }} </td>
<td> {{ hero.msg }} </td>
<td> {{ hero.date }} </td>
<td>
<select class="form-control">
<option *ngFor="let p of taskStatus"[value]="p"> {{p}}</option>
</select>
</td>
</tr>
</tbody>
</table>
</div>
`
})
export class TaskFormComponent {
taskStatus: string[];
taskMM: string[] = JSON.parse(localStorage.getItem("taskM"));
#Input('task-s') t_status: string;
#Input() data1: any= [];
onChange(deviceValue) {
console.log(deviceValue);
}
ngOnInit() {
console.log('this is ngOnInit ');
}
constructor() {
this.taskStatus = ['Started', 'Pending', 'Completed'];
}
}
<select (change)="onChange($event.target.value)" class="form-control">
<option *ngFor="let p of taskStatus"[value]="p"> {{p}}</option>
</select>
onChange($event) {
localStorage.setItem("taskM", $event);
}

Vue.js $remove not removing element after deleted from database

I am using Laravel and trying to learn Vue.js. I have a delete request that is working properly and deleting the object from the database. The problem is that it is not being removed from the DOM after the successful deletion. I am using the $remove method and passing it the full object, so I know I'm missing something.
As a side note, I have a main.js as an entry point with a PersonTable.vue as a component. The PersonTable.vue holds the template and script for that template.
Here is my Laravel view:
<div id="app">
<person-table list="{{ $persons }}">
</person-table>
</div>
And here is my `PersonTable.vue:
<template id="persons-template">
<div class="container">
<div class="row">
<div class="col-sm-12">
<h1>Persons List</h1>
<table class="table table-hover table-striped">
<thead>
<tr>
<td>First Name</td>
<td>Last Name</td>
<td>Email</td>
<td>Gender</td>
</tr>
</thead>
<tbody>
<tr v-for="person in list">
<td>{{person.first_name }}</td>
<td>{{person.last_name }}</td>
<td>{{person.email }}</td>
<td>{{person.gender }}</td>
<td><span #click="deletePerson(person)">X</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</template>
<script>
export default {
template: '#persons-template',
props: ['list'],
methods: {
deletePerson: function(person) {
this.$http.delete('/person/' + person.id).then(
function(response) {
this.persons.$remove(person);
}
);
}
},
created: function() {
this.persons = JSON.parse(this.list);
}
};
</script>
And my main.js entry point:
var Vue = require('vue');
Vue.use(require('vue-resource'));
var Token = document.querySelector('meta[name="_token"]').getAttribute('content');
Vue.http.headers.common['X-CSRF-TOKEN'] = Token;
import PersonTable from './components/PersonTable.vue';
new Vue({
el: '#app',
components: { PersonTable },
})
I think you need to bind this to the response function:
function(response) {
this.persons.$remove(person);
}.bind(this)
That way when you do this.persons you are still referring to the Vue component
edit: could try -
props:['personJson'],
data:function(){
return {
persons:[]
}
},
ready:function(){
this.persons = JSON.parse(this.personJson)
}
Thinking maybe since persons is a string initially, Vue isn't binding the reactive capabilities properly?
I think that you need to use the this.$set in your created method, if you don't, I am afraid that Vue would lose reactivity.
In your created method, could you try the following:
export default {
template: '#persons-template',
props: ['persons'],
methods: {
deletePerson: function(person) {
var self = this;
this.$http.delete('/person/' + person).then(
function(response) {
self.persons.$remove(person);
}
);
}
},
created: function() {
this.$set('persons',JSON.parse(this.persons));
}
};
Finally figured it out. I needed to pass the JSON data to my data property of the component. Here is the code.
In the blade file:
<div id="app">
<person-table list="{{ $persons }}">
</person-table>
</div>
In my PersonTable.vue file:
<template id="persons-template">
<div class="container">
<div class="row">
<div class="col-sm-12">
<h1>Persons List</h1>
<table class="table table-hover table-striped">
<thead>
<tr>
<td>First Name</td>
<td>Last Name</td>
<td>Email</td>
<td>Gender</td>
</tr>
</thead>
<tbody>
// Notice how I am using persons here instead of list
<tr v-for="person in persons">
<td>{{person.first_name }}</td>
<td>{{person.last_name }}</td>
<td>{{person.email }}</td>
<td>{{person.gender }}</td>
<td><span class="delete person" #click="deletePerson(person)"><i class="fa fa-close"></i></span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</template>
<script>
export default {
template: '#persons-template',
props: ['list'],
data: function() {
return {
persons: []
}
},
methods: {
deletePerson: function(person) {
this.$http.delete('/person/' + person.id).then(
function(response) {
this.persons.$remove(person);
}
);
},
},
created: function() {
// Pushing the data to the data property so it's reactive
this.persons = JSON.parse(this.list);
},
};
</script>
Thanks to everyone for their contributions. I almost ditched Vue because of how long it has taken to fix this error.

Categories

Resources