Vue / Laravel - Dynamic multiple form saving data - laravel

I have a dynamic form that successfully adds multiple field by a click of the button. My problem comes when saving the data in the database. I want to be able to save in the employee_id field the id of the Auth::user.
This is my current set of code. Should I use a different approach such as for loop instead of foreach?
Component.vue
<tr v-for="(row, index) in rows" :key="row.id">
<td><base-select
:items="department_objectives"
item-text="department_objective"
item-value="id"
label="Department Objectives"
/></td>
<td><v-textarea label="KPA" placeholder=" " class="mr-2" rows="1" outlined v-model="row.kpa" /></td>
<td><v-textarea label="KPI" placeholder=" " class="mr-2" rows="1" outlined v-model="row.kpi" /></td>
<td><v-text-field label="Weight" placeholder=" " class="mr-2" outlined v-model="row.weight" /></td>
<td><v-text-field label="Score" placeholder=" " class="mr-2" outlined :disabled="disabled" filled v-model="row.score" /></td>
<td><a #click="removeElement(index);" style="cursor: pointer">Remove</a></td>
</tr>
addRow () {
this.rows.push({
kpa: '',
kpi: '',
weight: '',
score: '',
equal: '',
});
save () {
axios
.post('/api/employee-objective', { data: this.rows })
.then(res => { console.log(res) })
.catch(err => { console.log(err) });
}
Controller.php
public function store(Request $request) {
foreach($request->data as $data) {
$container = EmployeeObjective::updateOrCreate([
'employee_id' => // insert ID
'kpa_info' => $data['kpa'],
'kpi_info' => $data['kpi'],
'kpa_weight' => $data['weight'],
'kpa_score_1' => $data['score'],
'kpa_equal' => $data['equal'],
]);
$container->save();
}
}

It's fine using foreach as long all data you want is available like the key
to put the id of authenticated user in employee_id just put this one
Auth::id();
and put it above your code
use Auth;

I managed to make it work, somehow this syntax works. Hopefully someone could enlighten me more about this.
Controller.php
public function store(Request $request)
// This works
foreach($request->rows as $data) {
$test = new EmployeeObjective;
$test->employee_id = $request->id;
$test->kpa_info = $data['kpa'];
$test->save();
// This does not work
foreach($request->rows as $data) {
EmployeeObjective::updateOrCreate([
'employee_id' => $request->id,
'kpa_info' => $data['kpa'],
Now here is the tricky part. I saved the data from the $store to my local object and passed it during the save method.
Component.vue
created () {
this.auth = this.$store.state.authUser.id
},
save () {
axios.post('/api/employee-objective', {
rows: this.rows,
id: this.auth
})
.then(res => { console.log(res) })
.catch(err => { console.log(err) });
}

Related

Vus.js Laravel Update records not working

i am beginner of vue.js and laravel programming successfully done add records and view records from the database.but i can't update the records.when check the error through the console. it displayed the following
Failed to load resource: the server responded with a status of 404 (Not Found)
i don't know how to solve them.my api is working successfully.
what i done so far i attached below.
Laravel
Routes
Route::put('/update/{id}',[App\Http\Controllers\ContactController::class, 'update']);
ContactController
public function update(Request $request, $id)
{
$contact = new Contact([
'name' => $request->name,
'address' => $request->address,
'nic' => $request->nic
]);
$contact->update();
return response()->json('Contact Updateddd!');
}
Model
class Contact extends Model{
protected $table = "contact";
protected $primaryKey = "id";
protected $fillable = ["name", "address", "nic"];
}
Front End Vue JS
Save records and Updating records i adding the same form with validation. save is working but update dosen't working.
<form #submit.prevent="save">
<div class="form-group">
<label>Employee Name</label>
<input v-model="task.name" type="text" class="form-control">
</div>
<div class="form-group">
<label>Employee Address</label>
<input v-model="task.address" type="text" class="form-control" >
</div>
<div class="form-group">
<label>Nic</label>
<input v-model="task.nic" type="text" class="form-control">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
table records view from the database successfullly i attached code below. each rows i put the edit button for edit. when i click the edit button editable row records are passing to the form successfully. after that make the changes and click edit records not i updated what is the error i got i attached above.
table code
<td>{{ task.id }}</td>
<td>{{ task.name }}</td>
<td>{{ task.address }}</td>
<td>{{ task.nic }}</td>
<td>
<button type="button" class="btn btn-primary" #click="edit(task)">Edit</button>
<button type="button" class="btn btn-danger" #click="remove(task)">Delete</button>
</td>
Save and update code . save is working update only not working please check the update code
i attached the full code for easy to find out the error.
import Vue from 'vue';
import axios from 'axios';
Vue.use(axios)
export default {
name: 'Crud',
data () {
return {
result: {},
task:{
id: '',
name: '',
address: '',
nic: ''
}
}
},
created() {
console.log("created() called.....");
this.loadTaks();
},
mounted() {
console.log("mounted() called.......");
},
methods: {
loadTaks()
{
Vue.use(axios);
console.log("LoadTasks() calling....");
// var page = "http://localhost:8088/api/v1/employee/get-all-employees";
var page = "http://127.0.0.1:8000/api/contact";
axios.get(page)
.then(
({data})=>{
console.log(data);
this.result = data;
}
);
},
save()
{
if(this.task.id == '')
{
this.saveData();
}
else
{
this.updateData();
}
},
saveData()
{
axios.post('http://127.0.0.1:8000/api/save', this.task)
.then(
({data})=>{
this.loadTaks();
this.task.name = '';
this.address = '',
this.nic = '',
alert("saved!!!");
}
)
},
updateData()
{
var url = '127.0.0.1:8000/api/update/'+this.task.id;
axios.put(url, this.task)
.then(
({data})=>{
this.task.name = '';
this.address = '',
this.nic = ''
this.id = ''
alert("Updated!!!");
this.loadTaks();
}
);
},
edit(task){
this.task = task;
},
remove(task){
var url = 'http://127.0.0.1:8000/api/contact/delete/'+this.task.id;
axios.delete();
}
}
}
</script>
Have a problem on the controller update funtion what was the error here
public function update(Request $request, $id)
{
$contact = new Contact([
'name' => $request->name,
'address' => $request->address,
'nic' => $request->nic
]);
$contact->update();
return response()->json('Contact Updateddd!');
}

Vue / Laravel - Axios post multiple field

I created a component that can add additional fields by pressing a button. I don't know how would I submit this in the database with axios.post and laravel controller. I was able to achieve it in the past with the use of jquery and pure laravel, but I'm confused how to implement it in vue and axios.
Component.vue
<template>
<v-app>
<table class="table">
<thead>
<tr>
<td><strong>Title</strong></td>
<td><strong>Description</strong></td>
<td><strong>File</strong></td>
<td></td>
</tr>
</thead>
<tbody>
<tr v-for="(row, index) in rows" :key="row.id">
<td><v-text-field outlined v-model="row.title" /></td>
<td><v-text-field outlined v-model="row.description" /></td>
<td>
<label class="fileContainer">
<input type="file" #change="setFilename($event, row)" :id="index">
</label>
</td>
<td><a #click="removeElement(index);" style="cursor: pointer">X</a></td>
</tr>
</tbody>
</table>
<div>
<v-btn #click="addRow()">Add row</v-btn>
<v-btn class="success" #click="save()">Save</v-btn>
<pre>{{ rows | json}}</pre>
</div>
</v-app>
</template>
<script>
export default {
data: ()=> ({
rows: []
}),
methods: {
addRow() {
var elem = document.createElement('tr');
this.rows.push({
title: "",
description: "",
file: {
name: 'Choose File'
}
});
},
removeElement(index) {
this.rows.splice(index, 1);
},
setFilename(event, row) {
var file = event.target.files[0];
row.file = file
},
save() {
// axios.post
}
}
}
</script>
Controller.php
public function store(Request $request)
{
// store function
}
save() {
let data = this.rows
axios
.post("Url", {
data
})
.then((res) => {
console.log(res);
})
.catch((err) => {
console.log(err)
});
}
ref link https://github.com/axios/axios
save() {
axios
.post("/your/uri", {
user_id: 1,
user_name:'jhone doe',
email:'test#test.com'
})
.then(response => {
console.log(response);
})
.catch(error => {
console.log(error)
});
}
You can retrieve your data from your controller $request->user_id,...,$request->email
Tip: if you post any object,you must JSON.stringify(your_json) them and in a response data from controller json_decode($your_json,true) or you need to modify your header file.
Always use '/your/uri' instead of /your/uri/ without trailing '/'
It now works. I'll be posting my code just in case someone encounter the same hurdle. Than you very much to #kamlesh-paul and #md-amirozzaman
Component.vue
<script>
export default {
data: ()=> ({
rows: [],
}),
methods: {
addRow() {
this.rows.push({
corporate_objective_id: '',
kpa: '',
kpi: '',
weight: '',
score: '',
equal: '',
file: {
name: 'Choose File'
}
});
},
removeElement(index) {
this.rows.splice(index, 1);
},
setFilename(event, row) {
var file = event.target.files[0];
row.file = file
},
save() {
const postData = {
data: this.rows
}
console.log(postData)
axios
.post('/api/employee-objective', {postData})
.then(res => { console.log(res) })
.catch(err => { console.log(err) });
}
}
}
</script>
Controller.php
public function store(Request $request) {
foreach($request->data as $data) {
$container = EmployeeObjective::updateOrCreate([
'kpa_info' => $data['kpa'],
'kpi_info' => $data['kpi'],
'kpa_weight' => $data['weight'],
'kpa_score_1' => $data['score'],
'kpa_equal' => $data['equal'],
]);
$container->save();
}
}

Error 405: Method not allowed, EditUser route can't get info

So I've been learning Laravel and was getting into making DataTables. However, my 'editItem' route is not being able to get any information when I click 'Edit' button. It shows Error 405.
DataTable view (dt.blade.php) -
HTML part where the table is displayed
<div class="table-responsive text-center">
<table class="table table-borderless" id="table">
<thead>
<tr>
<th class="text-center">ID</th>
<th class="text-center">Name</th>
<th class="text-center">Created At</th>
<th class="text-center">Updated At</th>
<th class="text-center">Actions</th>
</tr>
</thead>
#foreach($users as $user)
<tr class="user{{$user->id}}">
<td >{{$user->id}}</td>
<td>{{$user->name}}</td>
<td>{{$user->created_at}}</td>
<td>{{$user->updated_at}}</td>
<td><button class="edit-modal btn btn-info"
value="{{$user->id}},{{$user->name}}">
<span class="glyphicon glyphicon-edit"></span> Edit
</button>
<button class="delete-modal btn btn-danger"
value="{{$user->id}},{{$user->name}}">
<span class="glyphicon glyphicon-trash"></span> Delete
</button></td>
</tr>
#endforeach
</table>
</div>
JS part in the same file
<script>
$(document).ready(function() {
$('#table').DataTable();
} );
</script>
<script>
$(document).on('click', '.edit-modal', function() {
$('#footer_action_button').text("Update");
$('#footer_action_button').addClass('glyphicon-check');
$('#footer_action_button').removeClass('glyphicon-trash');
$('.actionBtn').addClass('btn-success');
$('.actionBtn').removeClass('btn-danger');
$('.actionBtn').removeClass('delete');
$('.actionBtn').addClass('edit');
$('.modal-title').text('Edit');
$('.deleteContent').hide();
$('.form-horizontal').show();
var stuff = $(this).val().split(',');
console.log($(this).val());
fillmodaluser(stuff)
$('#myModal').modal('show');
});
$(document).on('click', '.delete-modal', function() {
$('#footer_action_button').text(" Delete");
$('#footer_action_button').removeClass('glyphicon-check');
$('#footer_action_button').addClass('glyphicon-trash');
$('.actionBtn').removeClass('btn-success');
$('.actionBtn').addClass('btn-danger');
$('.actionBtn').removeClass('edit');
$('.actionBtn').addClass('delete');
$('.modal-title').text('Delete');
$('.deleteContent').show();
$('.form-horizontal').hide();
var stuff = $(this).val().split(',');
console.log($(this).val('info'));
$('.did').text(stuff[0]);
$('.dname').html(stuff[1]);
$('#myModal').modal('show');
});
function fillmodaluser(details){
$('#fid').val(details[0]);
$('#name').val(details[1]);
}
$('.modal-footer').on('click', '.edit', function() {
$.ajax({
type: 'post',
url: '../public/editUser',
user: {
'_token': $('input[name=_token]').val(),
'id': $('#fid').val(),
'name': $('#name').val()
},
success: function(user) {
if (user.errors){
$('#myModal').modal('show');
if(user.errors.name) {
$('.name_error').removeClass('hidden');
$('.name_error').text("Name can't be empty !");
}
if(user.errors.email) {
$('.email_error').removeClass('hidden');
$('.email_error').text("Email must be a valid one !");
}
}
else {
$('.error').addClass('hidden');
$('.user' + users.id).replaceWith("<tr class='users" + users.id + "'><td>" +users.id + "</td><td>" + users.name+"</td><td>" + "</td><td>" + "</td><td><button class='edit-modal btn btn-info' user-info='" + users.id+","+users.name+"'><span class='glyphicon glyphicon-edit'></span> Edit</button> <button class='delete-modal btn btn-danger' user-info='" + users.id+","+users.name+"' ><span class='glyphicon glyphicon-trash'></span> Delete</button></td></tr>");
}}
});
});
$('.modal-footer').on('click', '.delete', function() {
$.ajax({
type: 'post',
url: '../public/deleteUser',
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
user: {
'_token': $('input[name=_token]').val(),
'id': $('.did').text()
},
success: function(user) {
$('.user' + $('.did').text()).remove();
}
});
});
</script>
And lastly, the web.php
Route::get('/dt', 'UserController#dt');
Route::get('/editUser', function (Request $request) {
$rules = array (
'name' => 'required|alpha',
);
$validator = Validator::make(Input::all(), $rules );
if ($validator->fails ())
return Response::json ( array (
'errors' => $validator->getMessageBag()->toArray ()
) );
else {
$user->id = User::find ( $request->id );
$user->name = ($request->name);
$user->save ();
return response ()->json ( $user );
}
});
Route::get ('/deleteUser', function (Request $request) {
User::find ( $request->id )->delete ();
return response ()->json ();
});
The JSON error that shows to me is "{"errors":{"name":["The name field is required."]}}"
My question is that, the info can be split fine in the JQuery here when I press the Edit button; it is able to show the info of the row I've selected. I don't understand why the same values aren't getting sent to my editUser route?
change all get method to post , because you are using post in client side
Route::post('/dt', 'UserController#dt');
Route::post('/editUser', function (Request $request) {
$rules = array (
'name' => 'required|alpha',
);
$validator = Validator::make(Input::all(), $rules );
if ($validator->fails ())
return Response::json ( array (
'errors' => $validator->getMessageBag()->toArray ()
) );
else {
$user->id = User::find ( $request->id );
$user->name = ($request->name);
$user->save ();
return response ()->json ( $user );
}
});
Route::post ('/deleteUser', function (Request $request) {
User::find ( $request->id )->delete ();
return response ()->json ();
});
Seems your urls should not be '../public/' (in your ajax requests) but it should match what you typed in your file web.php

I can not save values using POST method - laravel vue

I'm trying to save the data I send from the Event view. in the storeEvent method of the EventController driver but it gives me error 422 and I can not find the problem so far.
The Event model has a many-to-many relationship with the Categories model, and Event also has a many-to-many relationship with the Coins model, which is why I occupy vue-multiselect since the user can select several categories or several coins for the same event
Event.vue
<template>
<form v-on:submit.prevent="createdEvent" class="form-horizontal">
<div class="form-group row">
<label>Titulo</label>
<input type="text" name="title" maxlength="25" v-model="title">
</div>
<div class="form-group row">
<label>*Cryptodivisas</label>
<multiselect v-model="coinvalue" :options="coins"
:multiple="true" label="name"
track-by="id" placeholder="Seleccione">
</multiselect>
</div>
<div class="form-group row">
<label>*Categoría</label>
<multiselect v-model="categoryvalue" :options="categories"
:multiple="true" label="name"
track-by="id" placeholder="Seleccione">
</multiselect>
</div>
<div class="col-sm-12">
<button class="btn" type="submit">Crear evento</button>
</div>
</form>
<script>
import Multiselect from 'vue-multiselect';
export default {
components: {
Multiselect,
},
props: ['auth'],
data () {
return {
user: {},
title: '',
coins: [],
coinvalue: [],
categories: [],
categoryvalue: [],
}
},
created() {
this.getCoins();
this.getCategories();
},
mounted() {
this.user = JSON.parse(this.auth);
},
methods: {
getCoins(){
let urlCoin = '/dashboard/coins';
axios.get(urlCoin)
.then((response) => {
this.coins = response.data;
})
.catch((err) => {
})
},
getCategories(){
let urlCategories = '/dashboard/categories';
axios.get(urlCategories)
.then((response) => {
this.categories = response.data;
})
.catch((err) => {
})
},
createdEvent(){
let urlEvent = '/dashboard/newEvent';
const eventData = {
'id' : this.user.id,
'title' : this.title,
'coin' : this.coinvalue,
'category' : this.categoryvalue,
}
console.log(eventData);
axios.post(urlEvent, eventData)
.then((response) => {
console.log(ok);
})
.catch((err) => {
console.log(err.response.data);
})
}
</script>
storeEvent (EventController)
public function storeEvent(Request $request)
{
$this->validate($request, [
'title' => 'required|max:25',
'coin' => 'required',
'category' => 'required',
]);
$userAuth = Auth::user()->id;
$userEvent = $request->id;
if($userAuth === $userEvent){
$event = new Event;
$event->user_id = $userEvent;
$event->title = $request->title;
if($event->save()){
$event->coins()->attach($request->coin);
$event->categories()->attach($request->category);
return response()->json([
'status' => 'Muy bien!',
'msg' => 'Tu evento ya fue creado con éxito.',
], 200);
}
else {
return response()->json([
'status' => 'Error!',
'msg' => 'No pudimos crear tu evento.',
], 401);
}
}
}
I think the problem may be when I assign the values to the coin () -> attach () and category () -> attach () section, but I have no idea how to solve it due to my inexperience in the tool.
The system was made entirely in Laravel and it worked without problems, now that it is being updated with Vue it began to give inconveniences.
Any ideas? I occupy Laravel 5,6, Vuejs 2, Axios and Vue-multiselect 2
Try sending form data
Here is the example for you.
var urlEvent = '/dashboard/newEvent';
var form_data = new FormData();
form_data.append('id',this.user.id);
form_data.append('title',this.title);
for(let coin of this.coinvalue)
form_data.append('coin[]', coin);
for(let category of this.categoryvalue)
form_data.append('category[]', category);
axios(urlEvent,{
method: "post",
data: form_data
})
.then(res => {
console.log(ok);
})
.catch(err => {
console.log(err.response.data);
});
If this stills gives you a 422 status code (Unprocessable entities). Then try returning $request in you controller. And check what data are actually send to the controller and what your validation is.
422 means validation error so do a console.log or inspect the element on axios call and check that :
'title' : this.title,
'coin' : this.coinvalue,
'category' : this.categoryvalue,
Are not empty, cause right now some data from above is missing since its a 422 validation exception.

Laravel + Datatables, how to pass id to the controller?

I want to start using Datatables on my Laravel project, so I have followed this tutorial: https://youtu.be/ejj-078OvfY
It works well, but I can't figure it out how to pass a parameter to my controller since that route is being called by an AJAX call through a JavaScript function on the view.
It may sound a bit weird if you are not familiarized with the tutorial, so let me show you how this is setup:
ROUTE:
Route::get('/client/{id}', array('before' => 'auth', 'as' => 'getClient', 'uses' => 'ClientsController#getClient'));
Route::get('getAllParticipants', array('before' => 'auth', 'as' => 'getAllParticipants', 'uses' => 'ClientsController#showAllParticipants'));
CONTROLLER:
public function getClient() {
return View::make('/forms/dashboard_clients');
}
public function showAllParticipants () {
$allParticipants = User::where('users.id', '=', $id) //I need the ID parameter here
->join('users_roles', 'users.id', '=', 'users_roles.user_id')
->where('users_roles.role_id', '!=', Role::USER_PARTICIPANT)
->groupBy('users.id')
->get();
return Datatable::collection($allParticipants)
->searchColumns('firstname', 'lastname', 'email')
->orderColumns('firstname', 'lastname', 'email')
->addColumn('firstname', function ($model) {
return $model->firstname;
})
->addColumn('lastname', function ($model) {
return $model->lastname;
})
->addColumn('email', function ($model) {
return $model->email;
})
->make();
}
VIEW:
<div class="row">
<div class="col-md-12">
<table id="allParticipants" class="table table-striped table-hover">
<thead>
<tr>
<th scope="col">#lang('table.headers.fname')</th>
<th scope="col">#lang('table.headers.lname')</th>
<th scope="col">#lang('table.headers.email')</th>
<th scope="col">#lang('table.headers.action')</th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
</div>
</div>
<script type="text/javascript">
var allParticipants=null;
$(document).ready(function(){
allParticipants = $('#allParticipants').dataTable({
"ajax": "/getAllParticipants",
"lengthMenu": [[10, 50, 100, -1], [10, 50, 100, "All"]]
});
});
</script>
So to summarize, the user lands into the /client/{id} route where the view gets printed. From that view, the JavaScript identifies the table by its id and it sends an Ajax call that triggers the getAllParticipants route where a collection of participants gets sent to the view.
Any idea on how can I specify an ID parameter to that showAllParticipants function on my controller?
From what i can see you want to be able to set an ID parameter on a route, that's simple enough, the question is how Datatables makes that AJAX request, does it send an ID when it makes the "getAllParticipants" call?
If so you can go about it in two ways, either you set an ID on that route like you did for the client route. Or you use a traditional GET parameter and fetch it by calling $request->input('paramname') in your controller.
What confuses me is that your Datatable is not sending any data it's just calling the Controller route without sending any data.
To send data it should i believe look like this
$('#example').dataTable( {
"ajax": {
"url": "/getAllParticipants",
"data": {
"id": 451
}
}
} );
or alternatively
$('#example').dataTable( {
"ajax": {
"url": "/getAllParticipants?id=" + 451
}
} );
This way in my controller i would inject the Request class and get the "id" from that
public function showAllParticipants (Request $request) {
$id = $request->input('id');
$allParticipants = User::where('users.id', '=', $id) //I need the ID parameter here
->join('users_roles', 'users.id', '=', 'users_roles.user_id')
->where('users_roles.role_id', '!=', Role::USER_PARTICIPANT)
->groupBy('users.id')
->get();
return Datatable::collection($allParticipants)
->searchColumns('firstname', 'lastname', 'email')
->orderColumns('firstname', 'lastname', 'email')
->addColumn('firstname', function ($model) {
return $model->firstname;
})
->addColumn('lastname', function ($model) {
return $model->lastname;
})
->addColumn('email', function ($model) {
return $model->email;
})
->make();
}

Resources