I am developing project management app using laravel 5.2 and in my application user can create project and one project have many tasks and one task have many sub tasks. this is my relationship with each models
project Model
public function tasks(){
return $this->hasMany('App\Task');
}
Task Model
public function subtasks(){
return $this->hasMany(Subtask::class);
}
Subtask Model
public function task(){
return $this->belongsTo(Task::class);
}
this is my subtask input form in subtasks/form.blade.php
Add Sub Task
<form class="form-vertical" role="form" method="post" action="{{ route('subtasks.form', ['projectId'=> $projectId, 'taskId'=>$taskId])}}">
<div class="form-group{{ $errors->has('name') ? ' has-error' : '' }}">
<input type="text" name="task_name" class="form-control" id="name" value="{{ old('task_name') ?: '' }}">
#if ($errors->has('task_name'))
<span class="help-block">{{ $errors->first('task_name') }}</span>
#endif
</div>
<div class="form-group">
<button type="submit" class="btn btn-info">Create Task</button>
</div>
<input type="hidden" name="_token" value="{{ csrf_token() }}">
</form>
route
Route::get('projects/{projectId}/task/{taskId}/subtask', function ($projectId, $taskId) {
return view('subtasks/form',['projectId'=>$projectId,'taskId'=>$taskId]);
});
in my form file I can print $projectId and $ taskId as well but now I need print project_name and task_name regarding to ids how can I do this?
updated question
please see my subtask store methods
public function store(Request $request,$projectId,$taskId)
{
$subtask = new Subtask;
$subtask->subtask_name = $request->input('task_name');
$subtask->task_id = $taskId;
$subtask->project_id = $projectId;
$subtask->save();
//
}
You can do like so (Q&D solution):
Route::get('projects/{projectId}/task/{taskId}/subtask', function ($projectId, $taskId) {
$project = \App\ProjectModel::find($projectId);
$task = \App\TaskModel::find(taskId);
return view('subtasks/form',['project'=>$project,'task'=>$task]);
});
Note: In your form action, you will need to update the following :
['projectId'=> $projectId, 'taskId'=>$taskId]
By :
['projectId'=> $project->id, 'taskId'=>$task->id]
Related
How to show an old value / query field from database in mysql, and edit value in Laravel. I'm using Laravel 9x and PHP 8x
Controller.php :
public function edit(Business $business)
{
return view('dashboard.bisnis.edit', [
'item' => $business
]);
}
public function update(Request $request, Business $business)
{
$rules = [
'deskripsi' => 'required|max:255',
'pemilik' => 'required|max:255'
];
$validateData = $request->validate($rules);
Business::where('id', $business->id)->update($validateData);
return redirect('/dashboard/bisnis')->with('success', 'Item has been updated !');
}
Blade.php:
#extends('dashboard.index')
#section('container')
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
<h1 class="h2">Edit Data Bisnis</h1>
</div>
<div class="col-lg-8">
<form method="post" action="/dashboard/bisnis/{{ $item->id }}" class="mb-5" enctype="multipart/form-data">
#method('put')
#csrf
<div class="mb-3">
<label for="deskripsi" class="form-label">Deskripsi</label>
<input type="text" class="form-control #error('deskripsi') is-invalid #enderror" id="deskripsi" name="deskripsi" required autofocus
value="{{ old('deskripsi', $item->deskripsi) }}">
#error('deskripsi')
<div class="invalid-feedback">
{{ $message }}
</div>
#enderror
</div>
<div class="mb-3">
<label for="pemilik" class="form-label">Pemilik</label>
<input type="text" class="form-control #error('pemilik') is-invalid #enderror" id="pemilik" name="pemilik" required autofocus
value="{{ old('pemilik', $item->pemilik) }}">
#error('pemilik')
<div class="invalid-feedback">
{{ $message }}
</div>
#enderror
</div>
<button type="submit" class="btn btn-primary">Simpan Perubahan</button>
</form>
</div>
<script>
const deskripsi = document.querySelector('#deskripsi');
const pemilik = document.querySelector('#pemilik');
</script>
#endsection
Also when navigating through my menu such as Business, the sidebar seems cant to be clicked, nor use. Thank you so much
Please try like this:
{{ old('deskripsi') ? old('deskripsi') :$item->deskripsi }}
Please replace this:
return redirect('/dashboard/bisnis')->with('success', 'Item has been updated !');
to
return redirect()->back()->with('success', 'Item has been updated !');
I assume you use Laravel 9
Referring to Repopulating Forms - Validation
Controller.php:
you should use
$deskripsi = $request->old('deskripsi');
$pemilik = $request->old('pemilik');
before
$validateData = $request->validate($rules);
Blade.php:
you should use this on input
value="{{ old('deskripsi') }}"
value="{{ old('pemilik') }}"
By default old will return null if no input exists so we don't need to use nullcheck like
{{old('deskripsi') ?? ''}}
To repopulate value using old() in Laravel you need to return a response withInput(). Not just response.
The return code should
return redirect('/dashboard/bisnis')->with('success', 'Item has been updated !');
change to this
return redirect('/dashboard/bisnis')->with('success', 'Item has been updated !')->withInput();
The solution is i forgot to pass my $id on my controller and route (web.php). Here's my route
Route::controller(GroupServiceController::class)->middleware('auth')->group(function () {
Route::get('/dashboard/gruplayanan', 'index');
Route::get('/dashboard/gruplayanan/create', 'create')->name('gruplayanan.create');
Route::post('/dashboard/gruplayanan', 'store')->name('gruplayanan.store');
Route::get('/dashboard/gruplayanan/edit/{id}', 'edit')->name('gruplayanan.edit');
Route::post('/dashboard/gruplayanan/update/{id}', 'update')->name('gruplayanan.update');
Route::post('/dashboard/gruplayanan/delete/{id}', 'destroy')->name('gruplayanan.delete');
});
and my controller :
public function edit(GroupService $groupService, $id)
{
$groupService = $groupService->findOrFail($id);
return view('dashboard.gruplayanan.edit', [
'item' => $groupService
]);
}
I'm beginner in laravel and I want to update multiple checkboxes in database ..
when I click at update button automatically my inputs show old value also my permissions are checked by old value to update it ..
relation between user and permission is manytomany .. I have another table named userpermissions who has id_user and id_permission
this is my update form in ( edit.blade.php)
<form action="{{ url('users/'.$user->id) }}" method="POST">
#csrf
#method('PUT')
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label>Name</label>
<input type="text" name="name" id="name" required class="form-control" value="{{ $user->name }}">
#error('name')
<ul class="alert"><li class="text-danger">{{ $message }}</li></ul>
#enderror
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label>Email</label>
<input type="email" name="email" id="email" required class="form-control" value="{{ $user->email }}">
</div>
</div>
<div class="col-md-12">
<div class="form-group">
#foreach($permissions as $permission)
<input type="checkbox" name="data[]" value="{{ $permission->id }}"
<?php if( in_array($permission->id, $user->userPermissions->pluck('permission_id')->toArray())){ echo 'checked="checked"'; } ?>/>
{{ $permission->name }}
#if($loop->iteration % 3 == 0 ) <br> #else #endif
#endforeach
</div>
</div>
</div>
<div class="text-right mt-4">
<button type="submit" class="btn btn-primary"> Add</button>
</div>
</form>
and this is my controller where I think have a problem with methods :
edit function
public function edit(User $user)
{
$permissions = Permission::get();
return view('users.edit', compact('user','permissions'));
}
update function :
public function update(UserRequest $request,User $user)
{
$user->update(
$request->only('name', 'email')
);
$user->userPermissions()->save($request->input('data'));
return redirect()->back()->with('status','user updated !');
}
and this is my functio store :
public function store(UserRequest $request)
{
$this->validate($request, [
'name' => 'required',
'email'=>'required|email',
'password' => 'required|confirmed|min:6',
]);
$user = User::create(
$request->only('name', 'email', 'password')
);
$user->userPermissions()->createMany($request->input('data'));
return redirect()->back()->with('status','Utilisateur ajouté !');
}
Thanks for advance !
$user->userPermissions()->save($request->input('data'));
One important thing to understand here, is that save() on relation doesn't remove old values from pivot table, it just add more values to it(no distinction check). You need something like refresh functionality. Look at attaching\detaching or sync, second one is more convenient.
In first case before saving permissions you can do this
// remove all old permissions
$user->userPermissions()->detach();
// update them with new one
$user->userPermissions()->attach($request->input('data'));
In second case, which is less verbose then first one you just need to pass and array of permissions to user object.
// this will do both things which we did before
$user->userPermissions()->sync($request->input('data'))
But i encourage you to read the docs and ask questions after ;)
Another thing which i saw and its not related to the current topic is
$user->userPermissions->pluck('permission_id')->toArray()
you are using lazy load inside of foreach loop which means that on each iteration of the loop you are making a query to the database(N + 1 problem). You can preload/eager load userPermissions instead of loading them on a fly by declaring with relation in your User model like this
class User extends Model
{
/**
* The relationships that should always be loaded.
*
* #var array
*/
protected $with = ['userPermissions'];
...
}
and then in your User object will have userPermissions property which you can compare to permissions.
Hope that you get main idea and info was useful for you!
I have a question, I used the same blade template to create and insert. In my controller I created a variable ModificationMode on edit function and on the template I used isset() method.
Controller
public function edit($id)
{
$ModificationMode = 0;
$DataPraticien = \App\Praticien::find($id);
return view('AjoutePraticien', compact('DataPraticien'))->with('ModificationMode', $ModificationMode);
}
View
#if(isset($ModificationMode))
<form method="post" action="{{route('prat.update', $DataPraticien ?? '')}}">
#csrf
#method('PATCH')
#else
<form action="{{route('prat.store')}}" method="post">
#endif
//stuff
//stuff
I make every variable as optional. Is that a good idea? Can this method bring me some issues? How about security?
Here i am just explaining you with small example that how you use same form for add and edit. When I need to to the same I do this :
// routes.php
Route::get('test', 'TestController#create');
Route::get('test/{id}', 'TestController#edit');
Controller.php
// TestController.php
public function create()
{
return view('form');
}
public function edit($id)
{
$resource = Resource::find($id);
return view('form', compact('resource'));
}
Blade file
// form.blade.php
<h2>{{ isset($resource) ? 'Edit a Record' : 'Create a new Record' }}</h2>
<form action="{{ isset($resource) ? '/test/' . $resource->id : '/test' }}" method="post">
<label>Title</label>
<input type="text" name="title" value="{{ old('title', isset($resource) ? $resource->title : '') }}" />
<label>Description</label>
<textarea name="description">{{ old('description', isset($resource) ? $resource->description : '') }}</textarea>
<button type="submit">{{ isset($resource) ? 'Update' : 'Create' }}</button>
</form>
I think you are correct. If my form is simple then I do similar. Just a $ModificationMode variable does not require for me. what I do...
#if(isset($DataPraticien))
<form method="post" action="{{route('prat.update', $DataPraticien ?? '')}}">
#method('PATCH')
#else
<form action="{{route('prat.store')}}" method="post">
#endif
#csrf
This is my route :
Route::post('/store', 'EditlinkController#store');
My controller
public function index()
{
$id = $_GET['id'];
$links = DB::table('slugs')->where('slugs.id',$id)
->join('links','links.sid','=','slugs.id')
->get();
return view('editlink', ['links' => $links]);
}
public function store(Request $request, $id)
{
$url = $request->input('url');
$data =new link;
$sid = $id;
$data->sid = $sid;
$data ->url = $url;
$data ->save();
return redirect('/links');
}
And my view:
<form role="form" method='POST' action="{{url('store')}}">
<div class="entry input-group col-xs-3">
<input class="form-control" name="url" type='url' placeholder="https://..." size="100"/>
<input type="hidden" name="_Token" value="{{ csrf_token() }}">
<button type="submit" class="btn btn-primary" type="button">
<span class="material-icons md-12">add</span>
</button>
{{ csrf_field() }}
</div>
</form>
So basically here I want to call $id from index to store. I also have tried
Route::post('/store/{id}', 'EditlinkController#store');
But still doesn't work. Thank you.
Your route, /store/{id}, requires you to have a route parameter. Make sure you have an $id available to you before you generate your url for your form.
An example of what your open form tag should look like with the $id included:
<form role="form" method='POST' action="{{url('store', $id)}}">
I'm assuming the view editlink is where the markup for the form resides. If so, then you can simply pass the value of the id to your view from your controller:
return view('editlink', ['links' => $links, 'id' => $id]);
I'm learning Laravel from Lacast and i'm trying to create a CRUD application.I've implemented the index,show,create and store correctly,but with the edit form when i try to submit data it's throwing BadMethodCallException.
Here are my routes
Route::get('/projects','ProjectsController#index');
Route::get('/projects/{id}','ProjectsController#show')->where('id','[0-9]+');
Route::get('/create','ProjectsController#create');
Route::post('/projects','ProjectsController#store');
Route::get('/projects/{id}/edit','ProjectsController#edit')->where('id','[0-9]+');
Route::put('/projects/{id}','ProjectsController#update')->where('id','[0-9]+');
Route::delete('/projects/{id}','ProjectsController#destroy');
Here is the edit form:
#extends('template');
#section('content')
<h2>Create new project</h2>
<p>/projects/{{ $project->id }}</p>
<form method="POST" action="/projects/{{ $project->id }}">
{{ method_field('PUT') }}
{{ csrf_field() }}
<div>
<input value="{{ $project->title }}" type="text" name="title" id="title" placeholder="Project title">
</div>
<div>
<textarea name="description" placeholder="Enter the project description">{{ $project->description }}</textarea>
</div>
<div>
<button type="submit">Update project</button>
</div>
</form>
#endsection
The controller code:
public function edit($id){
$project= Project::find($id);
return view('projects.edit',compact('project'));
}
public function update($id){
$project= Project::find($id);
$project->title=request('title');
$project->description('description');
$project->save();
return redirect('/projects');
}
The edit form displays as expected with data coming from the database,after submit i get the following error page:
With the example of the instructor the code has worked perfectly,and before using the PUT either on my form and in my controller i used PATCH like the instructor but always the same result.
Here is the instructor video link: Faking PATCH and DELETE Requests
The error is pretty straightforward.
public function update($id){
$project= Project::find($id);
$project->title=request('title');
$project->description('description'); // You don't have a method description()
$project->save();
return redirect('/projects');
}
This is what you probably meant to do:
public function update($id)
{
$project= Project::find($id);
$project->title = request('title');
$project->description = request('description');
$project->save();
return redirect('/projects');
}