Edit post in vue js, axios, django - javascript

I start coding in vuetify and want to make Edit button who get the data of selected id, response selected post from axios and transfer it to another components.
I trying props but its not working here, or i do something wronk with it.
There is my List and Edit components:
<template>
<v-container>
<v-row>
<v-col cols="12">
<v-list shaped>
<v-list-item-group color="deep-purple" v-model="selected" multiple>
<v-list-item v-for="item in todoList" :key="item.id">
<v-list-item-icon>
{{ item.id }}
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title>
<strong>{{ item.title }}</strong>
</v-list-item-title>
</v-list-item-content>
<v-btn fab dark small color="purple">
<v-icon dark #click="Edit()"> mdi-pencil </v-icon>
</v-btn>
</v-list-item>
</v-list-item-group>
</v-list>
</v-col>
</v-row>
</v-container>
</template>
<script>
import axios from "axios";
export default {
name: "BookList",
data: () => ({
selected: [],
todoList: [],
}),
mounted() {
this.getTodos();
},
methods: {
getTodos() {
axios.get("http://127.0.0.1:8000/api/todo/").then((response) => {
this.todoList = response.data;
});
},
Edit() {
this.$emit("title", this.item.title);
},
},
};
</script>
<template>
<v-container>
<v-row>
<v-col cols="12">
<v-form>
<v-text-field
v-model="this.title"
:counter="64"
label="title"
required
></v-text-field>
</v-form>
</v-col>
<v-btn #click="edit" color="success" class="mr-4"> Edit </v-btn>
</v-row>
</v-container>
</template>
<script>
export default {
data: () => {
return {
title: this.title,
};
},
components: {},
mounted() {},
methods: {},
};
</script>
but i stuck. I think i do somethink wrong with Emit medo but dont know what. Can u give some hint what to do?

Related

Vue prop is sent from a component is undefined

I have a Kanban board inside my dashboard which displays issues of a project. I added a menu to allow the user to filter the kanban board by project such that only one project's issue are visible at once. The default view is the issues of all the projects.
In my Dashboard component, I get the list of all projects from a server using axios (which works correctly).
When a user chooses a project, I send to the Kanban board component a prop which is the project id so that I can fetch that project's issues from the server.
However, the prop I'm sending from Dashboard is undefined somehow, and I cannot figure out why
Dashboard.vue
<template>
<v-container>
<v-row class="my-1">
<v-col cols="3">
<h2 style="font-size:40px;color:rgb(92, 92, 92)">Kanban Board</h2>
</v-col>
<v-col cols="7"></v-col>
<v-col cols="2">
<v-menu offset-y>
<template v-slot:activator="{ on, attrs }">
<v-btn color="primary" dark v-bind="attrs" v-on="on">
View
</v-btn>
</template>
<v-list>
<v-list-item v-for="(project, index) in ProjectList" :key="index">
<v-list-item-title #click="changeView(project.id)">{{ project.title }}</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</v-col>
</v-row>
<v-row>
<KanBanBoard :projectid="project_id"></KanBanBoard>
</v-row>
</v-container>
</template>
<script>
import KanBanBoard from './KanBanBoard.vue'
import { mapGetters, mapActions } from 'vuex'
export default {
components: {
KanBanBoard,
},
data() {
return {
project_id: '',
}
},
computed: {
...mapGetters(['ProjectList']),
},
methods: {
...mapActions(['getProjectList']),
changeView(project_id) {
this.project_id = project_id
},
},
created() {
this.getProjectList()
},
}
</script>
<style scoped>
.view {
font-size: 20px;
}
</style>
NavBar.js (Vuex file Dashboard uses to get the list of projects)
import axios from 'axios'
const state = {
Projects: [],
ProjectsIssuesList: []
}
const getters = {
ProjectList: (state) => state.Projects,
ProjectIssuesList: (state) => state.ProjectsIssuesList
}
const actions = {
async getProjectList({ commit }) {
var projectList = []
var issuesList = []
await axios
.get('https://fadiserver.herokuapp.com/api/v1/my-projects/')
.then(response => {
projectList = response.data
for (let i = 0; i < projectList.length; i++) {
let projectid = projectList[i].id
axios
.get('https://fadiserver.herokuapp.com/api/v1/my-issues-titles/?projectid=' + projectid)
.then(response => {
issuesList.push(response.data)
})
.catch(error => {
console.log(error)
})
}
})
.catch(error => {
console.log(error)
})
commit('setProjects', projectList),
commit('setProjectsIssues', issuesList)
},
}
const mutations = {
setProjects: (state, Projects) => (state.Projects = Projects),
setProjectsIssues: (state, ProjectsIssuesList) => (state.ProjectsIssuesList = ProjectsIssuesList)
}
export default {
state,
getters,
actions,
mutations
}
KanBanBoard.vue
<template>
<v-container>
<v-row wrap>
<v-col xl="4" lg="4" md="4" sm="4" xs="12">
<v-card>
<v-card-title class="blue lighten-3">
<span class="white--text">Open</span>
</v-card-title>
<v-divider horizontal></v-divider>
<v-card-text class="blue lighten-3">
<draggable class="list-group kanban-column" :list="Open" group="tasks">
<v-card
class="#f4f5fa"
style="height:auto; margin-top:10px"
v-for="issue in Open"
:key="issue"
align-center
elevation="3"
>
<v-card-text>
<v-row dense style="width:auto">
<router-link
class="d-flex align-center text-decoration-none grey--text"
style="font-size:18px;"
:to="{ name: 'IssuePage', params: { id: issue.id, issue } }"
>
{{ issue.title }}
</router-link>
</v-row>
<v-row dense>
<v-col>
<v-chip
class="ma-2"
color="red"
outlined
style="position:relative; right:10px;top:10px; height:min-content"
>
{{ issue.issueSeverity }}
</v-chip>
</v-col>
<v-col>
<v-chip
class="ma-2"
color="green"
outlined
style="position:relative; right:83px; top:10px;height:min-content"
>
{{ issue.issueType }}
</v-chip>
</v-col>
</v-row>
</v-card-text>
</v-card>
</draggable>
</v-card-text>
</v-card>
</v-col>
<v-col xl="4" lg="4" md="4" sm="4" xs="12">
<v-card>
<v-card-title class="light-green lighten-3">
<span class="white--text">In Progress</span>
</v-card-title>
<v-divider horizontal></v-divider>
<v-card-text class="light-green lighten-3">
<draggable class="list-group kanban-column" :list="InProgress" group="tasks">
<v-card
class="#f4f5fa"
style="height:auto; margin-top:10px"
v-for="issue in InProgress"
:key="issue"
align-center
elevation="3"
>
<v-card-text>
<v-row dense style="width:auto">
<router-link
class="d-flex align-center text-decoration-none grey--text"
style="font-size:18px;"
:to="{ name: 'IssuePage', params: { id: issue.id, issue } }"
>
{{ issue.title }}
</router-link>
</v-row>
<v-row>
<v-col>
<v-chip
class="ma-2"
color="red"
outlined
style="position:relative; right:10px;top:10px; height:min-content"
>
{{ issue.issueSeverity }}
</v-chip>
</v-col>
<v-col>
<v-chip
class="ma-2"
color="green"
outlined
style="position:relative; right:83px; top:10px;height:min-content"
>
{{ issue.issueType }}
</v-chip>
</v-col>
</v-row>
</v-card-text>
</v-card>
</draggable>
</v-card-text>
</v-card>
</v-col>
<v-col xl="4" lg="4" md="4" sm="4" xs="12">
<v-card>
<v-card-title class="orange lighten-3">
<span class="white--text">Completed</span>
</v-card-title>
<v-divider horizontal></v-divider>
<v-card-text class="orange lighten-3">
<draggable class="list-group kanban-column" :list="Completed" group="tasks">
<v-card
class="#f4f5fa"
style="height:auto; margin-top:10px"
v-for="issue in Completed"
:key="issue"
align-center
elevation="3"
>
<v-card-text>
<v-row dense style="width:auto">
<router-link
class="d-flex align-center text-decoration-none grey--text"
style="font-size:18px;"
:to="{ name: 'IssuePage', params: { id: issue.id, issue } }"
>
{{ issue.title }}
</router-link>
</v-row>
<v-row dense>
<v-col>
<v-chip
class="ma-2"
color="red"
outlined
style="position:relative; right:10px;top:10px; height:min-content"
>
{{ issue.issueSeverity }}
</v-chip>
</v-col>
<v-col>
<v-chip
class="ma-2"
color="green"
outlined
style="position:relative; right:83px; top:10px;height:min-content"
>
{{ issue.issueType }}
</v-chip>
</v-col>
</v-row>
</v-card-text>
</v-card>
</draggable>
</v-card-text>
</v-card>
</v-col>
</v-row>
</v-container>
</template>
<script>
import draggable from 'vuedraggable'
import { mapGetters, mapActions } from 'vuex'
export default {
props: ['project_id'],
components: {
draggable,
},
computed: {
...mapGetters(['Open']),
...mapGetters(['InProgress']),
...mapGetters(['Completed']),
},
watch: {
projectid() {
this.fetchIssuesofProject(this.project_id)
this.test()
},
},
methods: {
...mapActions(['fetchIssuesofProject']),
test() {
console.log(this.projectid)
},
},
created() {
this.test(), this.fetchIssuesofProject(this.project_id)
},
}
</script>
<style scoped>
hr {
margin-top: 0.1px;
margin-bottom: 0.1px;
border: 1;
border-top: 1px solid rgba(0, 0, 0, 0.1);
}
</style>
Kanban.js
import axios from 'axios'
const state = {
Issues: [],
}
const getters = {
Open: (state) => state.Issues.filter(x => x.issueStatus == 'Open'),
InProgress: (state) => state.Issues.filter(x => x.issueStatus == 'In Progress'),
Completed: (state) => state.Issues.filter(x => x.issueStatus == 'Closed'),
}
const actions = {
async fetchIssuesofProject({ commit }, projectid) {
const response = await axios.get('https://fadiserver.herokuapp.com/api/v1/my-issues-titles/?projectid=' + projectid).catch(error => {
console.log("The error is here")
})
commit('setIssues', response.data)
}
}
const mutations = {
setIssues: (state, Issues) => (state.Issues = Issues)
}
export default {
state,
getters,
actions,
mutations
}```
Probably it's because in KanBanBoard.vue you defined your prop as project_id and in Dashboard.vue you're passing it like this:
<KanBanBoard :projectid="project_id"></KanBanBoard>
instead do:
<KanBanBoard :project_id="project_id"></KanBanBoard>

How can I remove other values ​based on the value I selected?

When using Vuetify v-autocomplete component and using the prop multiple we can multi select values.
How can I remove other values ​​based on the value I selected?
For example:
When I select the main value, the others will be selected removed.Then, when I select the first value, the main value and other values ​​will be deselected. Then when I select the third and others (the third and below are in the same group) the selected main and first value will be selected removed.
<div id="app">
<v-app>
<v-main>
<v-container>
<template>
<v-card color="blue-grey darken-1" dark>
<v-form>
<v-container>
<v-row>
<v-col cols="5">
<v-autocomplete
v-model="parametres"
:items="people"
filled
chips
color="blue-grey lighten-2"
label="Liste"
item-text="name"
item-value="name"
multiple
>
<template v-slot:selection="data">
<v-chip
v-bind="data.attrs"
:input-value="data.selected"
close
#click="data.select"
#click:close="remove(data.item)"
>
{{ data.item.name }}
</v-chip>
</template>
<template v-slot:item="data">
<template v-if="typeof data.item !== 'object'">
<v-list-group>
<v-list-item-content
v-text="data.item"
></v-list-item-content>
</template>
<template v-else>
<v-list-item-content>
<v-list-item-title
v-html="data.item.name"
></v-list-item-title>
</v-list-item-content>
</v-list-group>
</template>
</template>
</v-autocomplete>
</v-col>
</v-row>
</v-container>
</v-form>
<v-divider></v-divider>
</v-card>
</template>
</v-container>
</v-main>
</v-app>
</div>
<script>
new Vue({
el: "#app",
vuetify: new Vuetify(),
data() {
return {
selected: ["name"],
autoUpdate: true,
parametres: ["Main Select"],
people: [
{ name: "Main Select"},
{ name: "First Select"},
{ name: "Second Select"},
{ name: "Third Select."},
{ name: "Fourth Select."},
{ name: "Fifth Select."},
],
model: 1,
};
},
methods: {
remove(item) {
const index = this.parametreler.indexOf(item.name);/*Chip Remove */
if (index >= 0) this.parametreler.splice(index, 1); /*Chip Remove */
},
},
});
</script>
Hi #sercan you can use the #change events and call method on this event and write your logic within that method.
<div id="app">
<v-app>
<v-main>
<v-container>
<template>
<v-card color="blue-grey darken-1" dark>
<v-form>
<v-container>
<v-row>
<v-col cols="5">
<v-autocomplete v-model="parametres" :items="people" filled chips color="blue-grey lighten-2" label="Liste" item-text="name" item-value="name" multiple :key="index">
<template v-slot:selection="data">
<v-chip v-bind="data.attrs" :input-value="data.selected" close #click="data.select" #click:close="remove(data.item)">
{{ data.item.name }}
</v-chip>
</template>
<template v-slot:item="data">
<template v-if="typeof data.item !== 'object'">
<v-list-group>
<v-list-item-content v-text="data.item">
<span>{{typeof data.item !== 'object'}}</span>
</v-list-item-content>
</template>
<template v-else>
<v-list-item-content #click="updateSelection(data.item.name)">
<v-list-item-title v-html="data.item.name"></v-list-item-title>
</v-list-item-content>
</v-list-group>
</template>
</template>
</v-autocomplete>
</v-col>
</v-row>
</v-container>
</v-form>
<v-divider></v-divider>
</v-card>
</template>
</v-container>
</v-main>
new Vue({
el: "#app",
vuetify: new Vuetify(),
data() {
return {
selected: ["name"],
autoUpdate: true,
parametres: ["Main Select"],
people: [
{ name: "Main Select" },
{ name: "First Select" },
{ name: "Second Select" },
{ name: "Third Select." },
{ name: "Fourth Select." },
{ name: "Fifth Select." }
],
model: 1,
index: 0
};
},
methods: {
updateSelection(name) {
let toRemove = ["Main Select","First Select"];
let temp = event;
console.log(name);
switch (name) {
case "Main Select":
this.parametres = ["Main Select"];
this.index++;
break;
case "First Select":
this.parametres = ["First Select"]
this.index++;
break;
default:
this.parametres = this.parametres.filter( ( el ) => !toRemove.includes( el ) );
}
},
remove(item) {
const index = this.parametreler.indexOf(item.name); /*Chip Remove */
if (index >= 0) this.parametreler.splice(index, 1); /*Chip Remove */
}
}
});

Vue.js: How can I put a Login Modal inside a dropdown Menu?

I have the following dropdown menu:
<template>
<v-menu close-on-click transition="slide-y-transition">
<template v-slot:activator="{ on, attrs }">
<v-btn color="primary" v-bind="attrs" v-on="on">
Menu
</v-btn>
</template>
<v-list>
<v-list-item v-for="(item, index) in menuItemsMisc" :key="index" v-model="item.model">
<v-list-item-title>
<v-btn block color="white" #click="item.fn">{{ item.title }}</v-btn>
</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
<!-- Modal code here -->
</template>
<script>
export default {
name: 'MenuBar',
data: () => ({
loginModal: false,
purchaseModal: false,
menuItemsMisc: [
{ title: 'Login',
model: 'loginModal',
fn: () => { this.loginModal = true}
},
{ title: 'Purchase',
model: 'purchaseModal',
fn: () => { this.purchaseModal = true }
},
]
}),
}
</script>
And I am trying to display this Login Modal When the Login Button is clicked in the dropdown.
<v-dialog v-model="loginModal" persistent max-width="500px">
<v-card class="elevation-12">
<v-toolbar color="primary" dark flat>
<v-toolbar-title>Login form</v-toolbar-title>
<v-spacer></v-spacer>
</v-toolbar>
<v-card-text>
<v-form>
<v-text-field name="login" prepend-icon="mdi-account" type="text"></v-text-field>
<v-text-field id="password" name="password" prepend-icon="mdi-lock" type="password">
</v-text-field>
</v-form>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="primary">Login</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
But whenever I click the Login or Purchase Button, I have an error that says:
TypeError: Cannot set property 'loginModal' of undefined
What is the Problem here?
From the Vue docs on v-model:
You can use the v-model directive to create two-way data bindings on form input, textarea, and select elements. It automatically picks the correct way to update the element based on the input type.
The v-model property on your <v-dialog> component is expecting it to be an input of some type.
You should be able to simply change this to a v-if:
<v-dialog v-if="loginModal" persistent max-width="500px">
This will cause the <v-dialog> component to display when your button is clicked.
EDIT: Please also make sure your data property on the Vue instance is declared as a class-style function. If you use a lambda function you will lose the this scope when referring to this.loginModal:
export default {
...
data() {
return {
...
}
}
}

api data does not appear using VUEX and AXIOS in the VUETIFY app

I'm trying to present the data coming from my API using VUEX and AXIOS, however on my screen nothing appears as shown in the image:
But in console.log the data appears:
In Vue dev tools it appears as follows:
I tried different ways but due to my little experience I was not successful and I would like a help.
Follow my codes:
Clients.vue
<template>
<!-- Inicio do CONTAINER principal -->
<v-container fluid>
<v-row
justify="center"
>
<!-- Inicio do BLOCO principal -->
<v-col
md="9"
xs="12"
>
<nav-bar />
<v-card
class="mx-auto"
flat
height="900"
>
<v-list-item three-line>
<v-list-item-content>
<v-list-item-title class="display-1 font-weight-black">{{ pageName }}</v-list-item-title>
</v-list-item-content>
<!-- Inicio BLOCO button actions -->
<v-card-actions>
<v-spacer></v-spacer>
<v-btn
color="success"
depressed
large
>
New Client
</v-btn>
</v-card-actions>
<!-- Final BLOCO button actions -->
</v-list-item>
<!-- Inicio COMPONENTE TAB -->
<v-card
flat
tile
>
<v-col>
<v-tabs>
<v-tab class="text-capitalize">Search</v-tab>
<v-tab class="text-capitalize">Dashboard</v-tab>
<v-tab-item>
<v-divider></v-divider>
<!-- Início BLOCO Table-->
<v-card
flat
tile
>
<v-col
justify="center"
>
<v-col
md="5"
>
<v-text-field
v-model="search"
append-icon="mdi-magnify"
label="Search"
single-line
outlined
dense
class="pt-3"
></v-text-field>
</v-col>
<v-data-table
:headers="headers"
:items="clients"
:search="search"
></v-data-table>
</v-col>
</v-card>
<!-- Final BLOCO Table-->
</v-tab-item>
</v-tabs>
</v-col>
</v-card>
<!-- Final COMPONENTE TAB -->
</v-card>
</v-col>
<!-- Final do BLOCO principal -->
</v-row>
</v-container>
<!-- Final do CONTAINER principal -->
</template>
<script>
import { mapState} from 'vuex';
const state = mapState(['clients']);
export default {
name: 'Clients',
computed: state,
data: () => ({
pageName: 'Clients',
search: '',
headers: [
{ text: 'Name', value: 'firstName' },
{ text: 'Phone', value: 'phone' },
{ text: 'E-mail', value: 'email' },
],
}),
created () {
this.initialize()
},
methods: {
initialize () {
//console.log(this.$store)
this.$store.dispatch('loadData') // dispatch loading
},
},
}
</script>
store/modules/client.module.js
import axios from 'axios'
const URL = 'http://192.168.15.11:3000/clients';
const client = {
state: () => ({
clients: [],
loading: true
}),
mutations: {
updateClients(state, clients) {
state.clients = clients
},
changeLoadingState(state, loading) {
state.loading = loading
}
},
actions: {
loadData({commit}) {
axios.get(URL).then((response) => {
console.log(response.data, this)
commit('updateClients', response.data)
commit('changeLoadingState', false)
})
}
},
getters: {
//
}
}
export default client;
store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import auth from './modules/auth.module'
import client from './modules/client.module'
Vue.use(Vuex)
export default new Vuex.Store({
modules: {
auth:auth,
client:client,
},
})
Note: The authentication part is working perfectly in this form of store modules

Vuetify Item group how to preselect item?

I am trying to preselect item from vuetify item-group. It works for string but not for objects. In the vuetify document, they have used string array as the item list for the item-group. It works fine.
If I try to use an object array as the item list it doesn't work
<div id="app">
<v-app id="inspire">
<v-card class="mx-auto" max-width="500">
<v-list shaped>
<v-list-item-group v-model="model" multiple>
<template v-for="(item, i) in items">
<v-divider
v-if="!item"
:key="`divider-${i}`"
></v-divider>
<v-list-item
v-else
:key="`item-${i}`"
:value="item"
active-class="deep-purple--text text--accent-4"
>
<template v-slot:default="{ active, toggle }">
<v-list-item-content>
<v-list-item-title v-text="item.name"></v-list-item-title>
</v-list-item-content>
<v-list-item-action>
<v-checkbox
:input-value="active"
:true-value="item"
color="deep-purple accent-4"
#click="toggle"
></v-checkbox>
</v-list-item-action>
</template>
</v-list-item>
</template>
</v-list-item-group>
</v-list>
</v-card>
</v-app>
</div>
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: () => ({
items: [
{ name: "Connect"}
],
model: [{name: "Connect"}]
}),
})
You can implement using unique value from your data, it can be a id or something else. You need to pass you unique value inside of your model in form of Array and then the same unique value should be configure with your <v-list-item>.
Please check code snippet and working Codepen demo.
Code snippet:
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: () => ({
items: [],
model: [1, 3, 6]
}),
methods: {
getValue(item) {
return `${item.id}. - ${item.title.toLocaleUpperCase()}`;
}
},
created: function() {
let self = this;
fetch('https://jsonplaceholder.typicode.com/posts')
.then(response => response.json())
.then(json => self.$data.items = json)
}
});
<div id="app">
<v-app id="inspire">
<v-card class="mx-auto" max-width="100%">
<v-list shaped>
<v-toolbar color="indigo" dark>
<v-toolbar-title>List posts :- jsonplaceholder</v-toolbar-title>
</v-toolbar> <br/>
<v-list-item-group v-model="model" multiple>
<template v-for="(item, i) in items">
<v-divider
v-if="!item"
:key="`divider-${i}`"
></v-divider>
<v-list-item
v-else
:key="`item-${i}`"
:value="item.id"
active-class="deep-purple--text text--accent-4"
>
<template v-slot:default="{ active, toggle }" >
<v-list-item-content>
<v-list-item-title v-text="getValue(item)"></v-list-item-title>
</v-list-item-content>
<v-list-item-action>
<v-checkbox
:input-value="active"
:true-value="item.id"
color="deep-purple accent-4"
#click="toggle"
></v-checkbox>
</v-list-item-action>
</template>
</v-list-item>
</template>
</v-list-item-group>
</v-list>
</v-card>
</v-app>
</div>

Categories

Resources