I am migrating my current application from Laravel Livewire to Laravel InertiaJS VueJS. Currently I am stuck at setting the per page count from the front end and paginate the data accordingly. Currently I am using Laravel's default pagination along with the custom pagination component for VueJS and it works seamlessly. I just want to set the $per_page as per the input, the variable is set to 5 by default, in the index method of the controller. Below is the code structure and the logic. Please help me achieve this in the way InertiaJS is meant to be used.
UserController.php
public function index(Request $request)
{
$per_page = \Request::get('per_page') ?: 5;
$query = User::select('id', 'name', 'email', 'role_id', 'created_at');
$users = $query->paginate($per_page);
return Inertia::render('Backend/Management/AudienceManagement/Users/Index', [
'users' => $users
]);
}
Users/Index.vue
<template>
<input-group borderless paddingless inline>
<input-select #change="setPerPage($event)" id="perPage" placeholder="Per Page">
<option value="5">5</option>
<option value="10">10</option>
</input-select>
</input-group>
</template>
<script>
import {
Inertia
} from '#inertiajs/inertia'
export default {
props: {
users: {
type: Object
}
},
data() {
return {
sortField: '',
sortDirection: ''
}
},
methods: {
setPerPage(event) {
console.log(event.target.value);
this.users.per_page = event.target.value;
Inertia.reload({
only: ['users.data']
});
},
}
}
</script>
Related
I build a shift planner as part of a larger vuejs 2 project, with a Cloud Firestore database, and when I try to set a work shift for a specific day for any employee, selecting the shift from a predefined list, the shift is saved in the database as expected, but it is not displayed on the dropdown as being selected. Here is my code:
<template>
<div>
<select v-model="selectedShift" #change="saveShift">
<option :value="{start:'00:00',end:'00:00',name:'',abreviation:'',duration:0,adjustedReason:''}"></option>
<option v-for="shift in shifts" :key="shift.name" :value="shift">{{ shift.abreviation }}</option>
</select>
</div>
<script>
import {db} from '#/firebase/init'
import randomstring from 'randomstring';
export default {
props: ['employee','date'],
data(){
return{
shifts: [],
selectedShift: '',
shift: {
start:'00:00',
end:'00:00'
},
//in order to get a unique name for each modal
modalName: '',
modalNameSent: ''
}
},
methods:{
saveShift(){
let id = `${this.employee.id}${this.date}`
db.collection('shifts').doc(id).update(this.selectedShift)
}
},
created(){
//retrieve defined shifts from db
db.collection('shifts_definition').where('service_id','==',this.employee.service_id).get().then(docs=>{
docs.forEach(doc=>{
this.shifts.push(doc.data())
})
})
let id = `${this.employee.id}${this.date}`;
let ref = db.collection('shifts').doc(id)
ref.onSnapshot(doc=>{
if(!doc.exists){
ref.set({
uid: randomstring.generate({length: 12,charset: 'alphabetic'}),
service_id: this.employee.service_id,
employee_id: this.employee.id,
adjustedReason:'',
date: this.date,
start:'00:00',
end:'00:00',
duration:0,
name:'',
abreviation:'',
})
}else{
this.selectedShift = doc.data()
this.shift = doc.data()
this.shift.id = doc.id
this.modalName = doc.data().uid
this.modalNameSent = '#'+doc.data().uid
}
});
}
}
</script>
How can I set a value input that uses the v-model?
I Googled for this problem but not solved
I have an input like this:
<input type="text" name="customer_email" v-model="form.customer_email" id="email">
I need to set this input value to {{ auth()->user()->email }}
TRY THIS :)
data() {
return {
form: {
customer_email: "",
}
}
},methods:{
user(){
axios.get("api/profile").then(({data})=>{
(this.user = data)
this.form.customer_emeail = this.user.email
})
},
},created(){
this.user();
}
In your controller add this
public function profile()
{
return auth('api')->user();
}
then put this in your api.php
Route::get('profile','YourController#profile');
As you are using two way data binding v-model, you can simply set this value in the vue end.
let app = new Vue({
el:"#app",
data() {
return {
form: {
customer_email: "{{ auth()->user()->email }}",
......
......
}
}
},
......
......
});
I am trying to implement an event calendar inside one of my vue components in Laravel but I am not able to display the events on the calendar from my SQL database. Although, I am able to view the columns of my table using my resource controller.
Note:- I am using router-view to display all the content under the id content so there are no blade templates.
Any help please!!
Thanks in advance.
Dashboard.vue
<template>
<full-calendar :config='config'>
</full-calendar>
</template>
<script>
export default{
data() {
return {
config: {
defaultView: "month"
},
methods:{
loadEvents() {
axios.get("api/event").then(({ data }) => (this.events = data));
}
},
created(){
this.loadEvents();
}
};
</script>
Controller type:resource
public function index()
{
$events = DB::table('events')->get();
$event = [];
foreach($events as $row){
$endDate = $row->end_date."24:00:00";
$event[] = \Calendar::event(
$row->event_title,
true,
new \DateTime($row->start_date),
new \DateTime($row->end_date),
$row->id,
[
'color'=>$row->color,
]
);
}
$calendar = \Calendar::addEvents($event);
return $events;
}
class CreateEventsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('events', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users');
$table->string('event_title');
$table->string('event_description');
$table->string('color');
$table->datetime('start_date');
$table->datetime('end_date');
$table->timestamps();
});
}
};
I have a form and a live preview of what the form will create.
My model
//campaign.js
export default Model.extend({
title: attr('string'),
body: attr('string')
});
In the route
// new.js
export default Ember.Route.extend({
model () {
return this.store.createRecord('campaign', {
title: null,
body: null
})
}
});
My current implementation uses a component for the input
export default Ember.Component.extend({
keyPress(event) {
// binding code
}
});
And in the template
{{#title-input}}
{{/title-input}}
<div id="title-preview"></div>
My Feeling is that there is a cleaner or more idiomatic way to do this. I am new to ember so thank you for any help
While the use of Components are compelling they aren't required for capturing form input in ember. For what what its worth. For simple form input the route could be:
setupController() {
Ember.set('controller','newCampaign', {}); //set empty newCampaign
},
# Action hash would create the new record but only when you have some data.
actions: {
createCampaign(newCampaign) {
let newRecord = this.store.createRecord('campaign', newCampaign); //create record
newRecord.save().then(( /* response */ ) => {
this.transitionTo('campaigns'); //transition to different page.
}, (error) => { // Deal with an adapter error
//handle error
//rollback if necessary
});
}
}
The form or template could be:
{{input name="title" id="title" value=newCampaign.title type="text"}}
{{input name="body" id="body" value=newCampaign.body type="text"}}
Just a suggestion.
Jeff
I have to add/post data form. But the form dynamically can increase as user 'click' on a button. I've already browse about it and there some answer i get like using $request->all() to fetch all data from input forms.
And then my problem is, my app using VueJS as front-end. Is there any some configuration on VueJS script to post all data from that dynamic form??
My Blade template that will be increase dynamically:
<div id="form-message">
{!! Form::text('rows[0][DestinationNumber]', null, [
'id' => 'recipient',
'class' => 'form-control',
'v-model' => 'newMessage.DestinationNumber'
])
!!}
{!! Form::textarea('rows[0][TextDecoded]', null, [
'rows' => '3',
'id' => 'recipient',
'class' => 'form-control',
'v-model' => 'newMessage.TextDecoded'
])
!!}
</div>
That zero number will increase depends on how much user click add button.
And then here my VueJS script
var newSingleMessage = new Vue({
el: '#newsinglemsg',
data: {
newMessage: {
DestinationNumber: '',
TextDecoded: ''
},
},
methods: {
onSubmitForm: function(e) {
e.preventDefault();
var message = this.newMessage;
this.$http.post('api/outbox', message);
message = { DestinationNumber: '', TextDecoded: '' };
this.submitted = true;
}
}
});
On laravel controller, i have simple logic to test result how data passed.
$input = $request->all();
$output = dd($input);
return $output;
And, I test it using 2 additional form. So, the data should be 3 rows. The result (checked from FireBug) to be like this
{"DestinationNumber":"1234567890","TextDecoded":"qwertyuio"}
Data passed just one, and then the type is JSON. Even I use return $output->toArray(), type still JSON.
Oh yeah, once more. Idk how to make the zero number increase dynamically using javascript. When testing, i just manual add the form. Here my add click function javascript
var i = 0,
clone = $('#form-message').clone(),
recipient = document.getElementById('recipient');
recipient.setAttribute('name', 'rows['+ i +'][DestinationNumber]');
clone.appendTo('.form-message:last');
i++;
For second and next rows, name attribute not added on the input elements.
Thanks
You're mixing blade and jquery and vue in a way that is pretty confusing. Check out this JS fiddle that accomplishes all of this with Vue:
https://jsfiddle.net/cr8vfgrz/10/
You basically have an array of messages that are automatically mapped to inputs using v-for. As those inputs change, your messages array changes. Then when submit is pressed, you just post this.messages and the array of messages is sent to server. Then you can clear the array to reset the form.
Template code:
<div id="form-message">
<button class="btn btn-default" #click="addNewMessage">New Message</button>
<template v-for="message in messages">
<input type="text" v-model="message.DestinationNumber" class="form-control">
<textarea rows="3" v-model="message.TextDecoded" class="form-control"></textarea>
</template>
<button class="btn btn-success" #click.prevent="submitForm">Submit</button>
</div>
Vue code:
var newSingleMessage = new Vue({
el: '#form-message',
data: {
messages: [
{
DestinationNumber: '',
TextDecoded: ''
}
],
submitted:false
},
methods: {
addNewMessage: function(){
this.messages.push({
DestinationNumber: '',
TextDecoded: ''
});
},
submitForm: function(e) {
console.log(this.messages);
this.$http.post('api/outbox', {messages:this.messages})
.then(function(response){
//handle success
console.log(response);
}).error(function(response){
//handle error
console.log(response)
});
this.messages = [{ DestinationNumber: '', TextDecoded: '' }];
this.submitted = true;
}
}
});
Edit:
In the controller you can use $request->input('messages'); which will be the array of messages. You can insert multiple new Outbox model using:
Outbox::insert($request->input('messages'));
or
foreach($request->input('messages') as $message){
Outbox::create($message);
}