I handle vuejs + laravel
I Controller :
public function listData (Request $request)
{
$currentPage = !empty($request->currentPage) ? $request->currentPage : 1;
$pageSize = !empty($request->pageSize) ? $request->pageSize : 30;
$skip = ($currentPage - 1) * $pageSize;
$totalProduct = Product::select(['id', 'name'])->get();
$listProduct = Product::select(['id', 'name'])
->skip($skip)
->take($pageSize)
->get();
return response()->json([
'listProduct' => $listProduct,
'total' => $totalProduct,
]);
}
In vuejs
data() {
return {
pageLength: 30,
columns: [
{
label: "Id",
field: "id",
},
{
label: "Name",
field: "name",
},
],
total: "",
rows: [],
currentPage: 1,
};
},
created() {
axios
.get("/api/list")
.then((res) => {
this.rows = res.data. listProduct;
this.total = res.data.total;
})
.catch((error) => {
console.log(error);
});
},
methods: {
changePagination() {
axios
.get("/api/list", {
params: {
currentPage: this.currentPage,
pageSize: this.pageLength,
},
})
.then((res) => {
this.rows = res.data. listProduct;
this.total = res.data.total;
})
.catch((error) => {
console.log(error);
});
},
},
Template :
<vue-good-table
:columns="columns"
:rows="rows"
:rtl="direction"
:search-options="{
enabled: true,
externalQuery: searchTerm,
}"
:select-options="{
enabled: false,
selectOnCheckboxOnly: true,
selectionInfoClass: 'custom-class',
selectionText: 'rows selected',
clearSelectionText: 'clear',
disableSelectInfo: true,
selectAllByGroup: true,
}"
:pagination-options="{
enabled: true,
perPage: pageLength,
}"
>
<template slot="pagination-bottom">
<div class="d-flex justify-content-between flex-wrap">
<div class="d-flex align-items-center mb-0 mt-1">
<span class="text-nowrap"> Showing 1 to </span>
<b-form-select
v-model="pageLength"
:options="['30', '50', '100']"
class="mx-1"
#input="changePagination"
/>
<span class="text-nowrap"> of {{ total }} entries </span>
</div>
<div>
<b-pagination
:value="1"
:total-rows="total"
:per-page="pageLength"
first-number
last-number
align="right"
prev-class="prev-item"
next-class="next-item"
class="mt-1 mb-0"
v-model="currentPage"
#input="changePagination"
>
<template #prev-text>
<feather-icon icon="ChevronLeftIcon" size="18" />
</template>
<template #next-text>
<feather-icon icon="ChevronRightIcon" size="18" />
</template>
</b-pagination>
</div>
</div>
</template>
I am dealing with a product list that has 500,000 products. I don't want to take it out once. I want it to pull out 30 products each time, when I click on the partition, it will call to the api to call the next 30 products.. But my problem is the default pageLength is 30 products, When I choose show showing 50 products , it still shows 30 products on the page list (But I console.log (res.data.listProduct)) it shows 50 products, how do I change the default value pageLength.
Is there any way to fix this, Or am I doing something wrong. Please advise. Thanks.
Add this into computed =>
paginationOptionsComputed(){
return { enabled: true, perPage: Number(this.pageLength), }
}
And change :pagination-options="paginationOptionsComputed"
Note: actual problem is that vue-good-table expects perPage as number. If you look at the initializePagination method in here you can see this:
if (typeof perPage === 'number') {
this.perPage = perPage;
}
Related
Hello guys im trying to learn vue and im trying to use datatable from https://datatables.net/ and having a problem with my action button that im not able to get the id when the #viewModal is been triggered i hope someone can help me to get the id of each buttons thanks and here is my code TIA:
EmployeeDataTable Component :
<template>
<div class="card">
<div class="card-header">
<div class="card-title">Employee List</div>
</div>
<div class="card-body">
<div class="table-responsive">
<table
id="employee-table"
class="table-sm table-bordered table-hover text-center display"
width="100%"
>
<thead>
<tr>
<th class="pt-3 pb-3">#</th>
<th>Name</th>
<th>Address</th>
<th>Contact #</th>
<th>Department</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</div>
</div>
</template>
<script>
//For Datatable to work
import "datatables.net";
import EmployeeEdit from "./EmployeeEdit.vue";
export default {
name: "EmployeeList",
data() {
return {
employees: [],
};
},
mounted() {
this.getEmployeeLists();
},
components: {
"employee-edit": EmployeeEdit,
},
methods: {
getEmployeeLists() {
// INITIALIZE DATATABLE
$("#employee-table")
.DataTable({
//LOADING
// processing: true,
//AJAX
serverSide: true,
//DIRECTION
order: [[1, "desc"]],
//AJAX
ajax: {
url: "/api/getEmployeeLists",
dataList: "json",
type: "POST",
data: { _token: "{{csrf_token()}}" },
},
//TABLE COLUMNS SHOULD BE THE SAME IN CONTROLLER
columns: [
{ data: "#" },
{ data: "name" },
{ data: "address" },
{ data: "contact" },
{ data: "department" },
{ data: "status" },
{
data: "actions",
//allowing modification
createdCell(cell, cellData, rowData) {
let EmployeeListDataTableActions = Vue.extend(
require("./EmployeeListDataTableAction.vue").default
);
let instance = new EmployeeListDataTableActions().$mount();
$(cell).empty().append(instance.$el);
},
},
],
//View Count in Table
lengthMenu: [
[10, 25, 50, -1],
[10, 25, 50, "All"],
],
})
.columns();
},
beforeDestroy: function () {
$(this.$el).DataTable().destroy();
},
},
};
</script>
EmployeeDataTableAction Component :
<template>
<button class="btn btn-primary btn-sm" #click="viewModal" title="View Employee Details">
<i class="fa fa-eye"></i>
</button>
</template>
<script>
export default{
name: 'EmployeeListDataTableAction',
data: function() {
return {
}
},
mounted() {
},
methods: {
viewModal() {
var id = $(this.$el).closest('tr').find('input').val();
return false;
axios
.post(`/api/getEmployeeDetails/${id}`, {
id: id,
})
.then((response) => {
$("#edit-employee-modal").modal("show");
$(".myModalLabel").text(
response.data.name +
" - " +
response.data.department_name
);
state.commit("getEmployeeDetailsArray", response.data);
state.commit("getTransactionId", response.data.id);
})
.catch((response) => {
this.$toast.top("Something went wrong!");
});
},
},
}
</script>
Employee Controller for the DataTable :
public function employeeList(Request $request){
$all = Employee::getEmployeeTotal();
//total count of data
$total_data = $all;
//total filter
$total_filtered = $total_data;
//set_time_limit(seconds)
$limit = $request->input('length');
//start
$start = $request->input('start');
//order
// $order = $columns[$request->input('order.0.column')];
//direction
$dir = $request->input('order.0.dir');
$search_value = $request->input('search.value');
if (!empty($search_value)) {
$posts = Employee::getEmployeeNameSearch($search_value,$start, $limit, $dir);
$total_data = count($posts);
$total_filtered = $total_data;
}else{
if(empty($request->input('search.value')))
{
//if no search
$posts = Employee::getEmployeeList($start, $limit, $dir);
}
}
$data = array();
if(!empty($posts))
{
$counter = $start + 1;
foreach ($posts as $post)
{
$department = GlobalModel::getSingleDataTable('departments',$post->department_id);
$status = StatusController::checkStatus($post->status);
$nested_data['#'] = '<span style="font-size: 12px ; text-align: center;">'.$counter++.'</span>';
$nested_data['name'] = '<p style="text-align: center;">'.$post->name.'</p>';
$nested_data['address'] = '<p style="text-align: center;">'.$post->address.'</p>';
$nested_data['contact'] = '<p style="text-align: center;">'.$post->contact.'</p>';
$nested_data['department'] = '<p style="text-align: center;">'.$department->name.'</p>';
$nested_data['status'] = '<p style="text-align: center;">'.$status.'</p>';
$nested_data['actions'] = '';
$data[] = $nested_data;
}
}
$json_data=array(
"draw" => intval($request->input('draw')),
"recordsTotal" => intval($total_data),
"recordsFiltered" => intval($total_filtered),
"data" => $data
);
return response()->json($json_data);
}
In the second line of your viewModal() function, you are placing a return false; statement. "The return statement ends function execution and specifies a value to be returned to the function caller." From Mozilla docs. That's why the API call is never executing.
I am doing the search engine section in VueJS and Laravel, but I have a problem that does not allow me to advance in the other sections. The search engine opens and everything but when I write it only sends the first letter or 2 but not all of them like this in this image:
image of the data you send
the data that I write
After that it shows me the following error in console:
Uncaught (in promise) NavigationDuplicated: Avoided redundant navigation to current location: "/search?q=th"
Now showing my search engine code:
<template>
<div class="form_MCycW">
<form autocomplete="off" #sumbit.prevent>
<label class="visuallyhidden" for="search">Search</label>
<div class="field_2KO5E">
<input id="search" ref="input" v-model.trim="query" name="search" type="text" placeholder="Search for a movie, tv show or person..." #keyup="goToRoute" #blur="unFocus">
<button v-if="showButton" type="button" aria-label="Close" #click="goBack">
<svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 15 15"><g fill="none" stroke="#fff" stroke-linecap="round" stroke-miterlimit="10" stroke-width="1.5"><path d="M.75.75l13.5 13.5M14.25.75L.75 14.25"/></g></svg>
</button>
</div>
</form>
</div>
</template>
<script>
import { mapState } from 'vuex';
export default {
data() {
return {
query: this.$route.query.q ? this.$route.query.q : ''
}
},
computed: {
showButton() {
return this.$route.name === 'search';
},
...mapState({
search: state => state.event.fromPage
})
},
mounted() {
this.$refs.input.focus();
},
methods: {
goToRoute() {
if (this.query) {
this.$router.push({
name: 'search',
query: { q: this.query },
});
} else {
this.$router.push({
path: this.fromPage,
});
}
},
goBack() {
this.query = '';
this.$router.push({
path: '/',
});
},
unFocus (e) {
if (this.$route.name !== 'search') {
const target = e.relatedTarget;
if (!target || !target.classList.contains('search-toggle')) {
this.query = '';
this.$store.commit('closeSearch');
}
}
}
}
}
</script>
This is the other section of the search engine:
<template>
<main class="main">
<div class="listing">
<div class="listing__head"><h2 class="listing__title">{{ title }}</h2></div>
<div class="listing__items">
<div class="card" v-for="(item, index) in data.data" :key="index">
<router-link :to="{ name: 'show-serie', params: { id: item.id }}" class="card__link">
<div class="card__img lazyloaded"><img class="lazyload image_183rJ" :src="'/_assets/img/covers/posters/' + item.poster" :alt="item.name"></div>
<h2 class="card__name">{{ item.name }}</h2>
<div class="card__rating">
<div class="card__stars"><div :style="{width: item.rate * 10 + '%'}"></div></div>
<div class="card__vote">{{ item.rate }}</div>
</div>
</router-link>
</div>
</div>
</div>
</main>
</template>
<script>
import { mapState } from 'vuex';
let fromPage = '/';
export default {
name: "search",
metaInfo: {
bodyAttrs: {
class: 'page page-search'
}
},
computed: {
...mapState({
data: state => state.search.data,
loading: state => state.search.loading
}),
query() {
return this.$route.query.q ? this.$route.query.q : '';
},
title() {
return this.query ? `Results For: ${this.query}` : '';
},
},
async asyncData ({ query, error, redirect }) {
try {
if (query.q) {
this.$store.dispatch("GET_SEARCH_LIST", query.q);
} else {
redirect('/');
}
} catch {
error({ message: 'Page not found' });
}
},
mounted () {
this.$store.commit('openSearch');
this.$store.commit('setFromPage', fromPage);
if (this.data.length == 0 || this.data === null) {
this.$store.dispatch("GET_SEARCH_LIST", this.query);
}
setTimeout(() => {
this.showSlideUpAnimation = true;
}, 100);
},
beforeRouteEnter (to, from, next) {
fromPage = from.path;
next();
},
beforeRouteUpdate (to, from, next) {
next();
},
beforeRouteLeave (to, from, next) {
const search = document.getElementById('search');
next();
if (search && search.value.length) {
this.$store.commit('closeSearch');
}
}
};
</script>
In my routes section it is defined as follows:
{
name: 'search',
path: '/search',
component: require('../views/' + themeName + '/control/search/index').default
}
It is supposed to be a real-time search engine. I would appreciate your help in solving this problem...
What you need is a debounce. What it does is that it wait or delay till the user had finished typing before the model get updated or before you send it to the server.
An example of how it works is here
Here is a package for it.
https://github.com/vuejs-tips/v-debounce
is there something wrong with this part? getting this on console
app.js:38308 [Vue warn]: Unknown custom element: - did you
register the component correctly? For recursive components, make sure
to provide the "name" option.
(found in )
here is the code
<template>
<span>
<a href="#" v-if="isFavorited" #click.prevent="unFavorite(post)">
<i class="fa fa-heart"></i>
</a>
<a href="#" v-else #click.prevent="favorite(post)">
<i class="fa fa-heart-o"></i>
</a>
</span>
</template>
<script>
export default {
props: ['post', 'favorited'],
data: function() {
return {
isFavorited: '',
}
},
mounted() {
this.isFavorited = this.isFavorite ? true : false;
},
computed: {
isFavorite() {
return this.favorited;
},
},
methods: {
favorite(post) {
axios.post('/favorite/'+post)
.then(response => this.isFavorited = true)
.catch(response => console.log(response.data));
},
unFavorite(post) {
axios.post('/unfavorite/'+post)
.then(response => this.isFavorited = false)
.catch(response => console.log(response.data));
}
}
}
</script>
I have a vote system that allows the users to vote-up or unvote.
The issue is when a user clicks on the vote button multiple times quickly. It causes the number of upvotes to go up and down in a weird way (It goes up 1,2,3 and then down to below 0, probably has to do with the Vote.vue which adds and subtracts 1's from the total votes so when clicked fast enough it causes this weirdness) .
Also, I took care to have unique questions id and user id in the vote table.
I have these simple vote/unvote methods in the QuestionsController:
/**
* Vote a question up.
*/
public function voteUp(Question $question)
{
Auth::user()->votes()->attach($question->id);
}
/**
* Vote a question down.
*/
public function voteDown(Question $question)
{
Auth::user()->votes()->detach($question->id);
}
And maybe more importantly and probably causing the issue is the Vote.vue, as you may see I add/subtract 1 to the total #votes displayed.
methods: {
voteUp(question) {
axios.post('/voteup/'+question)
.then(response => this.isVoted = true, this.votes = this.votes + 1)
.catch(response => console.log(response.data));
},
voteDown(question) {
axios.post('/votedown/'+question)
.then(response => this.isVoted = false, this.votes = this.votes - 1)
.catch(response => console.log(response.data));
}
}
How do I overcome this so users won't exploit this + make it behave more stable?
EDIT: I tried these solutions but it didn't solve the issue:
#1 - I tried #Radu Diță solution:
<vote
:votes="{{ $question->votes()->count() }}"
:question="{{ $question->id }}"
:voted="{{ $question->currentUserVoted() ? 'true' : 'false' }}"
:disabled="voteInAir"
></vote>
and the Vote.vue script:
// resources/js/components/Vote.vue
<template>
<span>
<a href="#" v-if="isVoted" #click.prevent="voteDown(question)">
<i class="fas fa-caret-up fa-3x text-primary vote-effect vote-up-effect"></i>
</a>
<a href="#" v-else #click.prevent="voteUp(question)">
<i class="fas fa-caret-up fa-3x vote-gray vote-effect"></i>
</a>
<span class="vote-count-post "><strong>{{ this.votes }}</strong></span>
</span>
</template>
<script>
export default {
props: ['question', 'voted', 'votes'],
data: function() {
return {
isVoted: '',
voteInAir: false
}
},
mounted() {
this.isVoted = this.isVote ? true : false;
},
computed: {
isVote() {
return this.voted;
},
},
methods: {
voteUp(question) {
this.voteInAir = true;
axios.post('/voteup/'+question)
.then(response => this.isVoted = true, this.votes = this.votes + 1, this.voteInAir = false)
.catch(response => console.log(response.data), this.voteInAir = false);
},
voteDown(question) {
this.voteInAir = true;
axios.post('/votedown/'+question)
.then(response => this.isVoted = false, this.votes = this.votes - 1, this.voteInAir = false)
.catch(response => console.log(response.data), this.voteInAir = false);
}
}
}
</script>
#2 - I also tried #Rijosh solution:
<vote
:votes="{{ $question->votes()->count() }}"
:question="{{ $question->id }}"
:voted="{{ $question->currentUserVoted() ? 'true' : 'false' }}"
></vote>
And this is with time interval delay which didnt work:
<template>
<span>
<a href="#" v-if="isVoted" #click.prevent="voteDown(question)">
<i class="fas fa-caret-up fa-3x text-primary vote-effect vote-up-effect"></i>
</a>
<a href="#" v-else #click.prevent="voteUp(question)">
<i class="fas fa-caret-up fa-3x vote-gray vote-effect"></i>
</a>
<span class="vote-count-post "><strong>{{ this.votes }}</strong></span>
</span>
</template>
<script>
export default {
props: ['question', 'voted', 'votes'],
data: function() {
return {
isVoted: '',
timer: null,
interval: 200,
}
},
mounted() {
this.isVoted = this.isVote ? true : false;
},
computed: {
isVote() {
return this.voted;
},
},
methods: {
voteUp(question) {
clearTimeout(this.timer);
this.timer = setTimeout(() => {
axios.post('/voteup/'+question)
.then(response => this.isVoted = true, this.votes = this.votes + 1)
.catch(response => console.log(response.data));
}, this.interval);
},
voteDown(question) {
clearTimeout(this.timer);
this.timer = setTimeout(() => {
axios.post('/votedown/'+question)
.then(response => this.isVoted = false, this.votes = this.votes - 1)
.catch(response => console.log(response.data));
}, this.interval);
}
}
}
</script>
Since you are only allowing one vote (or that is what i understand) i would not increase the upvotes directly but make kind of a system with booleans kind of like this:
<button v-on:click="activateUpVote">UpVote</button>
<button v-on:click="activateDownVote">DownVote</button>
.
.
.
data(){
return{
upVote: false,
downVote: false,
hasVoted: false
}
},
methods: {
activateUpVote(){
this.upVote = !this.upVote
if(this.upVote && (!this.hasVoted || this.downVote)){
this.downVote = false
this.hasVoted = true
this.vote('/votedown/'+this.question, this.votes + 1)
}else{
this.hasVoted = false
}
},
//downVote same as above but the other way around except for the hasVoted part
vote(route, votes) {
axios.post(route)
.then(response => votes)
.catch(response => console.log(response.data));
},
}
Try this solution
Template
<div>
<button #click="voteUp">UpVote</button>
<button #click="voteDown">DownVote</button>
</div>
Data
data: () => {
return {
timer: null,
interval: 200
}
},
Methods
methods: {
voteUp: function () {
clearTimeout(this.timer);
this.timer = setTimeout(() => {
console.log('up vote')
// your action
}, this.interval);
},
voteDown: function () {
clearTimeout(this.timer);
this.timer = setTimeout(() => {
console.log('down vote')
// your action
}, this.interval);
}
}
I'm using setTimeout and clearTimeout in the methods. This will prevent consecutive actions on the buttons. Continuous clicks will trigger only one action. The time between each click can be controlled using the interval value in the data.
You should disable the button after it was pressed and enabled it again after you get a response. This is usable for any button that you wan't to disable spamming.
In your data add a boolean for each button
data () {
return {
//other data
upVoteInAir: false
}
}
then bind your button based on the flag
<button :disabled="upVoteInAir">Up</button>
update the flag based on the http request
methods: {
voteUp(question) {
this.upVoteInAir = true
axios.post('/voteup/'+question)
.then(response => this.isVoted = true, this.votes = this.votes + 1, this.upVoteInAir = false)
.catch(response => console.log(response.data), this.upVoteInAir = false);
},
}
I have made a CRUD based admin pannel with laravue. Now my problem is that whenever I am on the update page, I can't change the category immediately. I always have to make change in some other field to view the changed category. Its working fine on add card page when all the fields are empty.
This is the video of my issue
https://thisisntmyid.tumblr.com/post/189075383873/my-issue-with-elementui-and-laravue-and-vue
I've included the code for my list page as well as the add/update page.
Code for the listing page that will lead u to edit page
<div class="app-container">
<h1>My Cards</h1>
<Pagination
:total="totalCards"
layout="total, prev, pager, next"
:limit="10"
:page.sync="currentPage"
#pagination="loadNewPage"
></Pagination>
<el-table v-loading="loadingCardsList" :data="cards" stripe style="width: 100%">
<el-table-column prop="name" sortable label="Product Name"></el-table-column>
<el-table-column prop="description" label="Description" width="200px"></el-table-column>
<el-table-column prop="price" label="Price"></el-table-column>
<el-table-column prop="cardcategory" sortable label="Category"></el-table-column>
<el-table-column label="Operations" width="300px">
<template slot-scope="scope">
<el-button size="mini" type="primary" #click="handleView(scope.$index, scope.row)">View</el-button>
<el-button size="mini" #click="handleEdit(scope.$index, scope.row)">Edit</el-button>
<el-button size="mini" type="danger" #click="handleDelete(scope.$index, scope.row)">Delete</el-button>
</template>
</el-table-column>
</el-table>
<el-dialog :visible.sync="viewCard" width="30%">
<el-card class="box-card">
<h1>{{currentViewedCard.name}}</h1>
<p>{{currentViewedCard.description}}</p>
<p>{{currentViewedCard.price}}</p>
<el-tag>{{currentViewedCard.cardcategory}}</el-tag>
</el-card>
</el-dialog>
</div>
</template>
<script>
import Resource from '#/api/resource';
import Pagination from '#/components/Pagination/index.vue';
const cardcategoryResource = new Resource('cardcategories');
const cardResource = new Resource('cards');
export default {
name: 'Cards',
components: {
Pagination,
},
data() {
return {
cards: [],
categories: [],
currentPage: '',
totalCards: '',
loadingCardsList: true,
currentViewedCard: '',
viewCard: false,
};
},
created() {
this.getCardCategories();
this.getCardList({ page: 1 });
},
methods: {
async getCardList(query) {
this.loadingCardsList = true;
const data = await cardResource.list(query);
this.cards = data.data;
for (const card of this.cards) {
card['cardcategory'] = this.getCategoryName(card.cardCategory_id);
}
console.log(this.cards);
this.totalCards = data.total;
this.loadingCardsList = false;
},
async getCardCategories() {
this.categories = await cardcategoryResource.list({});
console.log(this.categories);
},
loadNewPage(val) {
this.getCardList({ page: val.page });
},
getCategoryName(id) {
return this.categories[id - 1].name;
},
handleView(index, info) {
this.viewCard = true;
this.currentViewedCard = info;
},
handleEdit(index, info) {
this.$router.push('/cards/edit/' + info.id);
},
closeDialog() {
this.viewProduct = false;
this.currentProductInfo = null;
},
handleDelete(index, info) {
cardResource.destroy(info.id).then(response => {
this.$message({
message: 'Card Deleted Successfully',
type: 'success',
duration: 3000,
});
this.getCardList({ page: this.currentPage });
});
},
},
};
</script>
<style lang="scss" scoped>
</style>
Code for the add/update page
<template>
<div class="app-container">
<el-form ref="form" :model="formData" label-width="120px">
<el-form-item label="Name">
<el-input v-model="formData.name"></el-input>
</el-form-item>
<el-form-item label="Description">
<el-input type="textarea" v-model="formData.description"></el-input>
</el-form-item>
<el-form-item label="Price">
<el-input v-model="formData.price"></el-input>
</el-form-item>
<el-form-item label="Category">
<!-- DO something here like binding category id to category name sort of meh... -->
<el-select v-model="formData.cardcategory" placeholder="please select category">
<el-option v-for="item in categories" :key="item" :label="item" :value="item"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" #click="editable ? updateProduct() : createProduct()">Save</el-button>
<el-button #click="editable ? populateFormData($route.params.id) : formDataReset()">Reset</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
import Resource from '#/api/resource';
const cardcategoryResource = new Resource('cardcategories');
const cardResource = new Resource('cards');
export default {
data() {
return {
formData: {
name: '',
description: '',
price: '',
cardcategory: '',
},
categories: [],
editable: '',
};
},
created() {
this.getCategories();
if (this.$route.params.id) {
this.editable = true;
this.populateFormData(this.$route.params.id);
} else {
this.editable = false;
}
},
methods: {
async getCategories() {
this.categories = (await cardcategoryResource.list({})).map(
cat => cat.name
);
console.log(this.categories);
},
formDataReset() {
this.formData = {
name: '',
description: '',
price: '',
cardcategory: '',
};
},
populateFormData(id) {
cardResource.get(id).then(response => {
this.formData = Object.assign({}, response);
this.formData.price = this.formData.price.toString();
this.formData.cardcategory = this.categories[
this.formData.cardCategory_id - 1
];
delete this.formData.cardCategory_id;
});
},
filterFormData(formData) {
const cardData = Object.assign({}, formData);
cardData['cardCategory_id'] =
this.categories.indexOf(cardData.cardcategory) + 1;
delete cardData.cardcategory;
return cardData;
},
createProduct() {
const cardData = this.filterFormData(this.formData);
cardResource
.store(cardData)
.then(response => {
this.$message({
message: 'New Card Added',
type: 'success',
duration: 3000,
});
this.formDataReset();
})
.catch(response => {
alert(response);
});
},
updateProduct() {
const cardData = this.filterFormData(this.formData);
cardResource.update(this.$route.params.id, cardData).then(response => {
this.$message({
message: 'Card Updated Successfully',
type: 'success',
duration: 3000,
});
this.populateFormData(this.$route.params.id);
});
},
},
};
</script>
<style>
</style>
Update
here is the git hub repo for my project
https://github.com/ThisIsntMyId/laravue-admin-pannel-demo