[
{
"address": "213 Marlon Forks\nSouth Corineland, HI 81723-1044",
"lat": "10.30431500",
"lng": "123.89035500"
},
{
"address": "1291 Stephania Road\nLake Dorotheastad, TN 82682-76",
"lat": "10.30309100",
"lng": "123.89154500"
},
{
"address": "20330 Schmeler Course Apt. 210\nNorth Ari, NV 70048",
"lat": "10.30356400",
"lng": "123.89964100"
}
]
I have this data. and from this template
<v-list two-line v-for="(address,index) in addresses" :key="index">
<delivery-address :address="address" :index="index"></delivery-address>
</v-list>
This is my Address.vue file
<template>
<div>
<v-list-tile :key="id">
<v-list-tile-content>
<v-list-tile-title>{{ geocodedAddress }}</v-list-tile-title>
<v-list-tile-sub-title>{{ address.address }}</v-list-tile-sub-title>
</v-list-tile-content>
</v-list-tile>
<v-divider inset></v-divider>
</div>
</template>
on that {{ geocodedAddress }} is a computed property that returns the geocoded address which means if I have those lat,lngs it would display the reverse geocoded address
https://developers.google.com/maps/documentation/javascript/examples/geocoding-reverse
geocodedAddress(){
return _.map(this.address, function (addr){
let geocoder = new google.maps.Geocoder() ;
var latLng = {
lat : parseFloat(addr.lat),
lng : parseFloat(addr.lng)
}
return new Promise(function (resolve, reject) {
geocoder.geocode({'address': latLng}, function (results, status) {
if (status === google.maps.GeocoderStatus.OK) {
latLong.latitude = results[0].geometry.location.lat();
latLong.longitude = results[0].geometry.location.lng();
} else {
reject(status);
}
});
});
});
},
Related
What I want to come true
I am creating TodoLists.
I tried to implement the following editing features, but it didn't work and I'm having trouble.
Click the edit button to display the edit text in the input field
If you click the save button after entering the changes in the input field, the changes will be reflected in the first position.
Code
<v-row v-for="(todo,index) in todos" :key="index">
<v-text-field
filled
readonly
:value="todo.text"
class="ma-3"
auto-grow
/>
<v-menu
top
rounded
>
<template #activator="{ on, attrs }">
<v-btn
v-bind="attrs"
icon
class="mt-6"
v-on="on"
>
<v-icon>
mdi-dots-vertical
</v-icon>
</v-btn>
</template>
<v-list>
<v-list-item
link
>
<v-list-item-title #click="toEdit(todos)">
<v-icon>mdi-pencil</v-icon>
Edit
</v-list-item-title>
</v-list-item>
</v-list>
<v-list>
<v-list-item
link
>
<v-list-item-title #click="removeTodo(todo)">
<v-icon>mdi-delete</v-icon>
Delete
</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</v-row>
<v-text-field
v-model="itemText"
filled
color="pink lighten-3"
auto-grow
#keyup.enter="addTodo"
/>
<v-btn
:disabled="disabled"
#click="addTodo"
>
Save
</v-btn>
data () {
return {
editIndex: false,
hidden: false,
itemText: '',
items: [
{ title: 'Edit', icon: 'mdi-pencil' },
{ title: 'Delete', icon: 'mdi-delete' }
]
}
},
computed: {
todos () {
return this.$store.state.todos.list
},
disabled () {
return this.itemText.length === 0
}
},
methods: {
addTodo (todo) {
if (this.editIndex === false) {
this.$store.commit('todos/add', this.itemText)
this.itemText = ''
} else {
this.$store.commit('todos/edit', this.itemText, todo)
this.itemText = ''
}
},
toEdit (todo) {
this.editIndex = true
this.itemText = this.todos
},
removeTodo (todo) {
this.$store.commit('todos/remove', todo)
}
}
}
</script>
export const state = () => ({
list: []
})
export const mutations = {
add (state, text) {
state.list.push({
text
})
},
remove (state, todo) {
state.list.splice(state.list.indexOf(todo), 1)
},
edit (state, text, todo) {
state.list.splice(state.list.indexOf(todo), 1, text)
}
}
Error
Click the edit button and it will look like this
What I tried myself
//methods
toEdit (todo) {
this.editIndex = true
this.itemText = this.todos.text //add
},
// Cannot read property 'length' of undefined
For some reason I get an error that I couldn't see before
The properties/data types in your code are a bit mixed up.
Here you're accessing state.todos.list...
todos () {
return this.$store.state.todos.list
},
...but in your store the const state doesn't include todos:
export const state = () => ({
list: []
})
Furthermore, you're writing to itemText the content of todos, which should be a string but actually is an object - which leads to the output of [object Object].
toEdit (todo) {
this.editIndex = true
this.itemText = this.todos
},
Also, please check out kissu's comment about the mutations.
I am developing a recipe app. At my CreateRecipe component, I have child component to add ingredients to the recipe or edit existing ingredients. Ill start by showing the code and what i want to achieve and then the problem
Parent component:
<template>
...
<v-dialog v-model="AddIgredientsDialog" max-width="800px">
<template v-slot:activator="{ on, attrs }">
<v-btn color="secondary" dark v-bind="attrs" v-on="on">
Add addIngredients
</v-btn>
</template>
<AddItemsForm
#addIngredient="SaveNewIgredient"
:newIngredientsItem="editedIgredient"
/>
</v-dialog>
</template>
<script>
import AddItemsForm from "./AddItemsForm"; //Child Component
data: () => ({
AddIgredientsDialog:false,
article: {
headline: "",
img: "",
content: "",
subHeader: "",
description: "",
igredients: [], //List to add/edit item at AddItemsForm child component
preperation: []
},
editedIgredient: { //Item to use for editing or adding new item to article.igredients
title: "",
subIgredients: []
},
defaultItem: { //Item used for resetting editedIgredient item
title: "",
subIgredients: []
},
editedIndex: -1, helper variable for knowing whether i need to add new item or edit exiting item
}),
methods:{
editIngredients(item) {
this.editedIndex = this.article.igredients.indexOf(item);
this.editedIgredient = Object.assign({}, item);
this.AddIgredientsDialog = true;
},
SaveNewIgredient(newItem) { //Triggered on #click of save button at child component New item is the
//item passed from children
if (this.editedIndex > -1) {
this.editedIgredient = Object.assign({}, newItem);
Object.assign(
this.article.igredients[this.editedIndex],
this.editedIgredient
);
} else {
this.article.igredients.push(this.editedIgredient);
}
this.AddIgredientsDialog = false;
this.$nextTick(() => {
this.editedIgredient = Object.assign({}, this.defaultItem);
this.editedIndex = -1;
});
},
}
</script>
Child Component:
<template>
<v-card>
<v-card-title>
<span class="headline">Add Ingredients</span>
</v-card-title>
<v-card-text>
<v-text-field v-model="newIngredientsItem.title" placeholder="כותרת">
</v-text-field>
<v-row align="center">
<v-col sm="11">
<v-text-field
v-model="newIgredient"
placeholder="New Igredient"
#keyup.enter="addNewIgredient"
>
</v-text-field>
</v-col>
<v-col sm="1">
<v-btn icon #click="addNewIgredient">
<v-icon>
mdi-plus
</v-icon>
</v-btn>
</v-col>
<v-col class="mt-0 pt-0" cols="12">
<v-row no-gutters>
<v-col cols="12">
<v-card flat tile>
<template
v-for="(item, index) in newIngredientsItem.subIgredients"
>
<v-list-item :key="index" class="mr-0 pr-0">
<v-list-item-content>
<v-list-item-title>
<v-edit-dialog #click.native.stop>
{{ item }}
<v-text-field
slot="input"
v-model="newIngredientsItem.subIgredients[index]"
></v-text-field>
</v-edit-dialog>
</v-list-item-title>
</v-list-item-content>
<v-list-item-action>
<v-btn icon #click="removeIgredient(index)">
<v-icon small>
mdi-delete
</v-icon>
</v-btn>
</v-list-item-action>
</v-list-item>
<v-divider
v-if="index + 1 < newIngredientsItem.subIgredients.length"
:key="item + index"
></v-divider>
</template>
</v-card>
</v-col>
</v-row>
</v-col>
</v-row>
</v-card-text>
<v-card-actions>
<v-btn color="primary" #click="AddIngredients">
Save
</v-btn>
</v-card-actions>
</v-card>
</template>
<script>
export default {
props: {
newIngredientsItem: {
type: Object,
default() {
return {
title: "",
subIgredients: [ ]
};
}
}
},
data: () => ({
newIgredient: ""
}),
methods: {
addNewIgredient() {
this.newIngredientsItem.subIgredients.push(this.newIgredient);
this.newIgredient = "";
},
AddIngredients() {
this.$emit("addIngredient", this.newIngredientsItem);
},
removeIgredient(index) {
this.newIngredientsItem.subIgredients.splice(index, 1);
}
}
};
</script>
My Problem:
At the moment im only trying to use the SaveNewIgredient() method.
After 1st time of adding item the item is added as it should and the parent defaultItem state remain as is which is good:
defaultItem: {
title: "",
subIgredients: []
},
After adding a second item the defaultItem changes and takes the editedItem properties.
For example if i add at the second time
{
title:'Test 1',
subIgredients: [
'Test 1 - 1',
'Test 1 - 2',
'Test 1 - 3',
]
}
That is what the defaultItem will be and then this assignment causes a bug
this.editedIgredient = Object.assign({}, this.defaultItem);
because editedItem should be:
{
title: "",
subIgredients: []
}
I tried to solve your problem. To do this I modified and in some places simplified your code to keep only what was close to the SaveNewIgredient() function. So here is my code.
Parent Component (for me App.vue):
<template>
<AddItemsForm #addIngredient="SaveNewIgredient" />
</template>
<script>
import AddItemsForm from "./AddItemsForm"; //Child Component
export default {
name: "App",
components: { AddItemsForm },
data() {
return {
article: {
igredients: [], //List to add/edit item at AddItemsForm child component
},
editedIgredient: {
//Item to use for editing or adding new item to article.igredients
title: "",
subIgredients: [],
},
defaultItem: {
//Item used for resetting editedIgredient item
title: "",
subIgredients: [],
},
};
},
methods: {
SaveNewIgredient(newItem) {
console.log("Received: ", newItem);
this.editedIgredient = newItem;
this.article.igredients.push({ ...this.editedIgredient });
console.log("defaultClear: ", this.defaultItem);
console.log("infoItem: ", this.editedIgredient);
this.editedIgredient = this.defaultItem;
console.log("defaultClear: ", this.defaultItem);
console.log("editedWillClear: ", this.editedIgredient);
console.log("listFinal: ", this.article.igredients);
},
},
};
</script>
Child Component (for me AddItemsForm.vue):
<template>
<div>
<input v-model="newIgredient" placeholder="New Igredient" />
<button #click="addNewIgredient">ADD</button>
<div>
<button color="primary" #click="AddIngredients">Save</button>
</div>
</div>
</template>
<script>
export default {
props: {
IngredientsItem: {
type: Object,
default() {
return {
title: "",
subIgredients: [],
};
},
},
},
data() {
return {
newIgredient: "",
title: "TEST",
titleNbr: 0,
resetIgredient: false,
};
},
computed: {
newIngredientsItem() {
return this.IngredientsItem;
},
},
methods: {
addNewIgredient() {
if (this.resetIgredient === true) {
this.newIngredientsItem.subIgredients = [];
}
this.newIngredientsItem.subIgredients.push(this.newIgredient);
this.newIgredient = "";
this.resetIgredient = false;
console.log("ADD: ", this.newIngredientsItem.subIgredients);
},
AddIngredients() {
this.newIngredientsItem.title = this.title + this.titleNbr;
this.titleNbr++;
console.log("EMIT: ", this.newIngredientsItem);
this.$emit("addIngredient", this.newIngredientsItem);
this.resetIgredient = true;
},
},
};
</script>
Im a noob in vuejs and i want to pass some data : profile that you can find inside of created() into
<span v-if="isLoggedIn">{{this.profile.username}}</span>
I know i'm missing some basics behind how vue works but im still learnig:)
<template>
<v-card class="mx-auto" color="dark" dark>
<div>
<v-app-bar clipped-left dark app>
<v-app-bar-nav-icon class="grey--text" #click="drawer= !drawer"></v-app-bar-nav-icon>
<v-toolbar-title class="grey--text">
<span class="font-weight-light">anime</span>
<span>Art</span>
</v-toolbar-title>
<v-spacer></v-spacer>
<span v-if="isLoggedIn">hi{{profile.username}}</span>
<v-btn icon>
<v-icon>mdi-heart</v-icon>
</v-btn>
<v-btn icon to="/login">
<v-icon>mdi-account-outline</v-icon>
</v-btn>
<v-btn icon v-if="isLoggedIn">
<v-icon v-on:click="logout">mdi-logout-variant</v-icon>
</v-btn>
</v-app-bar>
</div>
<v-navigation-drawer app expand-on-hover clipped v-model="drawer">
<v-divider></v-divider>
<v-list nav>
<v-list-item v-for="item in items" :key="item.title" :to="item.path" link>
<v-list-item-icon>
<v-icon>{{ item.icon }}</v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title>{{ item.title }}</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list>
</v-navigation-drawer>
</v-card>
</template>
<script>
import firebase from "firebase";
// import db from "#/Firebase/firebaseInit";
export default {
data() {
return {
profile: {},
name: "navbar",
isLoggedIn: false,
currentUser: false,
drawer: false,
items: [
{ title: "Anime Home", icon: "mdi-view-dashboard", path: "/" },
{
title: "Trends",
icon: "mdi-chart-line-stacked",
path: "/trends"
},
{ title: "Save", icon: "mdi-bookmark", path: "/save" },
{
title: "Profile",
icon: "mdi-badge-account-horizontal",
path: "/profile"
},
{ title: "About", icon: "mdi-label", path: "/about" }
],
right: null
};
},
created() {
this.profile = {username:'hello'}
var user = firebase.auth().currentUser;
// var name, email,uid;
//, photoUrl, emailVerified
if (user != null) {
this.isLoggedIn = true;
this.profile = {
username: user.displayName,
useremail: user.email,
userid: user.uid,
photoUrl: user.photoURL,
emailVerified: user.emailVerified
};
console.log(profile.username);
// The user's ID, unique to the Firebase project. Do NOT use
// this value to authenticate with your backend server, if
// you have one. Use User.getToken() instead.
}
// console.log(user)
},
methods: {
logout: function() {
firebase
.auth()
.signOut()
.then(function() {
// Sign-out successful.
if (!firebase.auth().currentUser) {
alert("Signed out successfuly ");
}
})
.catch(function(error) {
// An error happened.
alert(error.message);
});
this.isLoggedIn = false;
this.$router.go({ path: this.$router.path });
}
}
};
</script>
in your html :
<span v-if="isLoggedIn">{{profile.username}}</span>
in your script
<script>
import firebase from "firebase";
export default {
data() {
return {
profile: {},
//all your stuff
},
created() {
var user = firebase.auth().currentUser;
if (user != null) {
this.isLoggedIn = true;
this.profile = {
username:user.displayName,
useremail :user.email,
userid:user.uid,
photoUrl : user.photoURL,
emailVerified: user.emailVerified
}
}
// console.log(user)
},
methods: {//all your stuff }
};
</script>
I haven't found a question that addresses this problem using vuetify/vue.
I have a dynamic table, and on that page is an add item button. Clicking button pops up a dialog with anther dynamic table. I want to be able to click an add icon for each specific table row. Clicking the icon would move it to the original dynamic table.
I tried using something similar to the delete row function. I ended up getting two empty rows added, with the error " Invalid prop: type check failed for prop "item". Expected Object, got Number with value 0"
Here is what I have that creates that error.
HTML
<v-data-table
:headers="headers"
:items="agents"
sort-by="calories"
class="elevation-1"
>
<template v-slot:top>
<v-toolbar flat color="white">
<v-spacer></v-spacer>
<v-dialog v-model="dialog" max-width="800px">
<template v-slot:activator="{ on }">
<v-btn color="primary" dark class="mb-2" v-on="on">Add Agent</v-btn>
</template>
<v-card>
<v-card-title>
<span class="headline">New Agent</span>
</v-card-title>
<v-data-table :headers="headers2" :items="newAgents">
<template v-slot:item.action="{ item }">
<v-icon small #click="addItem(item)">
mdi-plus-circle-outline
</v-icon>
</template>
</v-data-table>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="blue darken-1" text #click="close">Cancel</v-btn>
<v-btn color="blue darken-1" text #click="save">Save</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</v-toolbar>
</template>
<template v-slot:item.action="{ item }">
<v-icon small #click="deleteItem(item)">
mdi-delete
</v-icon>
</template>
<template v-slot:no-data>
<v-btn color="primary" #click="initialize">Reset</v-btn>
</template>
import axios from "axios";
export default {
data: () => ({
dialog: false,
isLoading: true,
headers: [
{ text: "Host IP Address", value: "host_ip" },
{ text: "Hostname", value: "host_name" },
{ text: "Agent Version", value: "agent_version" },
{ text: "Agent Install Location", value: "install_location" },
{ text: "Agent Status", value: "agent_status" },
{ text: "Actions", value: "action", sortable: false }
],
headers2: [
{ text: "Host IP Address", value: "host_ip" },
{ text: "Hostname", value: "host_name" },
{ text: "Agent Version", value: "agent_version" },
{ text: "Agent Install Location", value: "install_location" },
{ text: "Agent Status", value: "agent_status" },
{ text: "Add", value: "action", sortable: false }
],
agents: [],
newAgents: []
}),
watch: {
dialog(val) {
val || this.close();
}
},
created() {
this.initialize();
axios
.get("https://my.api.mockaroo.com/add_new_agent.json?key=88c9bdc0")
.then(res => (this.newAgents = res.data))
.then(res => {
console.log(res);
})
.catch(err => console.log(err));
},
methods: {
initialize() {
this.agents = [
{
host_ip: "Frozen Yogurt",
host_name: 159,
agent_version: 6.0,
install_location: 24,
agent_status: 4.0
},
{
host_ip: "Ice cream sandwich",
host_name: 237,
agent_version: 9.0,
install_location: 37,
agent_status: 4.3
}
];
},
changeColor() {
this.isLoading = !this.isLoading;
},
deleteItem(item) {
const index = this.agents.indexOf(item);
confirm("Are you sure you want to delete this item?") &&
this.agents.splice(index, 1);
},
addItem(item) {
const index = this.newAgents.indexOf(item);
confirm("Are you sure you want to add this item?") &&
this.agents.push(index, 1);
},
close() {
this.dialog = false;
setTimeout(() => {
this.editedItem = Object.assign({}, this.defaultItem);
this.editedIndex = -1;
}, 300);
},
save() {
if (this.editedIndex > -1) {
Object.assign(this.agents[this.editedIndex], this.editedItem);
} else {
this.agents.push(this.editedItem);
}
this.close();
}
}
}
I need to add a function to pull the id from the row. then use that id to push the row into another array.
added:
addItem(item) {
this.newAgentId(item.id);
console.log(item);
confirm("Are you sure you want to add this item?") &&
this.agents.push(item);
},
newAgentId(keyID) {
if (this.selectedRows.includes(keyID)) {
this.selectedRows = this.selectedRows.filter(
selectedKeyID => selectedKeyID !== keyID
);
} else {
this.selectedRows.push(keyID);
}
}
I have a vuetify select (v-select):
<v-select prepend-icon="local_shipping" :rules="[v => !!v || 'Es necesario asignarl el T.A.R.']" required label="T.A.R." v-model="editedItem.tarID" :items="tars" item-text="nombre" item-value="id"></v-select>
What i want to do is get the value of the id in edit mode, that is, in this way:
I have been following the official documentation of vuetify to edit an item of a table in a modal dialog.
Just as the inputs have assigned text, I would also like the select to have its assigned data.
Here is what i have:
The edit button:
<v-btn icon class="mx-0" #click="editItem(props.item)">
<v-icon color="info">mode_edit</v-icon>
</v-btn>
The editedItem and the defaultItem, just like the official documentation:
editedItem: {
entidadID: "",
numeroEstacion: "",
tarID: "",
clave: "",
id:""
},
defaultItem: {
entidadID: "",
numeroEstacion: "",
tarID: "",
clave: "",
id: ""
},
The way in which i populate the v-select in data:
tars: [
{
id: "",
nombre: ""
}
],
I populate my tables like this:
<v-data-table
:headers="headers"
:items="items"
hide-actions
class="slideInDown"
:search="search"
:id="items.id"
>
<template slot="items" slot-scope="props">
<td>{{ props.item.grupo }}</td>
<td class="text-xs-right">{{ props.item.numeroEstacion}}</td>
<td class="text-xs-right">{{ props.item.clave }}</td>
<td class="text-xs-right">{{ props.item.nombre }}</td>
<td class="text-xs-right">{{props.item.id}}</td>
<td class="justify-center layout px-0">
<v-btn icon class="mx-0" #click="editItem(props.item)">
<v-icon color="info">mode_edit</v-icon>
</v-btn>
<v-btn icon class="mx-o" #click="deleteItem(props.item)">
<v-icon color="red">delete_sweep</v-icon>
</v-btn>
</td>
</template>
<v-alert slot="no-results" :value="true" color="error" icon="warning">
Tu búsqueda para "{{search}}" no arrojó resultados.
</v-alert>
</v-data-table>
And the editItem button:
editItem(item) {
this.editedIndex = this.items.indexOf(item);
this.editedItem = Object.assign({}, item);
this.dialog = true;
},
The editedIndex equals -1 in data return. So when i touch New Item button editedIndex = -1, when i touch The edit button, editedIndex != -1, like the documentation
The link of the official documentation:
https://vuetifyjs.com/en/components/data-tables
Here is my PUT method:
if(this.editedIndex > -1){
axios({
headers:{
"Authorization": "Bearer "+localStorage.getItem('token')
},
method: "put",
url: "http://localhost:58209/api/PutEstacion",
data:{
NumeroEstacion: this.editedItem.numeroEstacion,
Clave: this.editedItem.clave,
**TarID: this.editedItem.tarID**,
ID: this.editedItem.id,
}
}).then(response => {
console.log(response);
this.snackbar = true;
this.textSnackbar = "La información ha sido actualizada correctamente";
this.dialog = false
}).catch(error =>{
console.log(error.response);
this.snackbar = true;
this.textSnackbar = "Lo sentimos ha ocurrido un problema actualizando la informacíón";
this.dialog = false
});
}
This line: TarID: this.editedItem.tarID has no value. So i can't put in my WebApi. And finally my WbApi:
var ID = _context.Estacion.Where(x => x.ID == putEstacionDTO.ID).Select(x => x.ID).FirstOrDefault();
var NumeroEstacion = putEstacionDTO.NumeroEstacion;
var Clave = putEstacionDTO.Clave;
var TarID = putEstacionDTO.TarID;
var putEstacion = _context.LoadStoredProc("PutEstaciones")
.WithSqlParam("p0", NumeroEstacion)
.WithSqlParam("p1", Clave)
.WithSqlParam("p2", TarID)
.WithSqlParam("p3", ID)
.ExecuteStoredProc<PutEstacionDTO>();
return Ok();
When i debugging only the 'select' = 0 (TarID).
EDIT, Add the :items="items" of datatable
Data:
items: [
{
id: "",
grupo: "",
numeroEstacion: "",
clave: "",
nombre: "",
}
],
Method to set the items:
axios
.get("http://localhost:58209/api/GetEstaciones", {
headers: {
Authorization: "Bearer " + localStorage.getItem("token")
}
})
.then(response => {
console.log(response);
this.items = response.data;
this.snackbar = true;
this.textSnackbar = "Se han cargado correctamente las estaciones";
})
.catch(error => {
console.log(error.response);
this.snackbar = true;
this.textSnackbar =
"Lo sentimos, no pudimos cargar la información de los tanques";
});