Hope you're all fine.
I have an article, and I want to be able to edit it. Inside the article, I have checkboxs, and what I want is to check the ones I've checked when I first create the article (Im using a pivot table).
I have this code for now.
public function createArticle(Request $request)
{
$data = $request->validate([
'titreArticle' => 'bail|required|between:5,40',
'typeArticle' => 'bail|required',
'themeCheckbox' => 'required',
'themeCheckbox.*' => 'required',
'contenuArticle' => 'bail|required',
]);
$type_articles = Type_article::findOrFail($data['typeArticle']);
$article = new Article();
$article->type_article()->associate($type_articles);
$themes = Theme::whereIn('theme_id', array_keys($data['themeCheckbox']))->get();
$article->titre = $data['titreArticle'];
$article->contenu = $data['contenuArticle'];
$article->save();
$article->theme()->attach( $themes);
return view('admin');
}
And inside my view :
#foreach ($themes as $theme)
<div class="form-check form-check-inline">
<input class="form-check-input" type="checkbox" name="themeCheckbox[{{$theme->theme_id}}]" value="1" >
<label class="form-check-label">{{ $theme->nom_theme }}</label>
</div>
#endforeach
I've seen I must use contains but don't really know how to use it...
Cordially
Related
I am creating an online bookstore in Laravel, and upon creating a new book, the administrator is able to define which warehouses that are able to stock this book, by checking the specific warehouses checkboxes.
To give insight in how it works, this is my create function:
public function create()
{
$authors = Author::all();
$selectedAuthor = Book::first()->author_id;
$publishers = Publisher::all();
$selectedPublisher = Book::first()->publisher_id;
$warehouses = Warehouse::all();
$selectedWarehouse = Book::first()->warehouse_id;
return view('books.create', compact(['authors', 'publishers', 'warehouses'],
['selectedAuthor', 'selectedPublisher', 'selectedWarehouse']
));
}
and my store method:
public function store(Request $request)
{
$request->validate([
'ISBN' => 'required',
'author_id' => 'required',
'publisher_id' => 'required',
'year' => 'required',
'title' => 'required',
'price' => 'required',
]);
try {
$book = Book::create($request->all());
foreach ($request->checked as $value){
$book->warehouses()->attach([$value]);
}
return redirect()->route('books.index')
->with('success','Book created successfully.');
} catch (\Illuminate\Database\QueryException $e) {
var_dump($e->errorInfo);
}
}
But when an administrator edits a book, the checkboxes that were checked upon creating the book, should be "checked", and the administrator should be able to attach more warehouses, and be able to "unselect" a warehouse, so if an already checked value gets unchecked and sumbitted, it should get detached from the many-to-many table.
This is what i currently have:
My edit method:
public function edit(Book $book)
{
$authors = Author::all();
$selectedAuthor = Book::first()->author_id;
$publishers = Publisher::all();
$selectedPublisher = Book::first()->publisher_id;
$warehouses = Warehouse::all();
$selectedWarehouse = Book::first()->warehouse_id;
return view('books.edit', compact(['book', 'authors', 'publishers', 'warehouses'],
['selectedAuthor', 'selectedPublisher', 'selectedWarehouse']));
}
And my update method:
public function update(Request $request, Book $book)
{
$request->validate([
'ISBN' => 'required',
'publisher_id' => 'required',
'author_id' => 'required',
'year' => 'required',
'title' => 'required',
'price' => 'required',
]);
try {
$book->update($request->all());
// TODO: Update warehouses
return redirect()->route('books.index')
->with('success','Book updated successfully.');
} catch (\Illuminate\Database\QueryException $e) {
var_dump($e->errorInfo);
}
}
And the checkboxes in my edit.blade view:
#foreach($warehouses as $warehouse)
<input type="checkbox" name="checked[]" value="{{ $warehouse->id }}">
{{ $warehouse->address }}
<br/>
#endforeach
My Book model:
public function warehouses()
{
return $this->belongsToMany(Warehouse::class);
}
And my warehouse model:
public function books()
{
return $this->belongsToMany(Book::class);
}
Any help on being able to attach / detach upon editing an existing book, would be highly appreciated!
Try this on create and update method for storing
// Your method
foreach ($request->checked as $value){
$book->warehouses()->attach([$value]);
}
// Try This
$book->warehouses()->sync($request->checked); // $request->checked must be an array
Update Blade
#foreach($warehouses as $warehouse)
<input #if($book->warehouses()->where('warehouse_id', $warehouse->id)->exists()) checked #endif type="checkbox" name="checked[]" value="{{ $warehouse->id }}">
{{ $warehouse->address }}
<br/>
#endforeach
I will left this example with a logic according your problem. In this case are roles:
public function edit(Role $role){
//get roles ids
$permission_role = [];
foreach($role->permissions as $permission){
$permission_role[] = $permission->id;
}
//get permissions
$permissions = Permission::all();
return view("role.edit", compact('role', 'permission_role', 'permissions'));
}
In the blade:
<div class="row">
<div class="col-md-8">
<div class="form-group">
<label>Select the permissions for the current role</label>
#foreach ($permissions as $permission)
<div class="valid-feedback d-block" style="font-size: 15px !important;">
<input type="checkbox" value="{{ $permission->id }}" name="permissions[]"
#if(is_array(old('permissions')) && in_array("$permission->id", old('permissions')))
checked
#elseif(is_array($permission_role) && in_array("$permission->id", $permission_role))
checked
#endif>
<strong> {{ $permission->description }} </strong>
</div>
#endforeach
</div>
<div class="invalid-feedback d-block">
#foreach ($errors->get('permissions') as $error)
{{ $error }}
#endforeach
</div>
</div>
</div>
Of this way you can also keep the old checkboxes when nothing is select. You should validate it as required.
I'm trying to use sync on a many to many that includes a status and a comment. I can sync the applications without status and comment just fine.
NewUserAccount Model
public function applications()
{
return $this->belongsToMany('App\Application', 'new_user_account_applications', 'new_user_id')->withPivot('application_comment', 'status');
}
Application Model
public function newUserAccounts()
{
return $this->belongsToMany('App\NewUserAccount', 'new_user_accounts_applications', 'new_user_id')->withPivot('application_comment', 'status');
}
My NewUserAccountController
public function store(StoreRequest $request)
{
$userAccount = NewUserAccount::create(array_merge(
$request->all(),
['submitted_by' => $requester->id],
['start_date' => Carbon::parse($request->input('start_date'))],
['account_expires' => $request->accountExpires('newAccountExpireDate')],
['company_id' => $requester->company_id],
['username' => $request->manuallyAssignId()]
));
// Here I sync applications and include application comment and status
$userAccount->applications()->sync($request->applications, ['application_comment' => $request->application_comment, 'status' => 0]);
....
}
My pivot showing status and comment correctly
My form. Here is where I'm not sure how to handle the comment and get it to save with each application pivot record.
#foreach($applications as $application)
<label class="k-checkbox">
<input value="{{ $application->id }}" name="applications[]" type="checkbox">{{ $application->application_name }} <span></span>
</label>
<div class="form-group col-lg-4 mb-3">
<label>Comments</label>
<textarea name="application_comment[]" class="form-control" rows="2"></textarea>
</div>
#endforeach
First, you need to set the correct index for the application_comment attribute in your textarea. It's needed to correctly determine the comment for each application.
#foreach($applications as $application)
...
<textarea name="application_comment[{{ $application->id }}]" class="form-control" rows="2"></textarea>
...
#endforeach
Then, you just need to format your data to:
$userAccount->applications()->sync([
application_id_1 => ['application_comment' => 'comment for application_id 1'],
application_id_2 => ['application_comment' => 'comment for application_id 2'],
...
]);
So, here it is
$applications = collect($request->applications)->mapWithKeys(function ($appId) use ($request) {
return [$appId => [
'application_comment' => $request->input('application_comment')[$appId],
'status' => 0,
]];
});
$userAccount->applications()->sync($applications);
I'm working on a laravel application. In laravel I'm trying to update a row from a pivot table. In this application I have three tables:
issues: id, title, description
categories: id, name
category_issues:(pivot table) id, issue_id, category_id
In laravel I'm trying to update a row from a pivot table. I have this relationships:
Issue.php
public function categories() {
return $this->belongsToMany('App\Category', 'category_issues');
}
Category.php
public function issues() {
return $this->belongsToMany('App\Issue', 'category_issues');
}
A issue can have many categories.
Html code for displaying category section:
<div class="form-group row">
<label for="category" class="col-md-4 col-form-label text-md-right">{{ __('Category :') }}</label>
<div class="form-check col-md-6">
#foreach ($categories as $category)
<input type="checkbox" name="category[]" id="{{ $category->id }}" value="{{ $category->id }}"
{{ in_array($category->id, $issue->categories->pluck('id')->toArray()) ? 'checked' : '' }}>
<label for="{{ $category->id }}"> {{ $category->name }} </label>
#endforeach
</div>
</div>
Here is the update function file:
public function update(Issue $issue)
{
request()->validate([
'title'=> ['required', 'min:3'],
'description'=> ['required', 'min:3'],
'category' => ['required']
]);
$issue->title = request('title');
$issue->description = request('description');
$issue->save();
//Category_Issue Update
$categoryIssue = new CategoryIssue;
$cats = request('category');
foreach ($cats as $cat) {
$categoryIssue->updateOrCreate([
'issue_id'=> $issue->id,
'category_id' => $cat
]);
}
return redirect('issues')->with('success', 'Issue has been updated');
}
Instead of doing the creation / update on the CategoryIssue model (do you even have a CategoryIssue model?), Laravel makes this really easy to update the pivots of a relationship all at once, with the sync() method. You've set up the relationships correctly already per your code above.
In your update() method, you already have your Issue model, and have saved it. You have a set of categories coming in from the form via the $request object (or none if user didn't choose any), so you can then update the pivot like this:
$issue->categories()->sync($request->get('category', []));
Leaving a blank array as the second argument is optional. One small suggestion: maybe make the name of the field on the form 'categories' instead of 'category' just to keep it easy to remember it is an array coming in.
I am working on a medical lab application in laravel where I have the following tables:
1. Test table: This is a table which stores all the information related to medical tests:
2: Checkup: This is a page which contains all the patient information along with the tests he/she takes.
This is the test page:
This is the Checkup page where the tests and their results are selected:
Here can be many tests and user can check any number of them and will write the result of the test in the textfield below the checkbox.
I get this data in the controller like below code and save it to the database:
$this->validate($request,
[
'patient_name' => 'required|max:50',
'patient_age' => 'required',
'gender' => 'required',
'patient_type' => 'required',
'technition_id' => 'required',
'result' => 'required',
'test' => 'required',
'amount' => 'required'
]);
if( ($request->patient_type == 2) && ($request->doctor_id==0) )
{
return redirect()->back()->withInput(Input::all())->withErrors(['message' => 'Please select a valid Doctor.']);
}
$checkup = new Checkup;
$checkup->patient_name = $request->patient_name;
$checkup->patient_age = $request->patient_age;
$checkup->gender = $request->gender;
$checkup->patienttype_id = $request->patient_type;
$checkup->technition_id = $request->technition_id;
if(isset($request->doctor_id))
{
$checkup->doctor_id = $request->doctor_id;
}
$checkup->amount = $request->amount;
// $checkup->result = $request->result;
$checkup->save();
$tests =[];
$tests = $request->test;
$results =[];
$results = $request->result;
//$checkup->tests()->attach($tests->id, ['result' => $result]);
$sync_data = [];
for($i = 0; $i < count($tests); $i++)
$sync_data[$tests[$i]] = ['result' => $results[$i]];
$checkup->tests()->sync($sync_data);
Session::flash('success', 'The record was successfully saved.');
return redirect()->route('checkups.index');
Now the problem is that when I check all the checkboxes and write the result of all the tests then it is fine but when I select some and leave some of them then it gives error and the error comes because the result textbox for the unchecked test is empty.
This is the case when I select one test and leave the others:
When I check on test and write the result of it and then var_dump both test and result arrays i get the below output:
In the above image we can see that the test array contains one item because only one checkbox was checked but the result array contains two items and the first one is NULL which belongs to the unchecked checkbox.
This is the view file of the checkboxes and the textfields:
{{ Form::label('tests', 'Tests Taken') }}
#foreach(App\Test::all() as $test)
<div class="checkbox checkbox-switchery">
{{ Form::label('test', $test->name) }}
<input name="test[]" value="{{ $test->id }}" type="checkbox" class="switchery-primary">
</div>
<div>
{{ Form::label('result', "Result") }}
<input name="result[]" type="text" class="form-control">
</div>
#endforeach
<div class="form-group">
{{ Form::label('amount', 'Amount') }}
{{ Form::text('amount', null, ['class' => 'form-control']) }}
</div>
<div class="form-group">
{{Form::button('<i class="fa fa-save"> Save</i>', ['type' => 'submit', 'class' => 'btn btn-success'])}}
</div>
{!! Form::close() !!}
Please help me on this and show me how to insert the pivot table data properly to the system.
Thanks in advance for any help.
Try this..
In your blade file :
#foreach(App\Test::all() as $index => $test)
<div class="checkbox checkbox-switchery">
{{ Form::label('test', $test->name) }}
<input name="test[{{ $index }}]" value="{{ $test->id }}" type="checkbox" class="switchery-primary">
</div>
<div>
{{ Form::label('result', "Result") }}
<input name="result[{{ $index }}]" type="text" class="form-control">
</div>
#endforeach
Instead of the for loop you can use foreach lopp.
$sync_data = [];
foreach($tests as $index => $value) {
if(!empty($results[$index]) {
$sync_data[$value] = ['result' => $results[$index]]
}
}
$checkup->tests()->sync($sync_data);
I want to delete only checked tasks. At the moment I have this:
<form method="POST" action="/destroy">
#foreach($tasks as $t)
<label>
<input type="checkbox" name="checked[]" value="$t->id">
</label>
#endforeach
<button type="submit">Submit!</button>
</form>
This is my Controller
public function destroy(Request $request)
{
$this->validate($request, [
'checked' => 'required',
]);
$checked = $request->input('checked');
Task::destroy($checked);
}
And this is my route
Route::post('/destroy', [
'uses' => 'Controller#destroy',
]);
I don't get no error but the system does not work
I fixed the problem! Thanks for your support!
The problem was that my id variable was a hash.