Vue get id from table row - vue.js

How will I get selected item in this table row. I want When I click on the row its gives me the cowId then I can use it . is there a way i can do this in a very simple way without much modification. then i can send thecowwid to my api via axios for deleting
<div id="ArtificialInsemination" class="container">
<button v-on:click="viewRecords">View Record</button>
<table class="table table-striped">
<thead>
<tr>
<th>Cow Id</th>
<th>Bull Name</th>
<th>Semen Origin</th>
<th>Insemination Time</th>
<th>Pd Delivery Date</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr v-for ="artificialInseminationRecord in artificialInseminationRecords">
<td>{{ artificialInseminationRecord.cowId }}</td>
<td>{{ artificialInseminationRecord.bullUsedName }}</td>
<td>{{ artificialInseminationRecord.semenOrigin }}</td>
<td>{{ artificialInseminationRecord.inseminationTime }}</td>
<td>{{ artificialInseminationRecord.pdStatusDate }}</td>
<td><button v-on:click="DeleteArtificialInseminationRecords" >Delete</button></td>
</tr>
</tbody>
</table>
</div>
this VUE to GET COW ID WHEN a row in a table clicked
<script>
//class initialization
var ArtificialInsemination = new Vue({
el:'#ArtificialInsemination',
data: {
url:'http://localhost/dairyfarm/index.php',
artificialInseminationRecords: [],
cowId: ''
},
//invoke methods
methods: {
viewRecords:function () {
var data = new FormData()
data.append('function','viewRecords')
axios.post(this.url,data)
.then( function (response ) {
this.artificialInseminationRecords = response.data.data
}.bind(this)).catch(function (error) {
})
}, saveInseminationRecords:function () {
var data = new FormData()
data.append('function','saveInseminationRecords')
axios.post(this.url,data)
.then( function (response ) {
this.artificialInseminationRecords = response.data.data
}.bind(this)).catch(function (error) {
})
}, DeleteArtificialInseminationRecords:function () {
this.cowId = 'GET COW ID HERE'
var data = new FormData()
data.append('function','DeleteArtificialInseminationRecords')
data.append('cowId',this.cowId)
axios.post(this.url,data)
.then( function (response ) {
}.bind(this)).catch(function (error) {
})
},
create: function(){
this.viewRecords()
}.bind(this),
}
})
</script>

Complete example. Hope it helps.
const store = new Vuex.Store({
state: {
users: null
},
mutations: {
updateUsers (state, payload) {
state.users = payload
}
},
actions: {
async loadUsers ({commit}, payload) {
var response = await axios.get(payload.src)
commit('updateUsers', response.data )
}
}
})
Vue.component('user-list', {
template: '#user-list',
props: ['src'],
methods: {
removeUser (id) {
alert('You are deleting user id: ' + id)
// axios.delete('https://your.rest.api/users/' + id)
}
},
created () {
this.$store.dispatch('loadUsers', {src: this.src})
}
})
new Vue({
el: '#app',
store
})
table {
border: 1px solid black;
border-collapse: collapse;
}
th, td {
border: 1px solid black;
padding: 3px;
}
td:last-child {
text-align: center;
}
<div id="app">
<user-list src="https://jsonplaceholder.typicode.com/users">
</user-list>
</div>
<template id="user-list">
<table>
<thead>
<tr>
<th>ID</th>
<th>Nick</th>
<th>Full name</th>
<th>Actions</th>
</tr>
</thead>
<tr v-for="user in $store.state.users" :key="user.id">
<td>{{ user.id }}</td>
<td>{{ user.username }}</td>
<td>{{ user.name }}</td>
<td><button #click="removeUser(user.id)">X</button></td>
<tr>
</table>
</template>
<script src="https://unpkg.com/vue#2.5.2/dist/vue.min.js"></script>
<script src="https://unpkg.com/vuex#3.0.0/dist/vuex.min.js"></script>
<script src="https://unpkg.com/axios#0.17.0/dist/axios.min.js"></script>

Related

Cannot iterate the data from an array ref VUEJS

I'm having a slight issue here when i try to iterate through the data array from "history" ref
As we see here, there is 2 console log, 1 from the request and 1 after we put the data in history both show 2 array which is what the values should be but there is nothing on the table and yes every row have an unique id in the database
I'm still pretty new to vuejs ^^
Template
<template>
<div class="container">
<h3 v-if="loading"> Loading... </h3>
<table>
<tr>
<th>Title</th>
<th>Shares</th>
<th>Price</th>
</tr>
<tr ref="history" v-for="row in history" :key="row.id" >
<td>{{ row.title }}</td>
<td>{{ row.shares }}</td>
<td>{{ row.price }}</td>
</tr>
</table>
</div>
Script
<script>
import { store } from "../store"
import { onMounted, ref, reactive } from "vue"
import { supabase } from "#/supabase"
export default {
setup () {
const loading = ref(true);
const user = supabase.auth.user();
const history = ref([])
async function getHistory() {
try {
loading.value = true;
let { data, error, status } = await supabase
.from("history")
.select(`id, user_id, title, shares, price`)
.eq("user_id", user.id)
console.log(data)
if (error && status !== 406) throw error
if (data) {
history.value = data
console.log(history.value)
}
} catch (error) {
alert(error.message)
} finally {
loading.value = false
}
}
onMounted(() => {
getHistory()
})
return {
loading,
user,
history,
}
},
data() {
return {}
}
}
The issue is using ref="history" on the tr tag, as it will bind the ref with the DOM element, you need to remove it.
<tr v-for="row in history" :key="row.id" >
<td>{{ row.title }}</td>
<td>{{ row.shares }}</td>
<td>{{ row.price }}</td>
</tr>

Vue Sorted Table (Sorted from highest to lowest)

Hi i am a newbie in vuejs. I wanted to sort a table by Highest to lowest. However i install the library of vue-sorted-table. But when im trying run the code the data always return lowest to highest. Can anyone help me? Thank you..
Here is the code:
<template>
<div id="app">
<sorted-table :values="values" #sort-table="onSort">
<thead>
<tr>
<th scope="col" style="text-align: left; width: 10rem;">
<sort-link name="id">ID</sort-link>
</th>
</tr>
</thead>
<template #body="sort">
<tbody>
<tr v-for="value in sort.values" :key="value.id">
<td>{{ value.id }}</td>
</tr>
</tbody>
</template>
</sorted-table>
</div>
</template>
<script>
import { ChevronUpIcon } from "vue-feather-icons";
export default {
name: "App",
data: function() {
return {
values: [{ id: 2 }, { id: 1 }, { id: 3 }],
sortBy: "",
sortDir: ""
};
},
components: {
ChevronUpIcon
},
methods: {
onSort(sortBy, sortDir) {
this.sortBy = sortBy;
this.sortDir = sortDir;
}
}
};
</script>
<style>
.feather {
transition: 0.3s transform ease-in-out;
}
.feather.asc {
transform: rotate(-180deg);
}
</style>
code can access here:
https://codesandbox.io/s/pedantic-kirch-bx9zv
Add dir property to sorted-table, and make its value equals to desc
<template>
<div id="app">
<sorted-table :values="values" #sort-table="onSort" dir="desc">
<thead>
<tr>
<th scope="col" style="text-align: left; width: 10rem;">
<sort-link name="id">ID</sort-link>
</th>
</tr>
</thead>
<template #body="sort">
<tbody>
<tr v-for="value in sort.values" :key="value.id">
<td>{{ value.id }}</td>
</tr>
</tbody>
</template>
</sorted-table>
</div>
</template>
<script>
import { ChevronUpIcon } from "vue-feather-icons";
export default {
name: "App",
data: function() {
return {
values: [{ id: 2 }, { id: 1 }, { id: 3 }],
sortBy: "",
sortDir: ""
};
},
components: {
ChevronUpIcon
},
methods: {
onSort(sortBy, sortDir) {
this.sortBy = sortBy;
this.sortDir = sortDir;
}
}
};
</script>
<style>
.feather {
transition: 0.3s transform ease-in-out;
}
.feather.asc {
transform: rotate(-180deg);
}
</style>
check https://github.com/BernhardtD/vue-sorted-table and pay attention to dir property of the table, you'll find the answer

Calling a vue component into v-for

I have the following construction:
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Наименование</th>
<th scope="col">API ключ</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
<tr v-for="adv in advertisers">
<th scope="row">{{ adv.id }}</th>
<td>{{ adv.name }}</td>
<td>{{ adv.api_key }}</td>
<td>
<advertiser-delete-component :advertiser-id="adv.id"></advertiser-delete-component>
<advertiser-edit-component :advertiser-id="adv.id" :advertiser-name="adv.name"></advertiser-edit-component>
</td>
</tr>
</tbody>
</table>
Array "advertisers" keeps data from the server. Data is correct. But I see that all 'advertiser-delete-component' and 'advertiser-edit-component' have the first item of advertisers array in component props.
Here is the code of advertiser-edit-component:
<script>
import { EventBus } from '../../app.js';
export default {
mounted() {
},
props: ['advertiserId', 'advertiserName'],
data: function() {
return {
formFields: {
advertiserName: '',
advertiserId: this.advertiserId,
},
errors: []
}
},
methods: {
submit: function (e) {
window.axios.post('/advertiser/edit', this.formFields).then(response => {
this.formFields.advertiserName = '';
EventBus.$emit('reloadAdvertisersTable');
$('#addAdvertiser').modal('hide');
}).catch(error => {
if (error.response.status === 422) {
this.errors = error.response.data.errors || [];
}
});
}
}
}
The props props: ['advertiserId', 'advertiserName'] are the same for each component call with my code. I want them to be dynamic where they take corresponding elements from the array as the loop goes through it one by one.
What did I do wrong?
UPDATE:
Here is full code of table component:
<template>
<div>
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Наименование</th>
<th scope="col">API ключ</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
<tr v-for="adv in advertisers">
<th scope="row">{{ adv.id }}</th>
<td>{{ adv.name }}</td>
<td>{{ adv.api_key }}</td>
<td>
<advertiser-delete-component :advertiser-id="adv.id"></advertiser-delete-component>
<advertiser-edit-component :advertiser-id="adv.id"
:advertiser-name="adv.name"></advertiser-edit-component>
</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
import {EventBus} from '../../app.js';
export default {
mounted() {
this.getAdvertisersTable();
EventBus.$on('reloadAdvertisersTable', this.getAdvertisersTable)
},
props: ['totalCountOfAdvertisers'],
data: function () {
return {
advertisers: [],
}
},
methods: {
getAdvertisersTable: function () {
window.axios.get('/advertisers/all')
.then(r => {
this.advertisers = r.data.data;
})
.catch(e => {
console.log(e.response.data.errors);
})
}
}
}
</script>
I think formFields should be array of objects like:
formFields: [{
advertiserName: '',
advertiserId: this.advertiserId,
}],

In Vue how do I replace array with new array?

Every 10 seconds I query my database for latest fire calls. I do app.events = data.calls but my data doesn't refresh. I initialize the data with the same function that is called every 10 seconds. I see the table. How I do I replace an array in Vue with an array?
<html>
<head>
<script
src="https://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous"></script>
<script src="https://unpkg.com/vue"></script>
<script>
$(function() {
function getLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition);
} else {
$('#demo').text("Geolocation is not supported by this browser.");
}
}
function showPosition(position) {
$.get('http://localhost:8000/api/nearest_events?lng='+position.coords.longitude+'&lat='+position.coords.latitude, function(data) {
//app.$set(app.events, Object.assign({}, app.events, data.calls));
app.events = data.calls;
})
}
app = new Vue({
el: '#app',
data: {
events: []
},
created: function() {
setInterval(getLocation(), 10000)
}
})
})
</script>
<style>
td, th {border:1px solid #000;padding:5px}
table { border-collapse:collapse;}
</style>
</head>
<body>
<div id="app">
<table>
<tr v-for="event in events">
<td>{{ event.datetime }}</td>
<td>{{ event.address }}</td>
<td>{{ event.type }}</td>
<td>
<table>
<tr><th>Unit</th><th>Dispatched at</th><th>Arrived at</th><th>In service</th></tr>
<tr v-for="unit in event.units">
<td>{{ unit.unit }}</td>
<td>{{ unit.dispatched }}</td>
<td>{{ unit.arrived }}</td>
<td>{{ unit.in_service }}</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
</body>
</html>
It appears that your problem is in setInterval. When you call getLocation it does not require the ()
i = 0;
app = new Vue({
el: '#app',
data: {
events: []
},
methods: {
getLocation: function () {
var self = this;
i+=1;
self.events = [1,2,3,i];
}
},
created: function() {
self = this;
setInterval(self.getLocation, 1000);
}
})
And here is a working demo:
https://codepen.io/egerrard/pen/EwLVNB

Is it possible to use a component property as a data variable?

I've copied my current code below. I'm trying to dynamically generate table headers depending on what type I pass as a prop to my tables component (standings and status are what I have as the data arrays in my example).
I've accomplished this by using the if statement in the header computed value to return the proper list.
However I'd like to not have to add additional if statements for every type.
Is there a way that I can leverage the type prop to bind directly to the matching data?
<div id="root" class="container">
<tables type="stats">
</tables>
</div>
Vue.component('tables', {
template: `
<table class="table">
<thead>
<tr>
<th v-for="headers in header">{{ headers }}</th>
</tr>
</thead>
<tfoot>
<tr>
<th v-for="footers in header">{{ footers }}</th>
</tr>
</tfoot>
<tbody>
<tr>
<th>1</th>
<td>Leicester City <strong>(C)</strong>
<slot></slot>
</tr>
</tbody>
</table>
`,
data () {
return {
standings: ['Rank', 'Team', 'Wins', 'Losses'],
stats: ['Number', 'Player', 'Position', 'RBI', 'HR']
};
},
computed: {
header() {
if (this.type == 'standings') {
return this.standings;
} else {
return this.stats;
}
}
},
props: {
type: { required: true }
}
});
If you change up your data structure slightly, you can remove your if statements.
data () {
return {
types:{
standings: ['Rank', 'Team', 'Wins', 'Losses'],
stats: ['Number', 'Player', 'Position', 'RBI', 'HR']
}
};
},
computed: {
header() {
return this.types[this.type]
}
},
props: {
type: { required: true }
}
Here is an example.
Vue.component('tables', {
template: `
<table class="table">
<thead>
<tr>
<th v-for="headers in header">{{ headers }}</th>
</tr>
</thead>
<tfoot>
<tr>
<th v-for="footers in header">{{ footers }}</th>
</tr>
</tfoot>
<tbody>
<tr>
<th>1</th>
<td>Leicester City <strong>(C)</strong>
<slot></slot>
</td>
</tr>
</tbody>
</table>
`,
data () {
return {
types:{
standings: ['Rank', 'Team', 'Wins', 'Losses'],
stats: ['Number', 'Player', 'Position', 'RBI', 'HR']
}
};
},
computed: {
header() {
return this.types[this.type]
}
},
props: {
type: { required: true }
}
});
new Vue({
el: "#root"
})
<script src="https://unpkg.com/vue#2.2.6/dist/vue.js"></script>
<div id="root" class="container">
<tables type="stats">
</tables>
</div>