Whenever I save the first item in my store it won't show up in frontend, only my buttons do.
After the first row has been added and I refresh I can add more rows, which do show up.
I tried making a clientIndex because I thought it maybe it didn't update because of "field.id", but that changed nothing.
Can anyone tell what I can do to fix it?
My index.js
state: {
clientfields: [],
clients: [],
},
mutations: {
setClientFields(state, fields) {
state.clientfields = fields;
},
setClients(state, clients) {
state.clients = clients;
},
deleteClient(state, client) {
state.clients.splice(state.clients.indexOf(client), 1);
},
addClient(state, client) {
state.clients.unshift(client);
},
actions: {
fetchClients({ state, commit }) {
axios.get('http://localhost:8000/api/clients')
.then(response => {
console.log(response.data.data);
commit("setClients", response.data.data)
commit("setClientFields", Object.keys(state.clients[0]))
console.log(Object.keys(state.clients));
})
},
deleteClient({ commit }, clientdata) {
axios.delete("http://localhost:8000/api/clients/" + clientdata.id)
commit("deleteClient", clientdata)
},
saveClient({ commit }, clientdata) {
let promise;
if (clientdata.id != null) {
promise = axios.put("http://localhost:8000/api/clients/" + clientdata.id, clientdata)
console.log(clientdata)
} else {
console.log(clientdata)
promise = axios.post("http://localhost:8000/api/clients/", clientdata)
}
promise.then(function (response) {
if (clientdata.id != null) {
commit("saveClient", clientdata)
} else {
commit("addClient", response.data.data)
}
})
.catch(function (error) {
console.log(error.response);
commit('error', error.response)
})
},
}
My Component
<template>
<div class="app" >
<v-btn tile elevation="4" style="margin-left: 20px margin-top: 20px;" v-if="! showEdit" class="btn btn-blue left" v-on:click="saveClient">Nieuwe Client</v-btn>
<table class="table-auto">
<thead>
<tr class="md:border-t-2 border-collapse border border-gray-600 ...">
<th class="px-4 py-2 ">Edit</th>
<th class="px-4 py-2 ">Delete</th>
<th class="px-4 py-2 allow-overflow" v-for="field in fields" :key="field.id">{{ field.replace("_"," ") }}</th>
</tr>
</thead>
<tr class="md:border-t-2 border-collapse border border-gray-600 ..." v-for='(clientdata, clientIndex) in clients' :key="clientIndex">
<td class="px-4 py-2 font-medium">
<v-btn class="ocz" v-on:click="updClient(clientdata)">
Edit
</v-btn>
</td>
<td class="px-4 py-2 font-medium">
<template>
<v-dialog
v-model="confirm"
width="350"
>
<template v-slot:activator="{ on, attrs }">
<v-btn
color="red"
v-bind="attrs"
v-on="on"
>
Delete
</v-btn>
</template>
<v-card>
<v-card-title class="text-h5">
ARE YOU SURE YOU <br> WANT TO DELETE THIS?
</v-card-title>
<v-card-actions>
<v-btn
color="grey"
text
#click="confirm = false"
>
Cancel
</v-btn>
<v-btn
color="red"
text
#click="delClient(clientdata); confirm = false;"
>
Delete
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
</td>
<td class="px-4 py-2 font-medium" v-for="field in fields" :key="field.id">{{ clientdata[field] }}</td>
</tr>
<tr v-if="!clients.length" >
<td class="px-4 py-2 font-medium" style="opacity: 0.6;">No data to be shown.</td>
</tr>
</table>
<transition name="fade">
<div class="modal" v-if="dialog">
<div class="modal-content">
<EditModal :client="selClient" v-show="showEdit" #close="closeEdit"/>
</div>
</div>
</transition>
</div>
</template>
<script>
import EditModal from '#/components/Clients/EditClients.vue'
export default{
dialog: false,
overlay: true,
components: {
EditModal,
},
data () {
return {
selClient: {},
showEdit: false,
confirm: false,
clientIndex: 100,
}
},
created () {
this.$store.dispatch('fetchClients')
},
computed: {
clients() {
return this.$store.state.clients;
},
fields() {
return this.$store.state.clientfields;
}
},
methods: {
closeEdit: function() {
this.showEdit = false;
this.dialog = false;
},
delClient: function(clientdata) {
this.clientIndex--;
this.$store.dispatch('deleteClient', clientdata)
},
updClient: function(clientdata) {
this.selClient = clientdata;
this.showEdit = true;
this.dialog = true;
this.clientIndex++;
this.$store.dispatch('saveClient', clientdata)
},
saveClient: function(clientdata) {
this.showEdit = true;
this.dialog = true
this.clientIndex++;
this.$store.dispatch('saveClient', clientdata);
},
createClient(){
this.selClient = {};
}
}
}
</script>
I Fixed it, in my index I just committed my field data on save so my table gets filled and shows data.
promise.then(function (response) {
if (clientdata.id != null) {
commit("saveClient", clientdata)
} else {
commit("addClient", response.data.data)
}
! added my commit here to fill fields :) !
})
Related
When i use the vuetify data datable group header feature and
when the top group checkbox is selected, i want the checkboxes below it to be selected as well.
Here is the code.
https://codepen.io/ersin-g-ven-/pen/LYdeWor?editors=1010
<div id="app">
<v-app id="inspire">
<v-data-table
:headers="headers"
:items="desserts"
item-key="name"
sort-by="name"
group-by="category"
class="elevation-1"
show-select
show-group-by
>
<template v-slot:[`group.header`]="{items}">
<th colspan="2">
<v-checkbox
v-model="selected"
:label="items[0].category"
></v-checkbox>
</th>
</template>
</v-data-table>
</v-app>
</div>
Just came across your post. I think the combination of v-treeview with selection-type="leaf" can do the trick.
Check the documentation on: https://vuetifyjs.com/en/api/v-treeview/#props-selection-type
and see how it works: https://vuetifyjs.com/en/components/treeview/#selection-type
Using of the "v-model" with "watch" has worked for me:
<template v-slot:group.header="{group, items}">
<th colspan="4">
<v-checkbox
:label="items[0].category"
:value="group"
v-model="selected_groups"
>
</v-checkbox>
</th>
</template>
...
data() {
...
selected: [],
selected_groups: []
}
watch: {
selected_groups(node_new, node_old) {
if(node_new.length < node_old.length) {
let dif = node_old.filter(x => !node_new.includes(x))[0]
this.selected = this.selected.filter(item => { return !Object.values(item).includes(dif) })
} else if (node_new.length > node_old.length) {
this.items_arr.forEach(item => {
if(Object.values(item).includes(node_new.at(-1))) {
this.selected.push(item)
}
})
} else if (node_new.length == node_old.length) {
return this.selected
}
},
selected(selected_new, selected_old) {
if(selected_new.length < selected_old.length) {
let dif_NODE = selected_old.filter(x => !selected_new.includes(x))[0][this.groupable_col]
let arr_NODEs = []
selected_new.forEach(item => { arr_NODEs.push(item[this.groupable_col]) })
if(!arr_NODEs.includes(dif_NODE)) {
this.selected_groups= this.selected_groups.filter(item => item != dif_NODE)
}
} else if(selected_new.length > selected_old.length) {
if(!this.selected_groups.includes(selected_new.at(-1)[this.groupable_col])) {
this.selected_groups.push(selected_new.at(-1)[this.groupable_col])
}
}
}
}
I need replace a button when it's clicked because I need that button to have 3 states (entrada, salida and registrado),I already have those buttons but they only work when reloading the page, I just want it to render without reload, I add my code for a better explanation
vuetify-data-table
<td>
<v-btn color="success" v-if="item.check_in == null && item.check_out == null"
v-on:click="entrada(item)">
Entrada</v-btn>
<v-btn color="error" v-else-if="item.check_out == null && item.check_in !== null"
v-on:click="salida(item)">
Salida</v-btn>
<v-btn v-else disabled>Registrado</v-btn>
</td>
You can play out with the buttons with in the <v-data-table> without any page refresh.
Live Demo :
new Vue({
el: '#app',
data () {
return {
headers: [
{
text: 'Check-In',
value: 'checkin'
},
{ text: 'Check-Out', value: 'checkout' },
{ text: 'Actions', value: 'action' }
],
details: [
{
checkin: null,
checkout: null,
action: null
},
{
checkin: 1,
checkout: null,
action: null
},
{
checkin: 1,
checkout: 3,
action: null
}
]
}
},
methods: {
entrada(index) {
this.details.forEach((obj, i) => {
if (i === index) {
obj.checkin = 2
}
})
},
salida(index) {
this.details.forEach((obj, i) => {
if (i === index) {
obj.checkin = null,
obj.checkout = null
}
})
}
}
})
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#1.5.7/dist/vuetify.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vuetify#1.5.7/dist/vuetify.min.css"/>
<div id="app">
<v-app id="inspire">
<div>
<v-data-table
:headers="headers"
:items="details"
class="elevation-1"
>
<template v-slot:items="{item, index}">
<td>{{ item.checkin }}</td>
<td>{{ item.checkout }}</td>
<td>
<v-btn color="success" v-if="item.checkin == null && item.checkout == null"
v-on:click="entrada(index)">
Entrada</v-btn>
<v-btn color="error" v-else-if="item.checkout == null && item.checkin !== null"
v-on:click="salida(index)">
Salida</v-btn>
<v-btn v-else disabled>Registrado</v-btn>
</td>
</template>
</v-data-table>
</div>
</v-app>
</div>
I'm stucked with this issue. When I click on some element it push an item to an array, and I show this array in a table. I want to add an action to delete any row of the table on this way for example:
Table
My code:
<div id="pos">
<div class="container-fluid" style="font-size: 0.8em;">
<div class="row grid-columns">
<div class="col-md-6 col">
<table class="table">
<thead>
<tr>
<th>#</th>
<th>Descripcion</th>
<th>Stock</th>
<th>Precio uni</th>
<th>Precio alt</th>
<th>Cant</th>
<th>Subtotal</th>
<th>Acciones</th>
</tr>
</thead>
<tbody>
<pos-products
:products="products"
v-on:remove-product="removeProduct"
>
</pos-products>
<!-- <tr v-for="item in products" :key="item.id">
<th scope="row">${item.id}</th>
<td>${ item.descripcion }</td>
<td>${ item.stock }</td>
<td>${ item.precio } $</td>
<td>${ item.precio_alt } $</td>
<td>
<v-minusplusfield :value="1" :min="1" :max="100" v-model="item.cant"></v-minusplusfield>
</td>
<td>${ getSubtotal(item) }</td>
<td> Borrar </td>
</tr> -->
</tbody>
</table>
</div>
<div class="col-md-6 col">
<div>
<div id="grid-header" class="p-2 border-b ">
<input class="form-control" name="searchString" placeholder="Buscar producto" type="text" v-model="searchString" />
</div>
</div>
<div style="background-color:#fff">
<div class="col-md-3" v-for="item in searchResults">
<a
href="#"
class="list-group-item"
:key="item.id"
#click="loadItem(item)"
>
<img src="//images03.nicepage.com/a1389d7bc73adea1e1c1fb7e/af4ca43bd20b5a5fab9f188a/pexels-photo-3373725.jpeg" alt="" class="u-expanded-width u-image u-image-default u-image-1" width="25" height="30">
<h6 class="u-text u-text-default u-text-1">${item.descripcion}</h6>
<h4 class="u-text u-text-default u-text-2">${item.precio}$ / ${item.precio_alt}$</h4>
</a>
</div>
</div>
</div>
</div>
</div>
Vue code:
const app = new Vue({
el: "#pos",
delimiters: ["${", "}"],
data () {
return {
products: [],
total: 0,
client: "",
user: "",
paymentDetail: [],
errors: {},
garantia: false,
saveButton: false,
seller: "",
searchString: "",
searchTypingTimeout: "",
searchResults: [],
}
},
methods: {
getSubtotal: function (item) {
return parseInt(item.cant) * parseFloat(item.precio);
},
loadItem: function (item) {
this.products.push({
id: item.id,
descripcion: item.descripcion,
stock: item.stock,
precio: item.precio,
precio_alt: item.precio_alt,
cant: 1,
});
},
removeItem: () => {
products = products.filter((el) => el !== item);
},
searchProducts: function (value) {
axios
.post("/v2/producto/search", {
query: value
})
.then((response) => {
if (!response.status == 200 || response.data.error) {
console.log('error')
const errorMessage = response.data.error
? response.data.error
: "Ha ocurrido un error";
console.log("mensaje: " + errorMessage);
this.$swal({
icon: "error",
title: "Oops...",
text: errorMessage,
});
return;
}
this.searchResults = response.data.data;
})
.catch((error) => {
console.log("catch error", error);
});
},
},
mounted() {
var csrf = document
.querySelector('meta[name="csrf-token"]')
.getAttribute("content");
this.products = [];
},
computed: {},
watch: {
total(val) {
this.total = parseFloat(val);
},
searchString(val) {
if (this.searchTypingTimeout) clearTimeout(this.searchTypingTimeout);
this.searchTypingTimeout = setTimeout(
() => this.searchProducts(this.searchString),
850
);
},
},
});
I got this:
vue.js?3de6:634 [Vue warn]: Property or method "removeItem" 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. See: https://v2.vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.
Try using classic function like this :
removeItem(item){
const index = this.items.findIndex(x => x.id === item.id)
this.items.splice(index, 1)
},
I've here loaded the data with the jsonplaceholder.typicode.com api
new Vue({
el: '#app',
data: () => ({
items: []
}),
async mounted(){
await axios.get('https://jsonplaceholder.typicode.com/posts')
.then(res => {
this.items = res.data
})
},
methods: {
removeItem(item){
const index = this.items.findIndex(x => x.id === item.id)
this.items.splice(index, 1)
},
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.27.2/axios.min.js" integrity="sha512-odNmoc1XJy5x1TMVMdC7EMs3IVdItLPlCeL5vSUPN2llYKMJ2eByTTAIiiuqLg+GdNr9hF6z81p27DArRFKT7A==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<div id="app">
<h1>List </h1>
<ul>
<li v-for="item of items" :key="item.id">
<a #click="removeItem(item)">{{item.id}} - {{item.title}}</a>
</li>
</ul>
</div>
Company Profile
<dashboard-card
title="Company Profile"
titleColor="primary"
#click.native="componentClicked"
id="company-profile" class="vs-con-loading__container"
:isData= "isData"
>
<div class="w-full text-xl md:text-2xl font-bold">
{{ profile.companyName }}
</div>
<div class="md:text-md">
<div class="py-2">
{{ profile.description }}
</div>
<table class="table-auto border-collapse">
<tr>
<td class="py-1 pr-2 md:pr-4 font-bold">CEO:</td>
<td>{{ profile.ceo }}</td>
</tr>
<tr>
<td class="py-1 pr-2 md:pr-4 font-bold">Exchange:</td>
<td>{{ profile.exchange }}</td>
</tr>
<tr>
<td class="py-1 pr-2 md:pr-4 font-bold">Ticker:</td>
<td class="uppercase text-primary font-semibold">
{{ profile.symbol }}
</td>
</tr>
<tr>
<td class="py-1 pr-2 md:pr-4 font-bold">Industry:</td>
<td>{{ profile.industry }}</td>
</tr>
<tr>
<td class="py-1 pr-2 font-bold">Sector:</td>
<td>{{ profile.sector }}</td>
</tr>
</table>
<div class="pt-2">
<vs-icon
:icon="'icon-globe'"
icon-pack="feather"
class="text-primary pr-2"
></vs-icon>
<a class="text-primary" :href="profile.website" target="blank">
{{ profile.website }}
</a>
</div>
</div>
</dashboard-card>
</template>
<script>
import DashboardCard from "../dashboard-card";
export default {
name: "CompanyProfile",
extends: DashboardCard,
components: { DashboardCard },
props: {
ticker: {
type: String,
default: "",
},
},
data() {
return {
profile: {},
isData: "",
};
},
watch: {
ticker(value) {
this.isData = "";
this.getProfile(value);
},
},
mounted() {
this.isData = "";
this.getProfile(this.ticker);
},
methods: {
getProfile(ticker) {
this.$vs.loading({
container: "#company-profile",
type: "point",
scale: 0.8,
});
this.$api.ticker.profile(ticker).then((response) => {
if (Object.keys(response).length == 0) {
console.log("response is empty");
this.isData = "404";
this.$vs.loading.close("#company-profile > .con-vs-loading");
return;
}
this.profile = response;
this.$vs.loading.close("#company-profile > .con-vs-loading");
}).catch(error => {
console.log("error is in company Profile ", error);
if(error.response) {
this.isData = error.response.status.toString();
} else {
this.isData = "Network Error";
}
this.$vs.loading.close("#company-profile > .con-vs-loading");
});
},
},
};
</script>
Dashboard Card (where I'm applying the Blur effect)
<template>
<BaseTHCard
:title="title"
:titleColor="titleColor"
:actionable="actionable"
:fixed-height="fixedHeight"
#click.native="componentClicked"
>
<blur :isData="isData">
<!-- DEFAULT TRADEHAT CARD HEADER SLOT -->
<div slot="header">
<slot name="header"> </slot>
</div>
<!-- DEFAULT TRADEHAT CARD MEDIA SLOT -->
<div slot="media">
<slot name="media"> </slot>
</div>
<!-- DEFAULT TRADEHAT CARD BODY SLOT -->
<slot></slot>
<!-- DEFAULT TRADEHAT CARD EXTRA CONTENT SLOT -->
<div slot="extra-content">
<slot name="extra-content"> </slot>
</div>
<!-- DEFAULT TRADEHAT CARD FOOTER SLOT -->
<div slot="footer">
<slot name="footer"> </slot>
</div>
</blur>
</BaseTHCard>
</template>
<script>
import BaseTHCard from "#/components/common/base-th-card";
import blur from "../../ticker-dashboard/shared/Blur";
export default {
name: "DashboardCard",
extends: BaseTHCard,
components: {
BaseTHCard,
blur
},
props: {
isData: {
type: String,
},
title: {
type: String,
default: null,
},
titleColor: {
type: String,
default: "white",
},
fixedHeight: {
type: Boolean,
default: false,
},
actionable: {
type: Boolean,
default: false,
},
},
};
</script>
I'm getting two following warnings from vue:-
I am setting the isData data option in the CompanyProfile component and passing it as a prop to DashboardCard component and sending that isData prop value to the blurr component. The functionality works fine but I'm getting the above mentioned warnings from vue. What should be the approach to fix them.
I am using vuex , and with getters Iam filtering a array of data in the store.
In a parent component I am fetching the array and send it to a child with props.
The child component resieve filtered array with getters and save it in computed property.
But when I make changes by calling actions, store is updated but filtered array stayed the same.
When I send to the child component original unfiltered array it's okey.
It the vue dev tool I see correct updated getters.
Some of the code is below.
STORE
const getDefaultState = () => {
return {
activities: [],
error: null,
isActivitiesLoading: false,
isActivityUpdating: false,
}
}
const mutations = {
[FETCHING_ACTIVITIES](state) {
state.isActivitiesLoading = true;
state.error = null;
},
[FETCHING_ACTIVITIES_SUCCESS](state, activities) {
state.error = null;
state.isActivitiesLoading = false;
state.activities = activities
},
[FETCHING_ACTIVITIES_ERROR](state, error) {
state.error = error;
state.isActivitiesLoading = false
},
[UPDATING_ACTIVITY](state) {
state.isActivityUpdating = true;
state.error = null;
},
[UPDATING_ACTIVITY_SUCCESS](state, activity) {
state.error = null;
state.isActivityUpdating = false;
const index = state.activities.findIndex(a => a.id === activity.id)
state.activities[index] = activity;
},
[UPDATING_ACTIVITY_ERROR](state, error) {
state.error = error;
state.isActivityUpdating = false
},
}
const actions = {
async fetchActivities({ commit }) {
commit(FETCHING_ACTIVITIES);
try {
const response = await ActivitiesApi.fetchActivities();
const activities = response.data.data;
commit(FETCHING_ACTIVITIES_SUCCESS, activities);
return response.data.data;
} catch (error) {
commit(FETCHING_ACTIVITIES_ERROR, error);
return null;
}
},
async updateActivity({ commit }, payload) {
commit(UPDATING_ACTIVITY);
try {
const response = await ActivitiesApi.updateActivity(payload);
const activity = response.data.data;
commit(UPDATING_ACTIVITY_SUCCESS, activity);
return response.data.data;
} catch (error) {
commit(UPDATING_ACTIVITY_ERROR, error);
return null;
}
},
};
const getters = {
getActivities(state) {
return state.activities;
},
getRunningActivities(state) {
let today = new Date();
const activities = state.activities;
const filteredActivities = activities.filter(function(activity) {
let activityDate = new Date(activity.start_date)
return activityDate <= today
});
return filteredActivities;
},
};
export default {
namespaced: true,
state: getDefaultState(),
getters,
actions,
mutations,
}
PARENT COMPONENT
<template>
<div class="container">
<h3>Running Activities</h3>
<ActivitiesComponent
:initialActivitiesFromStore="runningActivities"
/>
</div>
</template>
import ActivitiesComponent from "../components/Activities";
export default {
components: {
ActivitiesComponent
},
mounted() {
this.$store.dispatch('activities/fetchActivities').then(
() => {
if (this.hasError) {
console.log(this.error)
} else {
}
}
);
},
computed: {
activitiesFromStore() {
return this.$store.getters['activities/getActivities'];
},
runningActivities() {
return this.$store.getters['activities/getRunningActivities']
},
},
}
</script>
CHILD COMPONENT
<template>
<div class="container">
<div v-if="isActivitiesLoading" class="spinner-border spinner"></div>
<div class="row">
<div class="col">
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Activities</th>
<th scope="col">Period</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
<tr v-for="(activity, activityId) in $v.activities.$each.$iter" :key="activityId">
<th scope="row">{{ parseInt(activityId) + 1 }}</th>
<td>
<input type="text" class="form-control" v-model="activity.name.$model">
<div class="alert alert-danger" v-if="!activity.name.required">Print Name</div>
<div v-if="activitiesFromStore[activityId].is_paused" class="alert alert-warning">
Activity is paused
</div>
</td>
<td>
<input type="text" class="form-control" v-model="activity.activity_period.$model">
<div class="alert alert-danger" v-if="!activity.activity_period.required">Print period</div>
<div class="alert alert-danger" v-if="!activity.activity_period.integer || !activity.activity_period.minValue">Period > 0</div>
</td>
<td class="d-flex border-0">
<button #click="activity.$model.is_paused = ! activity.$model.is_paused" class="btn btn-light mr-1" v-bind:class="{ active: !activity.$model.is_paused }">
<span v-if="activity.$model.is_paused">Убрать с паузы</span>
<span v-else>Make pause</span>
</button>
<button #click="updateActivity(activity.$model)" :disabled="
isActivityUpdating || !activitiesChanged(activityId) || !activity.name.required || !activity.activity_period.required || !activity.activity_period.integer || !activity.activity_period.minValue
" type="button" class="btn btn-success mr-1">
<span v-if="isActivityUpdating && activityActed.id == activity.$model.id" class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
Change
</button>
<button #click="deleteActivity(activity.$model)" type="button" class="btn btn-danger">
<span v-if="isActivityDeleting && activityActed.id == activity.$model.id" class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
Delete
</button>
</td>
</tr>
</tbody>
</table>
<div class="collapse" id="collapseExample">
<div class="form-group row">
<div class="col-4">
<label for="newPassword-input">Name</label>
<input v-model="activityToAdd.name" class="form-control">
<div v-if="$v.activityToAdd.period.$dirty && !$v.activityToAdd.name.required" class="alert alert-danger">Print name</div>
</div>
<div class="col-4">
<label for="newPassword-input">Period</label>
<input v-model="activityToAdd.period" class="form-control">
<div class="alert alert-danger" v-if="$v.activityToAdd.period.$dirty && !$v.activityToAdd.period.required">Print period</div>
<div class="alert alert-danger" v-if="(!$v.activityToAdd.period.integer || !$v.activityToAdd.period.minValue)">period > 0</div>
</div>
</div>
<button #click="addActivity" :disabled="!$v.activityToAdd.name.required || !$v.activityToAdd.period.required || !$v.activityToAdd.period.integer || !$v.activityToAdd.period.minValue" type="button" class="btn btn-primary">
<span v-if="isActivityAdding" class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
add
</button>
</div>
</div>
</div>
</div>
</template>
<script>
import {required, minValue, integer} from "vuelidate/lib/validators"
export default {
props: ['initialActivitiesFromStore'],
data() {
return {
activityActed: null,
justEdited: false,
justAdded: false,
justDeleted: false,
activityToAdd:{
name: '',
period: '',
isPaused: ''
}
}
},
computed: {
activitiesFromStore() {
return this.initialActivitiesFromStore
},
activities() {
return JSON.parse(JSON.stringify(this.initialActivitiesFromStore));
},
},
methods: {
activitiesChanged(id) {
if(this.activitiesFromStore[id] && this.activities[id].name == this.activitiesFromStore[id].name && this.activities[id].activity_period == this.activitiesFromStore[id].activity_period && this.activities[id].is_paused == this.activitiesFromStore[id].is_paused)
return false;
else
return true
},
updateActivity(activity){
this.activityActed = activity;
this.$store.dispatch('activities/updateActivity', activity).then(
() => {
if (this.hasError) {
console.log(this.error)
} else {
this.justEdited = true;
// still the same
console.log(this.$store.getters['activities/getRunningActivities']);
}
}
);
},
},
validations: {
activities: {
$each: {
name: {
required,
},
activity_period: {
required,
integer,
minValue: minValue(0)
},
is_paused: {
required,
},
}
},
}
}
</script>
The problem was that I did not follow the vue specification about modification of an array. I used vm.items[indexOfItem] = newValue which is not reactive.