I am building a CRUD with Laravel. Each category hasMany attachments and each attachment belongsTo a category.
In the category.edit view I want to give the user the possibility of deleting the attachments (singularly) from the Category. I tried this method but it did not work:
Registering route for the attachment:
Route::group(['middleware' => ['auth']], function () {
Route::delete('attachment/{id}', 'AttachmentController#delete')->name('attachment');
});
Handling the delete building the AttachmentController#delete method:
class AttachmentController extends Controller
{
public function delete($id) {
$toDelete = Attachment::findOrFail($id);
$toDelete->delete();
return redirect()->back();
}
}
In the CategoryController (edit method), I fetch the attachments linked to each category to be rendered inside the view:
public function edit($category)
{
$wildcard = $category;
$category = Category::findOrFail($wildcard);
$attachments = App\Category::findOrFail($wildcard)->attachments()->get()->toArray();
return view('category.edit', [
'category' => $category,
'attachments' => $attachments
]);
}
In the view, I render the attachment and the button to delete. I am fully aware of the error of having a form inside another form, nevertheless I do not know antoher approach to submit this delete request.
// update Category form
#foreach ($attachments as $attachment)
<div class="row">
<div class="col-4">
<img style="width: 100%;" src={{ $attachment['url'] }} alt="">
</div>
<div class="col-4">
<div>
<p class="general_par general_url">{{ $attachment['url'] }}</p>
</div>
</div>
<div class="col-4">
<form action="{{ route('attachment', $attachment['id']) }}" method="POST">
#csrf
#method('DELETE')
<button type="submit" class="btn btn-danger">Delete Image</button>
</form>
</div>
</div>
<hr>
#endforeach
// end of update Category form
Should I build a deleteAttachment method inside the CategoryController? If so, how can I still submit the Delete request? Also, if any other Model in the future will have attachments, should I build a deleteAttachment method inside each controller? That is cumbersome. Thanks in advance
if you don't like to use form, then use tag:
<a class="btn btn-danger" href="{{ route('attachment', $attachment['id']) }}">Delete Image</a>
And redefine the route to Route::get(...)
(or maybe use ajax for POST method if that is required)
Related
I have a form made with Livewire in Laravel.
This is the Livewire controller
namespace App\Http\Livewire;
use Livewire\Component;
use App\Rules\Mobile;
class Form extends Component
{
public $mobile;
public $required;
public $fields;
public $showDropdown = true;
public function mount()
{
foreach($this->fields as $field){
$this->required[$field->name] = ($field->pivot->is_required == '1') ? 'required' : 'nullable';
}
}
public function submit()
{
$validatedData = $this->validate([
'mobile' => [$this->required['mobile'] ?? 'nullable', new Mobile()]
]);
}
}
This is the Livewire view
<div>
<div x-data="{ open: #entangle('showDropdown').defer, required: #js($required) }">
<span x-show="open" wire:loading.remove>
<form wire:submit.prevent="submit" style="display: flex; flex-direction: column;">
<div class="fields">
#foreach($fields as $field)
<div class="form-{{$field->name}}">
#if($field->name == 'mobile')
<input name="{{$field->name}}" type="tel" wire:model.defer="{{ $field->name }}" placeholder="{{ __($field->pivot->placeholder ?? $field->name) }}">
#endif
#error($field->name) <span class="error">{{ ucfirst($message) }}</span> #enderror
</div>
#endforeach
</div>
<button class="btn btn-primary">Send</button>
</form>
</span>
</div>
</div>
Problem is here placeholder="{{ __($field->pivot->placeholder ?? $field->name) }}"
When the form is first loaded $field->pivot->placeholder is set, but after I submit the form and the validation fails, it's not set anymore and $field->name is used instead of $field->pivot->placeholder
Have checked this way:
<input name="{{$field->name}}" type="tel" wire:model.defer="{{ $field->name }}" placeholder="{{ __($field->pivot->placeholder ?? $field->name) }}">
{{ var_dump(isset($field->pivot->placeholder)) }}
When the form is first loaded it prints bool(true) under the field, after I send the form it says bool(false)
How can I get over this? Why the pivot does not work after validation fails?
//Edit: Did a workaround, but I would still like to know why it happens
What I did is I used another property $placeholders
In the Livewire controller have added public $placeholders;, in the mount() have added $this->placeholders[$field->name] = $field->pivot->placeholder ?? $field->name;, and then used it in the view like placeholder="{{ __($placeholders[$field->name] ?? $field->name) }}"
I don't know much about livewire , but I know that mount() only called on the initial page load meaning it will only run when you refresh the whole page or visit the page. Instead of only using mount() you should also use hydrate() which will run every subsequent request after the page load.
mount() - Initial Page Load
hydrate() - Every subsequent request
You can implement the hydrate() like how you implement the mount()
Following is my controller. Method ProjectsView is to view all the listings. The second method BackendProjectSearch is for searching of projects. The first page of search result is displayed properly, but when we click on next page it gives the error "The GET method is not supported for this route. Supported methods: POST."
What should I do ?
public function ProjectsView(){
$projects = projects::orderBy('id','ASC')->paginate(15);
return view('backend.projects.projects_view',compact('projects')); }
public function BackendProjectSearch(Request $request){
$request->validate(["search" => "required"]);
$item = $request->search;
$projects = Projects::where('project_name','LIKE',"%$item%")->paginate(15);
return view('backend.projects.projects_view',compact('projects')); }
Following are the routes for both the methods :
Route::post('/backend/project/search', [ProjectsController::class, 'BackendProjectSearch'])->name('backend.project.search');
Route::get('/view', [ProjectsController::class, 'projectsView'])->name('projects.view');
View code :
<div class="col-md-8">
<div class="header-navsearch">
<form class="form-inline mr-auto" method="post" action="{{route('backend.project.search')}}">
#csrf
<div class="nav-search">
<input type="search" name="search" class="form-control header-search" placeholder="Search projects…" aria-label="Search">
<button class="btn btn-primary" type="submit"><i class="fa fa-search"></i></button>
</div>
</form>
</div>
</div>
The route for this request should be post, not get.
Example
Route::post(-----);
Also, make sure to insert a CSRF token while making the request
it means you now cannot do something like the following.
Instead, you have to do something like...
<form action="{{ route('example') }}" method="POST">
#csrf {{-- According to the version of laravel --}}
{{-- Your other codes --}}
<button type="submit" class="">Submit</button>
</form>
You have to use the below code
return redirect()->route('projects.view')->with(['projects' => $projects]);
Your route might be little change
Route::get('/view/{projects?}', [ProjectsController::class, 'projectsView'])->name('projects.view');
and In your controller, you have to change function like this
public function ProjectsView($projects = null){
if($projects!=null){
return view('backend.projects.projects_view',compact('projects'));
}
else{
$projects = projects::orderBy('id','ASC')->paginate(15);
return view('backend.projects.projects_view',compact('projects'));
}
I am new to laravel. This is my view (bids.new):
<form method="post" action="{{ route('bids.storeBid', $project->id) }}" enctype="multipart/form-data" >
#csrf
*content*
<div class="row pt-4">
<button class="btn btn-primary">Place Bid</button>
</div>
</form>
This is my route:
Route::get('/bids/new/{id}', 'BidController#create')->name('bids.new');
Route::post('/bids/{id}', 'BidController#storeBid')->name('bids.storeBid');
BidController:
public function create($id)
{
$project = Projects::findOrFail($id);
return view('bids.new',compact('project'));
}
public function storeBid(Request $request, $id)
{
*content*
}
When I clicked on Place Bid button in my view, the page is not responding and URL is still showing /bids/new/1 which means the storeBid route was not loaded. I tried using dd($id) at controller but it is not displaying as well so I assumed I have a problem with the route or form in the view.
<div class="row pt-4">
<button type="submit" class="btn btn-primary">Place Bid</button>
</div>
try this one. I hope it will help you. Let me know.
Thank you guys for the comments, I figured out the problem was not because of the form or route but due to some errors on my eloquent in the controllers.
Is there any way to get the data inside a modal? I know that it is possible to work with this through Jquery, but I would like to know if there is any way to work with Laravel itself. In a view, we can do this:
return view ('admin/users/index', ['datas1' => $ datas1, 'datas2' => $datas2];
but for a modal, is it possible to do something like this? to send my data through the controller and within my modal I check if this data are coming empty or filled, as this answer I just want to show different things, like this:
$dep = User::query()->where('dep_link', $id)->get();
return['status' => 'success', 'dep' => $dep];
only my validation in the modal:
<div class="row" style="padding: 28px 20px;">
<div class="col-12">
#if(empty($dep))
<div class="position-relative">
<label for="rg_titular">Selecione o RG do titular (.png .jpg .pdf)</label><br>
<input type="file" name="rg_titular" class="file-input"/>
<button type="button" class="file-button">Selecionar arquivo</button>
<span class="text-arquivo">Arquivo selecionado!</span>
</div>
#else
<a href="link" target="_blank">
Visualizar RG do titular
</a>
#endif
</div>
</div>
Is there any way I can get this data inside the modal window and work with them? I just want to check if it's coming empty or not, that's all.
You can write a view composer for the modal blade file.
https://laravel.com/docs/5.8/views#view-composers
In your service provider (app, or a custom one you make)
public function boot()
{
view()->composer('myBladeFileName', function ($view) {
$activeUsers = \App\User::where('active', true)->get();
$view->with(compact('activeUsers'));
});
}
I need to pull in data to my view but this doesn't work:
return view ('sub-domain', ['worker' => $worker ]);
Here is my code:
public function aerospace(Request $request , Worker $worker ){
$worker = $worker->newQuery();
if ($request->has('profession')) {
$worker->where('profession', $request->input('profession'));
}
if ($request->has('state')) {
$worker->where('state', $request->input('state'));
}
if ($request->has('local_govt')) {
$worker->where('local_govt', $request->input('local_govt'));
}
return $worker->get();
The above code brings out an array of data from the database which I can then filter with "domain/sub-domain?state=xyz"
Now when I try to pass in the data into my views using
return view ('sub-domain', ['worker' => $worker ]);
The page is loaded but no $worker data is loaded on the page. How can I pull the data? Here is my view file
<div class="row">
<form method="GET" action="">
Profession:<input type="text" name="profession"> State:<input type="text" name="state"> Local Govt:<input type="text" name="local_govt">
<button type="submit">Filter</button>
</form>
</div>
<div class="row">
#foreach ($worker as $worker)
<div class="col-lg-3 col-md-6">
<div class="member">
<div class="pic"><img src="avatar/{{$worker->avatar}}" alt=""></div>
<div class="details">
<h4>{{$worker->name}} {{$worker->l_name}}</h4>
<span>{{$worker->profession}}</span><br>{{ $worker->state }}
</div>
</div>
</div> #endforeach
</div>
I want to filter data by certain parameters, if there's a better way to do that please do let me know. But first I need the data to display.
You are returning a query instance, not a collection or singular model. That's why the get() method works. So first do:
$worker = $worker->get();