I'm newbie in vue.js in laravel. I have a array data that display in table in vue. I want to create pagination for every 15 data. how can I do this? Any idea ?
template in vue.
<tbody>
<tr v-for="booking in bookings">
<td>{{ booking.booking_number | formatBookingNumber }}</td>
<td>{{ booking.date }}</td>
<td>{{ booking.status }}</td>
<td>{{ booking.check_in_date }}</td>
<td>{{ booking.check_out_date }}</td>
<td>
</td>
</tr>
</tbody>
Vue.js
<script>
export default {
props: ['bookings'] ..................
Amendments and additions
In case you haven't implemented a REST endpoint I suggest doing it with Transformers. After that you may follow the next use case:
app/Transformer/BookingsTransformer.php
public function transform($booking) {
return [
'booking-id' => $booking->booking_id,
'booking-data' => $booking->booking_date,
'booking-status' => $booking->booking_status,
'checkin' => $booking->booking_checkin,
'checkout' => $booking->booking_checkout,
];
}
app/Http/Controllers/BookingsResourceController.php
use EllipseSynergie\ApiResponse\Contracts\Response;
use App\Models\Bookings;
use App\Transformer\BookingsTransformer;
class ImageController extends Controller
{
protected $response;
public function __construct(Response $response)
{
$this->response = $response;
}
public function index()
{
//Get dataset's items
$image = Bookings::paginate(10);
// Return a collection of $images
return $this->response->withPaginator($image, new BookingsTransformer());
}
app/Http/Controllers/BookingsController.php
use App\Models\Bookings;
use Illuminate\Http\Request;
class BookingsController extends Controller
{
public function index()
{
return view('reservations');
}
routes/api.php
Route::get('bookings-api','ImageController#index');
routes/web.php
Route::get('/Bookings','BookingsController#index','as' => 'reservations');
resources/views/reservations.blade.php
<div class="container" id='app'>
<reservation-list></reservation-list>
</div>
Meanwhile you have to install npm and a pagination package in your Laravel project:
npm install
npm install vuejs-paginate --save
npm run watch
resources/assets/js/app.js
require('./bootstrap');
window.Vue = require('vue');
Vue.component(
'image-list',
require('./components/Bookings.vue')
);
Vue.component('paginate', require('vuejs-paginate'));
const app = new Vue({
el: '#app'
})
resources/assets/js/Components/Bookings.vue
<template>
<tbody>
<tr v-for="booking in bookings">
<td>{{ booking.booking_number | formatBookingNumber }}</td>
<td>{{ booking.date }}</td>
<td>{{ booking.status }}</td>
<td>{{ booking.check_in_date }}</td>
<td>{{ booking.check_out_date }}</td>
</tr>
</tbody>
<div class="centered">
<paginate
:page-count="pageCount"
:margin-pages="2"
:page-range="4"
:initial-page="0"
:container-class="'pagination'"
:click-handler="fetch"
:prev-text="'Prev'"
:next-text="'Next'"
></paginate>
</div>
</template>
<script>
export default {
data() {
return {
bookings: [],
endpoint: 'api/bookings-api'
};
},
created() {
this.fetch();
},
methods: {
fetch(page = 1) {
axios.get(this.endpoint + page)
.then(({data}) => {
this.dataset = data.data;
this.pageCount = data.meta.pagination.total_pages;
});
},
}
}
</script>
Hope it helped
you can try Vue Datatable package for this:
In your vue laravel application, you need to run below command just:
npm install --save vue-good-table
For more check this link:
Vue Laravel Tutorial Part 7 – Datatables
I am going to show you how to do it in simple way.Of course you need to change or add code to make this works in your app.Just try to understand the logic.
Vue.js component:
<template>
.....//here supposed to have more code
<tbody>
<tr v-for="booking in bookings">
<td>{{ booking.booking_number | formatBookingNumber }}</td>
<td>{{ booking.date }}</td>
<td>{{ booking.status }}</td>
<td>{{ booking.check_in_date }}</td>
<td>{{ booking.check_out_date }}</td>
<td>
</td>
</tr>
</tbody>
...
</template>
<script>
import axios from 'axios'
export default {
data() {
return {
bookings: [],
page: 1, //change the page regarding your next and previous pagination button
rowsPerPage: 15,
totalItems: 0
.....
}
},
created () {
axios.get('/bookings', {
params: {
page: this.page,
rowsPerPage: this.rowsPerPage
}
})
.then(response => {
this.bookings = response.data.bookings
this.totalItems = response.data.totalItems
})
}
}
</script>
In Laravel routes/api.php
Route::get('/bookings','ControllerName#controllerFunctionName');
Then in your function,in your Controller do the following:
$page = $request->get('page');
$rowsPerPage = $request->get('rowsPerPage');
$skip = ($page - 1) * $rowsPerPage;
$bookings = YouBookingsModel::select(here put your query)->skip($skip)->take($rowsPerPage)->get();
$bookingsCount = YouBookingsModel::all()->count();
return response()->json([
"bookings" => $bookings,
"totalItems" => $bookingsCount
], 200);
Note that you have to made it in your own. But also consider using a material frameworks. I am using Vuetify which is awesome!!And there go to dataTables and you can use your table with pagination in easy and vuetiful way
Related
Im using jQuery datatables for displaying my data in my users component in Vue.js, but when I run my code it displays the data but it has some text that says "No data found". Can someone help me with this? I really don't have any idea because I'm new in this Frontend tools.
Users.vue:
<template>
<table id="table" class="table table-striped table-bordered">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Email</th>
<th>Type</th>
<th>Created</th>
</tr>
</thead>
<tbody>
<tr v-for="user in users" :key="user.id">
<td>{{ user.id }}</td>
<td>{{ user.name }}</td>
<td>{{ user.email }}</td>
<td>{{ user.type }}</td>
<td>{{ user.created_at }}</td>
</tr>
</tbody>
</table>
</template>
<script>
export default {
data() {
return {
users: [],
form: new Form({
id: "",
name: "",
email: "",
password: "",
type: ""
})
};
},
methods: {
loadUsers() {
axios.get("api/user").then(({ data }) => (this.users = data));
}
},
created() {
console.log("Component mounted.");
this.loadUsers();
}
};
$(document).ready(function() {
$("#table").DataTable({});
});
</script>
Probably, you should init your widget DataTable after receiving data from api, more precisely in then method.
axios.get("api/user").then(({ data }) => {
this.users = data;
this.$nextTick(() => {
$("#table").DataTable({});
});
});
Explanation about Vue.$nextTick:
Defer the callback to be executed after the next DOM update cycle. Use
it immediately after you’ve changed some data to wait for the DOM
update. This is the same as the global Vue.nextTick, except that the
callback’s this context is automatically bound to the instance calling
this method.
axios.get("api/user").then(({ data }) => {
this.users = data;
$(function() {
$("#table").DataTable({});
});
});
i want to create a delete function with vue js in my laravel app.
here what i try
my .vue code
<tr v-for="(artist, index) in artists.data">
<td>{{ artist.artist_name }}</td>
<td>{{ artist.gender }}</td>
<td>{{ artist.created_at }}</td>
<td>{{ artist.updated_at }}</td>
<td>Edit | Delete</td>
my variable
data() {
return {
term:'',
disabled: 0,
artists: [],
results: [],
loading: false,
noResults: false,
SearchDiv: false,
IndexDiv: true
}
},
my delete method
deleteUser(id, index) {
axios.delete('/api/artist/'+id)
.then(resp => {
this.artists.splice(index, 1);
})
.catch(error => {
console.log(error);
})
}
error i get
TypeError: _this4.artists.splice is not a function
code above can delete data from database but not remove data from array result.
You are splicing data to its mother array.
Try this.
this.artists.data.splice(index, 1);
I have a function in component.ts as follow:
getImage(name) {
this._productService.getImage(name).subscribe((response) => {
// ??? my problem is here
});
}
and it's called here
<tr *ngFor="let i of data">
<td>{{ i.id }}</td>
<td><img [src]="getImage(i.image)" alt=""></td>
<td>{{ i.name }}</td>
<td>{{ i.price }}</td>
</tr>
So, how to my function return image?
P/S: my service get image from API ensure proper operation.
Thank for your help!
In your onInit use the below code,
this._productService.index().subscribe((data) => {
this.data = data;
console.log(data);
},
(error) => {
console.log(error);
},
() => {
this.data.forEach((element: IProduct) => {
element.image = element.image === null ? '' : this._productService.getImage((element.image));
});
});
As worked in teamviwer
I am having hard time inserting the values which is the id that is being passed from the form into the controller of my enrollment system. To achieve this I make use of vue.js and vue-resource library. In my all.js file I am gettting the correct id value when I console.log the id being passed. However, when passing it to the route address of my application I am getting 500 error. Also, upon debugging I' m getting this error SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'section_subject_id' cannot be null (SQL: insert into reservations. How can I solve this?
ReservationController.php
class ReservationController extends Controller
{
public function create($id)
{
$subjects = Subject::with('sections')->get();
return view('reservation.form',compact('subjects'));
}
public function store(Request $request)
{
$subject = new Reservation();
$subject->section_subject_id = $request->input('id');
$subject->student_id = 1;
$subject->save();
}
}
all.js
Vue.http.headers.common['X-CSRF-TOKEN'] = document.querySelector('#token').getAttribute('value');
new Vue({
el: '#app-layout',
data: {
subject: {
id : ''
},
subjects: []
},
ready: function(){
},
methods:{
addSubject: function(id){
this.subject = id;
this.$http({url: 'http://localhost:8000/reservation', id, method: 'POST'}).then(function(response){
}, function (response){
console.log('error');
});
}
}
});
form.blade.php
<body>
#foreach($subjects as $subject)
#foreach($subject->sections as $section)
<tr>
<td>{{ $section->section_code }}</td>
<td>{{ $subject->subject_code }}</td>
<td>{{ $subject->subject_description }}</td>
<td>{{ $section->pivot->schedule }}</td>
<td>{{ $subject->units }}</td>
<td>{{ $section->pivot->room_no }}</td>
<td>
<button
v-on:click="addSubject( {{ $section->pivot->id }} )"
class="btn btn-xs btn-primary">Add
</button>
<button class="btn btn-xs btn-info">Edit</button>
</td>
</tr>
#endforeach
#endforeach
</body>
Try formatting the data being sent like this: {id: this.id}
So your Vue addSubject Method looks like this:
addSubject: function(id){
this.subject = id;
this.$http({url: 'http://localhost:8000/reservation', {id: this.id}, method: 'POST'}).then(function(response){
}, function (response){
console.log('error');
});
}
I have this project that should fetch values from a pivot table and one to many relationship. When using the eloquent syntax I am getting the correct output as seen here:
ReservationController
public function index()
{
$secSubs = Student::find(1);
return $secSubs->sectionSubjects;
}
form.blade.php
#inject('reservation', 'App\Http\Controllers\ReservationController')
#foreach( $reservation->index() as $reserved )
<tr>
<td>{{ $reserved->section->section_code }}</td>
<td>{{ $reserved->subject->subject_code }}</td>
<td>{{ $reserved->subject->subject_description }}</td>
<td>{{ $reserved->schedule }}</td>
<td>{{ $reserved->subject->units }}</td>
<td>{{ $reserved->room_no }}</td>
<td>
<button class="btn btn-xs btn-danger">Delete</button>
</td>
</tr>
#endforeach
However I want to make use of the feature of vue js so that my page will automatically be populated with value being fetch as seen below.
new Vue({
el: '#app-layout',
data: {
subjects: []
},
ready: function(){
this.fetchSubjects();
},
methods:{
fetchSubjects: function(){
var self = this;
this.$http({
url: 'http://localhost:8000/reservation',
method: 'GET'
}).then(function (subjects){
self.subjects = subjects.data;
console.log('success');
}, function (response){
console.log('failed');
});
},
}
});
form.blade.php
<tr v-for="subject in subjects">
<td>#{{ subject.section.section_code }}</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>#{{ subject.room_no }}</td>
<td>
<button class="btn btn-xs btn-danger">Delete</button>
</td>
</tr>
As seen in my form.blade.php I cannot get the value of section_code. Am I missing something here?
UPDATE:
SectionSubject Model
class SectionSubject extends Model
{
protected $table = 'section_subject';
public function students()
{
return $this->belongsToMany(Student::class, 'section_subject_student','section_subject_id','student_id'
)->withTimestamps();
}
public function assignStudents(Student $student)
{
return $this->students()->save($student);
}
public function subject()
{
return $this->belongsTo(Subject::class);
}
public function section()
{
return $this->belongsTo(Section::class);
}
}
Student Model
public function sectionSubjects()
{
return $this->belongsToMany(SectionSubject::class,'section_subject_student', 'student_id','section_subject_id')
->withTimestamps();
}
Section Model
class Section extends Model
{
public function subjects()
{
return $this->belongsToMany(Subject::class)->withPivot('id','schedule','room_no');
}
public function sectionSubjects()
{
return $this->hasMany(SectionSubject::class);
}
}
it is not problem of laravel or vuejs.
this code.
this.$http({
url: 'http://localhost:8000/reservation',
method: 'GET'
}).then(function (subjects){
self.subjects = subjects.data;
console.log('success');
}, function (response){
console.log('failed');
});
you can see this ajax request will get answer in json.
and json is pretty much static content. as "Eloquent" within php scope its an object so if you ask relational data from it, it will execute call and return its relational data but json can not do that.
so to make it work you need to convert whole relational data and create one massive array which holds all relational data then encode it.
for example :
$user = App\User::with('roles')->first();
return $user->toJson();
now if you return this it will contain "user.roles.name" this value as we eagerly loaded that and converted to json.
in you case :
$subjects = App\Reservation::with('section')->all();
return $subjects->toJson();
now you can use subjects and loop it "subject.section.section_code" as section is eagerly loaded and added to array and converted to json.
I hope this will solve your problem.