Pagiantion with server table is not working on vue js - vue.js

I am creating a table using a ServerTable from 'vue-tables-2' to render a the data with axios and create a pagination, but the problem in the pagination the table show all the records together in the first page
I tried to fixe it but i didn't find any solution
Here you can find the component that i am using to create that table and the pagination
<template>
<div class="mt-5">
<div class="card-header purple-background bord-top-lr-5">
<h4 class="title-align font-montserrat text-light white-text-color">
{{ items.count + ' results found' }}
</h4>
</div>
<div class="card-body white-bg">
<div class="grid-x grid-padding-x m-2 border-0">
<div class="border-0 mb-2">
<v-server-table
url="/companies/search"
:columns="columns"
:options="options"
class="table-header"
>
<div slot="company_name" class="m-3" slot-scope="props">
<h5 class="title-align font-montserrat" style="color: #5b2557">
<a :href="props.row.url" :title="props.row.name">
{{ props.row.name }}
</a>
({{ $t('labels.frontend.companies.demontage') }})
</h5>
<div class="row">
<div class="col">
<p
class="gray-text-color font-montserrat-thin font-weight-bold"
>
{{ props.row.address.street }}
{{ props.row.address.building_nr }},
{{ props.row.address.postal }},
{{ props.row.address.city }}, {{ props.row.address.state }},
{{ props.row.address.country }}
</p>
</div>
<div class="col ml-lg-5">
<p
class="font-montserrat-thin blue-light-color font-weight-bold"
>
T. {{ props.row.address.phone }}<br />
<a
:href="props.row.website"
target="_blank"
:title="props.row.name"
class="gray-text-color"
>
{{ $t('labels.frontend.companies.goTo') }}
</a>
</p>
</div>
<div class="col ml-lg-5">
<a
class="font-montserrat-regular"
href="#"
style="color: #74aee0"
>
{{ $t('labels.frontend.companies.moreInfo') }} »
</a>
</div>
</div>
<button
class="mb-3 blue-light-bg btn bord-rad-5 white-text-color font-montserrat-regular"
href="#"
>
{{ $t('labels.frontend.companies.stock') }}
</button>
<br />
</div>
</v-server-table>
</div>
</div>
</div>
</div>
</template>
<script>
import Vue from 'vue'
import { ServerTable } from 'vue-tables-2'
Vue.use(ServerTable, {}, false, 'bootstrap4', 'default')
export default {
name: 'SearchCompaniesTable',
props: {
companyName: {
type: String,
required: false,
default: () => ''
}
},
data() {
return {
total: 0,
items: [],
columns: ['company_name'],
options: {
headings: {
remote_id: 'Document'
},
highlightMatches: true,
pagination: {
chunk: 10,
edge: true,
dropdown: false,
nav: 'fixed'
},
perPage: 10,
perPageValues: [10],
preserveState: true,
sortable: ['company_name'],
filterable: ['company_name'],
skin: 'table-bordered table-hover'
},
page: 1
}
},
computed: {
rows() {
return Object.keys(this.items).length
}
},
mounted() {
axios.get('/companies/search').then(response => {
this.items = response.data
})
}
}
Could you please check what mistake did i make?

Related

"adding" products to cart in vue not showing up in console.log

the code:
shop.vue
<template>
<div class="shop">
<div class="products" v-for="Product in items" :key="Product.id" :Product="Product"
v-on:add-To-Cart="addToCart($event)">
<h1>{{ Product.name }}</h1> <img :src="Product.pic" width="400" /> <br>
{{ Product.description }} <br>
{{ "$" + Product.price }} <br>
<button class="addToCart" #click="$emit('add-To-Cart', Product)">Add to Cart</button>
</div>
</div>
</template>
<script>
import Product from '../db.json';
export default {
name: 'shop',
data() {
return {
items: Product
}
},
methods: {
addToCart(Product) {
this.Product=Product
console.log(this.Product)
}
}
}
</script>
when I click the add to cart button it is not logging the product to the console
how can I fix that? and implement a shopping cart to my website?
Custom events are emitted from vue components not from native html elements, the same for props, you can directly call the method addToCart from the click event handler :
<template>
<div class="shop">
<div class="products" v-for="Product in items" :key="Product.id" >
<h1>{{ Product.name }}</h1> <img :src="Product.pic" width="400" /> <br>
{{ Product.description }} <br>
{{ "$" + Product.price }} <br>
<button class="addToCart" #click="addToCart(Product)">Add to Cart</button>
</div>
</div>
</template>
<script>
import Product from '../db.json';
export default {
name: 'shop',
data() {
return {
items: Product
}
},
methods: {
addToCart(Product) {
this.items.push(Product)
console.log(this.items)
}
}
}
</script>
I have a modified the code a little bit without any stylings applied. Please check the below snippet
new Vue({
el: '#app',
data() {
return {
items: [{
name: 'aaa',
description: 'about aaa',
pic: 'https://www.google.com/url?sa=i&url=https%3A%2F%2Fwww.taste.com.au%2Frecipes%2Fchocolate-cream-biscuits%2Fee3d0934-ccca-4fdf-8827-64f2fd2737e1&psig=AOvVaw1fEqbEmoJeGS0WmrnSy6pS&ust=1668580370820000&source=images&cd=vfe&ved=0CBAQjRxqFwoTCICb2LbIr_sCFQAAAAAdAAAAABAD',
price: 12,
},
{
name: 'bbb',
description: 'about bbb',
pic: 'https://www.google.com/url?sa=i&url=https%3A%2F%2Fwww.taste.com.au%2Frecipes%2Fchocolate-cream-biscuits%2Fee3d0934-ccca-4fdf-8827-64f2fd2737e1&psig=AOvVaw1fEqbEmoJeGS0WmrnSy6pS&ust=1668580370820000&source=images&cd=vfe&ved=0CBAQjRxqFwoTCICb2LbIr_sCFQAAAAAdAAAAABAD',
price: 12,
}],
cartItems:[],
};
},
methods: {
addToCart(item) {
this.cartItems.push({...item});
},
}
});
.products {
display: flex;
justify-content: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div class="products" v-for="product in items" :key="product.id">
<h1>{{ product.name }}</h1> <img :src="product.pic" width="400" /> <br>
{{ product.description }} <br>
{{ "$" + product.price }} <br>
<button class="addToCart" #click="addToCart(product)">Add to Cart</button>
</div>
</div>

Accessing Vuex data within dynamic _id.vue page - Vue/Nuxt

I want to access my user details stored in the state when visiting a dynamic (_id.vue) page. I have set the id of the page like this after using the link to the page:
data() {
return {
selectedTutor: null,
id: this.$route.params.id,
}
},
But now I need to define the selectedTutor by searching the id within the data in the vuex state. I was trying to do something like this:
created() {
this.selectedTutor = this.$store.state.tutors.find((tutor) => tutor.id === this.id)
},
But everything stays undefined. So when id equals to the id within the object, that object needs to be set as selectedTutor so I can access all the necessary data to be displayed on the page.
Here you can see the Vuex state
EDIT
_id.vue page
<template>
<div>
<section>
<div>
<h3>
{{ id }}
</h3>
</div>
</section>
</div>
</template>
<script>
import { mapState } from 'vuex'
export default {
name: 'TutorPage',
/* eslint-disable vue/require-prop-types */
layout: 'app',
props: ['id'],
middleware: 'auth',
data() {
return {
selectedTutor: null,
}
},
computed: {
...mapState(['tutors']),
},
created() {
this.selectedTutor = this.$store.state.tutors.find(
(tutor) => tutor.id === this.id
)
},
}
</script>
MainResult Page
<base-grid>
<ul id="tutors" class="grid grid-cols-2 gap-6">
<tutor-item
v-for="tutor in tutors"
:id="tutor.id"
:key="tutor.id"
:name="tutor.attributes.name"
:rate="student.hourlyRate"
:subject="student.subject"
:description="student.biography"
:profile-image="student.imageUrl"
:image-alt="student.imageAlt"
:age="student.age"
:rating="student.rating"
:total-reviews="student.reviewCount"
class="overflow-hidden bg-white border rounded-lg shadow-md"
>
</tutor-item>
</ul>
</base-grid>
Tutor Item (the resultcard)
<template>
<div>
<li>
<div class="flex">
<div class="w-2/3">
<img
class="flex-shrink-0 object-cover w-full h-64 mx-auto bg-gray-200"
:src="profileImage"
:alt="imageAlt"
/>
</div>
<div class="p-6">
<div
class="text-xs font-semibold leading-snug tracking-wide text-gray-500 uppercase"
>
{{ subject }} • {{ age }} jaar
</div>
<NuxtLink :to="'/tutors/' + id">
<h4 class="text-lg font-semibold leading-5 tracking-wide">
{{ name }}
</h4>
</NuxtLink>
<div class="mt-2">
{{ rate }}€
<span class="text-sm text-gray-600">per uur</span>
</div>
<div class="mt-2">
<span class="font-semibold text-light-blue-800"
>{{ rating }}/5 sterren</span
>
<span class="text-sm text-gray-600 truncate">
(na {{ totalReviews }} reviews)
</span>
</div>
<div class="mt-2">{{ description }}</div>
<div>
<div class="mt-4 text-sm font-semibold text-gray-600">
<span>MA</span>
<span
class="inline-block leading-7 text-center text-gray-100 bg-yellow-400 bg-opacity-50 w-7 h-7 rounded-xl"
>DI</span
>
<span>WO</span>
<span
class="inline-block leading-7 text-center text-gray-100 bg-yellow-400 bg-opacity-50 w-7 h-7 rounded-xl"
>DO</span
>
<span
class="inline-block leading-7 text-center text-gray-100 bg-yellow-400 bg-opacity-50 w-7 h-7 rounded-xl"
>VR</span
>
<span>ZA</span>
<span>ZO</span>
</div>
</div>
</div>
</div>
</li>
</div>
</template>
<script>
export default {
/* eslint-disable vue/require-prop-types */
name: 'TutorItem',
props: [
'id',
'firstName',
'lastName',
'name',
'rate',
'subject',
'age',
'rating',
'totalReviews',
'description',
'profileImage',
'imageAlt',
],
computed: {
fullName() {
return this.firstName + ' ' + this.lastName
},
tutorsDetailsLink() {
return this.$route.path + '/' + this.id
},
},
}
</script>
<style></style>
EDIT
Whoops, what a mistake. It was returning the id as a string but I needed a number. This is why it returned undefined. It is solved now! Thanks

Pagination in vue.js framework

Error with Pagination in vue.js framework in view page, The Pagination bar is working fine but I have 50 records on the same page. The Pagination bar is 17 => 50/3 . The Post is displayed in div section not in Table.
<template>
<div class="blog">
<h2>{{ pageDescreption }}</h2>
<hr />
<div class="alert alert-success" role="alert" v-text="alertTitel"></div>
<div class="row">
<div class="col-md-8">
<div class="posts-area">
<PostList
id="PostList"
v-for="post in posts"
:key="post.id"
:post="post"
:current-page="currentPage"
:per-page="perPage"
/>
<div class="overflow-auto">
<b-pagination
v-model="currentPage"
:total-rows="rows"
:per-page="perPage"
aria-controls="PostList"
></b-pagination>
<p class="mt-3">Current Page: {{ currentPage }}</p>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import PostList from "#/components/Blogs/PostList.vue";
import PostJson from "../Gatewaye/post.json";
export default {
data: function() {
return {
pageName: "blog",
pageDescreption: "This is an Blog page",
alertTitel: "List of all Posts",
posts: PostJson, // array of posts [50 records]
perPage: 3,
currentPage: 1
};
},
name: "Blog",
components: {
PostList
},
computed: {
rows() {
return this.posts.length;
}
}
};
</script>
And in Components file Blog.vue is:
<template>
<div class="PostList">
<div class="post-container text-left">
<span class="post-views badge badge-primary" title="Views">{{
post.views
}}</span>
<h3 class="post-title" title="Title">{{ post.title }}</h3>
<span class="post-date" title="Date">{{ post.date }}</span>
<p class="post-body">
{{ post.contant }}
</p>
<div class="row">
<div class="col-sm-6">
<span class="post-author" title="Auther">{{ post.auther }}</span>
</div>
<div class="col-sm-6 text-right">
<span class="post-category" title="Category">{{
post.category
}}</span>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: ["post"],
name: "PostList"
};
</script>
The Pagination bar is working fine but I have 50 records on the same page ... Thank you
Use a computed property to slice the post array in the parent component:
computed: {
paginatedposts() {
return this.posts.slice(this.perPage*(this.currentPage-1), (this.perPage*(this.currentPage-1))+this.perPage);
}
}
Now you just need to bind this computed property:
<PostList
id="PostList"
v-for="post in paginatedposts"
:key="post.id"
:post="post"
/>

How to update data() in vue.draggable

I know this may be basic stuff... but I cannot get my data updated when using Vue.Draggable 2.23. In the code below, the 4 lists are returned from the axios call exactly as they are now return by data(), but then, of course, with content. Somehow I keep getting "Property or method "lane0" is not defined on the instance but referenced during render." In App.vue:
<script>
import draggable from "vuedraggable";
import axios from "axios";
export default {
name: "two-lists",
display: "Two Lists",
order: 1,
components: {
draggable
},
data() {
return {
"lane0": [],
"lane1": [],
"lane2": [],
"lane3": []
}
},
mounted () {
axios
.get('http://localhost:8000/pylims/get_sequencable_lanes/10/S4')
.then(response => (this.data= response.data))
},
methods: {
log: function(evt) {
window.console.log(evt);
}
}
}
</script>
On request, the HTML part (template in App.vue):
<template>
<div class="row">
<div class="col-3">
<h3>Draggable 1</h3>
<draggable class="list-group" :list="lane0" group="people" #change="log">
<div
class="list-group-item"
v-for="(element, index) in lane0"
:key="element.sample_name"
>
{{ element.sample_name }} {{ index }}
</div>
</draggable>
</div>
<div class="col-3">
<h3>Draggable 2</h3>
<draggable class="list-group" :list="lane1" group="people" #change="log">
<div
class="list-group-item"
v-for="(element, index) in lane1"
:key="element.sample_name"
>
{{ element.sample_name }} {{ index }}
</div>
</draggable>
</div>
<div class="col-3">
<h3>Draggable 3</h3>
<draggable class="list-group" :list="lane2" group="people" #change="log">
<div
class="list-group-item"
v-for="(element, index) in lane2"
:key="element.sample_name"
>
{{ element.sample_name }} {{ index }}
</div>
</draggable>
</div>
<br><br>
{{ lane0 }}
<br><br>
{{ lane1 }}
<br><br>
{{ lane2 }}
<br><br>
{{ lane3 }}
</div>
</template>
As Tobias G. states in the comment and is clearly explained here: https://v2.vuejs.org/v2/cookbook/using-axios-to-consume-apis.html the problem is solved by wrapping the lanes in an object, and then updating that from within the mounted() function, like this:
data() {
return {
lanes: {
"lane0": [],
"lane1": [],
"lane2": [],
"lane3": []
}
}
},
mounted () {
axios
.get('http://localhost:8000/pylims/get_sequencable_lanes/10/S4')
.then(response => (this.lanes = response.data))
},
then using it in the HTML part like this:
<draggable class="list-group" :list="lanes.lane0" group="people" #change="log">

Local-Storage in Vue.JS

I am working on Vue.JS and I tried to use local-storage with it to save data. In my code, I can store and retrieve all data with local-storage except line-through effect. Here, I am trying to store actual boolean value of line-through effect in local-storage and want to retrieve that value on to-do list app.
<title>To Do List</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js'></script>
<style>
.taskDone {
text-decoration: line-through;
}
</style>
</head>
<body>
<div id="todo-list" class="container">
<div class="container col-sm-8 col-sm-offset-2">
<h1 class="text-center"> <big><b> To Do List </b> </big></h1>
<h5 class="text-center"> <span v-show="itemsTodo.length"> ({{ itemsTodo.length }} pending) </span></h5>
<div class="col-md-8">
<button v-if="state === 'default'" class="btn btn-primary" #click="changeState('edit') ">Add Item</button>
<button v-else class="btn btn-info" #click="changeState('default')">Cancel</button>
</div>
<br>
<br>
<div v-if="state === 'edit'" >
<div class="col-sm-4">
<input class='form-control' v-model="newItem" type="text" placeholder="Type here" #keyup.enter="saveItem" >
</div>
<div class="col-sm-4">
<input class="form-control" v-model="newdate" type="date" type="text"/>
</div>
<div class="col-sm-4">
<button class='btn btn-primary btn-block' v-bind:disabled="newItem.length === 0"#click= "saveItem">Save Item</button>
</div>
</div>
<br>
<br>
<ul type="none" class="list-group">
<li class="list-group-item" v-for="(item,index,date) in items" :class="{taskDone : item.completed}" >
<h4>
<input type="checkbox" v-model="item.completed" #click="item.completed = !item.completed">
<button class="btn btn-primary " #click.stop="removeitems(index)">× </button>
<b><i> {{ item.label }} {{ item.date }} </i></b></h4>
</li>
</ul>
<h2 v-if="items.length === 0">Nice Job! Nothing in TO DO LIST</h2>
<div class="col-sm-4">
<button class="btn btn-warning btn-block" #click="clearcompleted"> Clear Completed</button>
</div>
<div class="col-sm-4">
<button class="btn btn-danger btn-block" #click="clearAll"> Clear All</button>
</div>
</div>
</div>
2. Vue.JS code
<script src="https://unpkg.com/vue" ></script>
<script>
var todolist = new Vue({
el: '#todo-list',
data : {
state : 'edit',
header: 'To Do List',
newItem: '',
newdate: '',
items: [
{
label:'coffee',
completed:false,
date:'2019-06-20' ,
},
{
label:'tea',
completed:false,
date:'2019-06-19' ,
},
{
label:'milk',
completed:false,
date:'2019-06-19' ,
},
]
},
computed:{
itemsDone(){
return this.items.filter(items => items.completed)
},
itemsTodo(){
return this.items.filter(items =>! items.completed)
},
},
methods:{
saveItem: function(){
if (this.newItem != ''){
this.items.push({
label:this.newItem,
completed: false,
date : this.newdate,
});
this.newItem = '';
this.newdate = '';
}},
changeState: function(newState){
this.state = newState;
this.newItem = '';
this.newdate = '';
},
removeitems(index){
this.items.splice(index,1);
},
clearcompleted (){
this.items = this.itemsTodo;
},
clearAll: function(){
this.items = [ ];
},
},
mounted(){
console.log('App Mounted!');
if (localStorage.getItem('items')) this.items = JSON.parse(localStorage.getItem('items'));
},
watch: {
items:{
handler(){
localStorage.setItem('items',JSON.stringify(this.items));
},
},
},
});
</script>
I expect correct boolean value of line-through effect to be stored in local-storage. So that, appropriate effect will show on browser.
You are just watching items. If you change something in a item (in your case completed) the handler will not be called and your change is not stored.
You could use a "deep" watcher but i suggest to call your save logic whenever you changed something.