I have a page with multiple posts, each post has a location and department & title.
I implemented the search function for "word search" and it works fine, but in addition to this I have two Dropdown menus for location & department, they get their content from two different table.
I am kind of stuck and don't know why it doesn't work, here is my controller code:
public function index(Request $request)
{
$posts = Post::orderBy('titel')->get();
$standorts = Standort::orderBy('standort_name')->get();
$abteilungs = Abteilung::orderBy('abteilung_name')->get();
if ($request->filled('s') || $request->has('standort') || $request->has('abteilung')) {
$word = strtolower($request->get('s'));
$location = $request->standort;
$dep = $request->abteilung;
$query = strtolower($request->get('s'));
$posts = $posts->filter(function ($post) use ($dep, $word, $location) {
if (
Str::contains(strtolower($post->Titel), $word) ||
Post::where('standort_name') == $location
|| Post::where('abteilung_name') == $dep
) {
return true;
}
return false;
});
}
return view('posts.overview', [
'posts' => $posts,
'standorts' => $standorts,
'abteilungs' => $abteilungs,
]);
}
Here is my blade code:
<form class="mb-5 flex justify-left grid grid-cols-4 gap-x-20" action=" {{ route('overview') }}"
method="get">
<div class="w-full h-12 text-left col-start-1 col-end-1">
<input placeholder="Schlagwort" type="text" id="s" name="s" value="{{ request()->get('s') }}"
class="mb-2 w-full h-full bg-white bg-opacity-95 rounded focus:ring-2 border border-gray-300 focus:border-indigo-500 text-base outline-none text-gray-700 text-xl py-1 px-3 leading-8">
</div>
<div class="text-left mb-4 h-12">
<select name="abteilung" id="abteilung" class="h-full w-full flex justify-center bg-white bg-opacity-95 rounded focus:ring-2 border border-gray-300 focus:border-indigo-500 text-base outline-none text-gray-700 text-lg text-center leading-8">
<option selected="true" disabled="disabled">Abteilung</option>
#foreach($abteilungs as $abteilung)
<option value="{{ $abteilung->abteilung_name }}">{{ $abteilung->abteilung_name }}</option>
#endforeach
</select>
</div>
<div class="text-left mb-4 h-12">
<select name="standort" id="standort" class="h-full w-full flex justify-center bg-white bg-opacity-95 rounded focus:ring-2 border border-gray-300 focus:border-indigo-500 text-base outline-none text-gray-700 text-lg text-center leading-8">
<option selected="true" disabled="disabled">Standort</option>
#foreach($standorts as $standort)
<option value="{{ $standort->standort_name }}">{{ $standort->standort_name }}</option>
#endforeach
</select>
</div>
<button class="col-start-4 col-end-4 w-11/12 h-12 text-white text-2xl px-4 py-2 rounded text-base font-medium bg-gradient-to-r from-green-400 to-blue-500 float-right shadow transition duration-500 ease-in-out transform hover:-translate-y-1 hover:scale-100">
Suchen
</button>
</form>
When I dd this part:
$word = strtolower($request->get('s'));
$location = $request->standort;
$dep = $request->abteilung;
I get the correct attributes, for instance a word like "HR", a location like "Munich" and a department like "Finance".
When I perform the search though for a specific department all posts are gone.
Edit for clarity:
The goal is that a user can search for a word in a title, a location and department all in one request, and only the post where each is present gets shown.
Edit Relation Models:
Post Model:
class Post extends Model
{
use HasFactory;
/**
* The attributes that are mass assignable.
*
* #var string[]
*/
protected $fillable = [
'titel',
'startdate',
'enddate',
'beschreibung',
'standort',
'type_name',
'abteilung_name',
'kontakt',
'isActive',
'lebenslauf',
'zeugnisse',
'anschreiben',
'weitere_Doks',
'is_Permitted',
'job_start',
];
public function location() {
return $this->hasOne(Standort::class);
}
public function job_type() {
return $this->hasOne(Jobtypes::class);
}
}
Abteilung Model:
class Abteilung extends Model
{
use HasFactory;
/**
* The attributes that are mass assignable.
*
* #var string[]
*/
protected $fillable = [
'abteilung_name',
];
public function posts() {
return $this->hasMany(Post::class);
}
}
Standort Model:
class Standort extends Model
{
use HasFactory;
/**
* The attributes that are mass assignable.
*
* #var string[]
*/
protected $fillable = [
'abteilung_name',
];
public function posts() {
return $this->hasMany(Post::class);
}
}
Related
in my livewire view i get all the credits from their respective owners through the model relationship between clients and credits
Model: Client
protected $fillable = ['name'];
public function credits(){
return $this->hasMany(Credit::class);
}
public function payments(){
return $this->hasManyThrough(Payment::class, Credit::class);
}
Model: Credit
const ACTIVE= 1;
const LIQUIDATED= 2;
protected $fillable = ['amount', 'amount_end', 'status', 'dues'];
public function client(){
return $this->belongsTo(Client::class);
}
public function provider(){
return $this->belongsTo(Provider::class);
}
public function payments(){
return $this->hasMany(Payment::class);
}
in my livewire view I have a foreach that gets me all the clients, inside a switch that counts the credits of the clients
Livewire: Show-client
#foreach ($clients as $item)
...
#switch($item->credits->count())
#case($status_credit = 1)
<span class="px-2 py-1 inline-flex text-sm leading-5 font-semibold rounded-md bg-yellow-300 text-yellow-600 geosanslgbold text-md">
Credit
</span>
#break
#case($status_credits >= 2)
<span class="px-2 py-1 inline-flex text-sm leading-5 font-semibold rounded-md bg-orange-300 text-orange-700 geosanslgbold text-md">
Credits
</span>
#break
#default
<span class="px-2 py-1 inline-flex text-sm leading-5 font-semibold rounded-md bg-green-400 text-green-900 geosanslgbold text-md">
Not Credits
</span>
#endswitch
#endforeach
So far everything is fine, it tells me the credits and tells me if it has or not.
now the credits have the option to place them as active or liquidated
How would I make my switch, instead of telling me all the client's credits, only take the active or in this case the ones with the number 1 and add the active credits
sorry for my bad english
I believe you are looking for what's called "local query scopes" : https://laravel.com/docs/9.x/eloquent#local-scopes
public function scopeIsLiquidated(Builder $query): Builder
{
return $query->where('status', LIQUIDATED);
}
Usage :
$clients = ...->isLiquidated()->...;
I am trying to make a delete button for my Laravel 8 app. I got some errors while doing that and don't know how to do it.
My app is about creating training courses for students and for each training course they will get a YouTube video created by an admin and I am trying to add the delete formation function.
That is my controller I tried to create a delete function. My update, create functions work fine but the delete doesn't work and I get the following error message:
[Vue warn]: Error in v-on handler: "TypeError: Cannot read property 'course' of undefined"
![Error message screenshot][1]
<?php
namespace App\Http\Controllers;
use App\Models\User;
use Inertia\Inertia;
use App\Models\Course;
use App\Models\Episode;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Database\Eloquent\Builder;
use App\Http\Requests\StoreCourseWithEpisodes;
class CourseController extends Controller
{
public function index()
{
$courses = Course::with('user')
->select('courses.*', DB::raw(
'(SELECT COUNT(DISTINCT(user_id))
FROM completions
INNER JOIN episodes ON completions.episode_id = episodes.id
WHERE episodes.course_id = courses.id
) AS participants'
))->addSelect(DB::raw(
'(SELECT SUM(duration)
FROM episodes
WHERE episodes.course_id = courses.id
) AS total_duration'
))
->withCount('episodes')->latest()->paginate(5);
return Inertia::render('Courses/Index', [
'courses' => $courses
]);
}
public function show(int $id)
{
$course = Course::where('id', $id)->with('episodes')->first();
$watched = auth()->user()->episodes;
return Inertia::render('Courses/Show', [
'course' => $course,
'watched' => $watched
]);
}
public function store(StoreCourseWithEpisodes $request)
{
$user_id = \Auth::user()->id;
$course = Course::create($request->all());
foreach($request->input('episodes') as $episode)
{
$episode['course_id'] = $course->id;
Episode::create($episode);
}
return Redirect::route('courses.index')->with('success', 'Félicitations, votre formation a bien été postée.');
}
public function edit(int $id)
{
$course = Course::where('id', $id)->with('episodes')->first();
$this->authorize('update', $course);
return Inertia::render('Courses/Edit', [
'course' => $course
]);
}
public function update(StoreCourseWithEpisodes $request)
{
$course = Course::where('id', $request->id)->first();
$this->authorize('update', $course);
$course->update($request->all());
$course->episodes()->delete();
foreach($request->episodes as $episode) {
$episode['course_id'] = $course->id;
Episode::create($episode);
}
return Redirect::route('courses.index')->with('success', 'Félicitations, votre formation a bien été modifiée.');
}
public function toggleProgress(Request $request)
{
$id = $request->input('episodeId');
$user = auth()->user();
$user->episodes()->toggle($id);
return $user->episodes;
}
public function delete(StoreCourseWithEpisodes $request ,$id)
{
$course = Course::find($id);
$course->episodes()->delete();
// $request->has('id') ?
// Article::find($request->input('id'))->delete() :
// redirect()->back()
// ->with('errors', 'Attentions.');
return Redirect::route('courses.index')->with('success', 'Félicitations, votre formation a bien été supprimer.');
}
}
That is my vue where I have to call my delete function:
<template>
<app-layout>
<template #header>
Liste des formations
</template>
<section class="py-6">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div v-if="$page.flash.success" class="bg-green-200 text-green-600 p-4">
{{ $page.flash.success }}
</div>
<div class="py-3" v-for="course in courses.data" v-bind:key="course.id">
<div class="bg-white rounded shadow p-4">
<div class="text-sm text-gray-500 flex justify-between items-center">
<div>
Mise en ligne par <strong>{{ course.user.name }}</strong> (<span class="text-gray-500 text-sm">{{ course.participants }} participant<span v-if="parseInt(course.participants) > 1 ">s</span>)
</span>
</div>
<span class="block text-sm text-gray-400">{{ course.episodes_count }} épisode<span v-if="course.episodes_count > 1">s</span></span>
</div>
<h1 class="text-3xl">{{ course.title }}</h1>
<span class="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700">
{{ convert(course.total_duration) }}</span>
<div class="text-sm text-gray-500 mt-2">{{ course.description }}</div>
<div class="flex justify-between items-center">
<a :href="'course/' + course.id" class="bg-indigo-700 text-white px-3 py-2 text-sm mt-3 inline-block rounded hover:bg-indigo-500">Voir la formation</a>
<a :href="'courses/edit/' + course.id" v-if="course.update" class="bg-gray-700 text-white px-3 py-2 text-sm mt-3 inline-block rounded hover:bg-gray-500">Editer</a>
<button #click="remove(course.id)"
class="bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-4 rounded">
Supprimer
</button>
</div>
</div>
</div>
<inertia-link :href="link.url" class="text-indigo-700 border-gray-500 p-5" v-for="link in courses.links" v-bind:key="link.label">
<span v-bind:class="{'text-red-700' : link.active}">{{ link.label }}</span>
</inertia-link>
</div>
</section>
</app-layout>
</template>
<script>
import AppLayout from './../../Layouts/AppLayout';
export default {
components: {
AppLayout
},
props: ['courses'],
data() {
return {
courseData: this.courses
}
},
methods: {
remove() {
this.$inertia.delete('/courses/delete/'+ this.courseData.id, this.courseData);
},
// deleteRow(id) {
// this.$inertia.delete('/article/delete/' + id)
// },
convert(timestamps) {
let hours = Math.floor(timestamps / 3600);
let minutes = Math.floor(timestamps / 60) - (hours * 60);
let seconds = timestamps % 60;
return hours.toString().padStart(2, 0) + ':' + minutes.toString().padStart(2, 0) + ':' + seconds.toString().padStart(2, 0);
}
}
}
</script>
[enter image description here][2]
here is my vue with no error but my delete button still does not work
<template>
<app-layout>
<template #header>
Liste des formations
</template>
<section class="py-6">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div v-if="$page.flash.success" class="bg-green-200 text-green-600 p-4">
{{ $page.flash.success }}
</div>
<div class="py-3" v-for="course in courses.data" v-bind:key="course.id">
<div class="bg-white rounded shadow p-4">
<div class="text-sm text-gray-500 flex justify-between items-center">
<div>
Mise en ligne par <strong>{{ course.user.name }}</strong> (<span class="text-gray-500 text-sm">{{ course.participants }} participant<span v-if="parseInt(course.participants) > 1 ">s</span>)
</span>
</div>
<span class="block text-sm text-gray-400">{{ course.episodes_count }} épisode<span v-if="course.episodes_count > 1">s</span></span>
</div>
<h1 class="text-3xl">{{ course.title }}</h1>
<span class="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700">
{{ convert(course.total_duration) }}</span>
<div class="text-sm text-gray-500 mt-2">{{ course.description }}</div>
<div class="flex justify-between items-center">
<a :href="'course/' + course.id" class="bg-indigo-700 text-white px-3 py-2 text-sm mt-3 inline-block rounded hover:bg-indigo-500">Voir la formation</a>
<a :href="'courses/edit/' + course.id" v-if="course.update" class="bg-gray-700 text-white px-3 py-2 text-sm mt-3 inline-block rounded hover:bg-gray-500">Editer</a>
<button #click="remove()"
class="bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-4 rounded">
Supprimer
</button>
</div>
</div>
</div>
</div>
</section>
</app-layout>
</template>
<script>
import AppLayout from './../../Layouts/AppLayout';
export default {
components: {
AppLayout
},
props: ['courses'],
data() {
return {
courseData: this.courses
}
},
methods: {
remove(id) {
this.$inertia.delete('/courses/delete/'+ id);
},
// deleteRow(id) {
// this.$inertia.delete('/article/delete/' + id)
// },
convert(timestamps) {
let hours = Math.floor(timestamps / 3600);
let minutes = Math.floor(timestamps / 60) - (hours * 60);
let seconds = timestamps % 60;
return hours.toString().padStart(2, 0) + ':' + minutes.toString().padStart(2, 0) + ':' + seconds.toString().padStart(2, 0);
}
}
}
</script>
and my controller right here
<?php
namespace App\Http\Controllers;
use App\Models\User;
use Inertia\Inertia;
use App\Models\Course;
use App\Models\Episode;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Database\Eloquent\Builder;
use App\Http\Requests\StoreCourseWithEpisodes;
class CourseController extends Controller
{
public function index()
{
$courses = Course::with('user')
->select('courses.*', DB::raw(
'(SELECT COUNT(DISTINCT(user_id))
FROM completions
INNER JOIN episodes ON completions.episode_id = episodes.id
WHERE episodes.course_id = courses.id
) AS participants'
))->addSelect(DB::raw(
'(SELECT SUM(duration)
FROM episodes
WHERE episodes.course_id = courses.id
) AS total_duration'
))
->withCount('episodes')->latest()->paginate(5);
return Inertia::render('Courses/Index', [
'courses' => $courses
]);
}
public function show(int $id)
{
$course = Course::where('id', $id)->with('episodes')->first();
$watched = auth()->user()->episodes;
return Inertia::render('Courses/Show', [
'course' => $course,
'watched' => $watched
]);
}
public function store(StoreCourseWithEpisodes $request)
{
$user_id = \Auth::user()->id;
$course = Course::create($request->all());
foreach($request->input('episodes') as $episode)
{
$episode['course_id'] = $course->id;
Episode::create($episode);
}
return Redirect::route('courses.index')->with('success', 'Félicitations, votre formation a bien été postée.');
}
public function edit(int $id)
{
$course = Course::where('id', $id)->with('episodes')->first();
$this->authorize('update', $course);
return Inertia::render('Courses/Edit', [
'course' => $course
]);
}
public function update(StoreCourseWithEpisodes $request)
{
$course = Course::where('id', $request->id)->first();
$this->authorize('update', $course);
$course->update($request->all());
$course->episodes()->delete();
foreach($request->episodes as $episode) {
$episode['course_id'] = $course->id;
Episode::create($episode);
}
return Redirect::route('courses.index')->with('success', 'Félicitations, votre formation a bien été modifiée.');
}
public function toggleProgress(Request $request)
{
$id = $request->input('episodeId');
$user = auth()->user();
$user->episodes()->toggle($id);
return $user->episodes;
}
public function delete(StoreCourseWithEpisodes $request ,$id)
{
// dd($id);
Course::find($id)->delete();
// $course->episodes()->delete();
// $request->has('id') ?
// Article::find($request->input('id'))->delete() :
// redirect()->back()
// ->with('errors', 'Attentions.');
return Redirect::route('courses.index')->with('success', 'Félicitations, votre formation a bien été supprimer.');
}
}
I'm facing against this problem since yesterday.
I have a db table called resources have a foreign key linked to another table called category.
I'm trying to retrieve the description field in my blade view, but I get this error:
Trying to get property 'description' of non-object.
My blade view:
#extends('templates.header')
#section('section')
<div class="p-10 grid grid-cols-1 sm:grid-cols-1 md:grid-cols-3 lg:grid-cols-3 xl:grid-cols-3 gap-5">
#foreach($resources as $resource)
<div class="max-w-sm rounded overflow-hidden shadow-lg">
{{-- <img class="w-full" src="#" alt="Mountain"> --}}
<div class="px-6 py-4">
<div class="font-bold text-xl mb-2">
{{ $resource->name }}
</div>
<p class="text-gray-700 text-base">
{{ $resource->description }}
</p>
</div>
<div class="px-6 pt-4 pb-2">
<span class="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2 mb-2">{{ $resource->categor->description }}</span>
<span class="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2 mb-2">{{ $resource->status }}</span>
<span class="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2 mb-2">{{ $resource->centerId }}</span>
<button type="submit" class="inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
Prenota
</button>
</div>
</div>
#endforeach
</div>
#endsection
My Resource Model:
namespace App\Models;
use App\Models\Category;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Resource extends Model
{
use HasFactory;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name',
'description',
'category',
'inventoryN',
'status',
'centerId',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
];
public function category()
{
return $this->hasOne(Category::class, 'id', 'category');
}
}
My Category Model:
namespace App\Models;
use App\Models\Resource;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Category extends Model
{
use HasFactory;
protected $table = 'categories';
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'description',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
];
public function resource()
{
return $this->belongsTo(Resource::class, 'category');
}
}
And lastly my ResourceController:
namespace App\Http\Controllers;
use App\Models\Category;
use App\Models\Resource;
use Illuminate\Http\Request;
class ResourceController extends Controller
{
public function index()
{
$resources = Resource::with('category')->get();
return view('resources', compact('resources'));
}
}
This is a dd of "$resources":
dd of $resources
You have a few mistakes here.
The first is in the Blade. You need to fix a typo
$resource->categor->description
// should be
$resource->category->description
Then I recommend changing your schema by changing your resources column from category to category_id.
This will help Laravel auto populate the values in the below snippets.
Next, you need to fix your relationships.
In the Resources model, you need
public function category()
{
return $this->hasOne(Category::class);
}
I have removed the second and third parameters, these are autofilled by Laravel; and since you are using Laravel's naming schemes, you don't need it.
What you had previously was stating that the table was the singular variant of category, which it wasn't.
Then you need to change your Category model to
public function resource()
{
return $this->belongsTo(Resource::class);
}
The reason this was failing is because Laravel was returning null, because the column names weren't quite correct.
It's easier to just have a more standard naming structure in your Database as it helps other developers, and makes your life easier when using Laravel.
There is a typo in your category viewing. I think that's the problem.
{{ $resource->categor->description }}
vs.
{{ $resource->category->description }}
I am building a search bar within a webpage. Ideally, user would enter the search text in the search field, and then if there are records found, a search results table would show and display the record found. I am using Laravel Livewire to implement this feature, however, I ran into the problem that the wire:click not firing the event, and any help would be needed!
This is my blade file (resources/livewire/dashboard.blade.php) contains the search bar:
<form>
<label for="searchText" class="block text-xx font-medium text-gray-700">Search Users</label>
<div class="mt-1 flex rounded-md shadow-sm">
<div class="relative flex items-stretch flex-grow focus-within:z-10">
<input type="text" name="searchText" id="searchText"
class="focus:ring-indigo-500 focus:border-indigo-500 block w-full rounded-none rounded-l-md pl-10 sm:text-sm border-gray-300" placeholder="User ID / Email Address / Mobile Number"
wire:model="searchText">
</div>
<button wire:click="search()" class="-ml-px relative inline-flex items-center space-x-2 px-4 py-2 border border-gray-300 text-sm font-medium rounded-r-md text-gray-700 bg-gray-50 hover:bg-gray-100 focus:outline-none focus:ring-1 focus:ring-indigo-500 focus:border-indigo-500">
Search
</button>
</div>
</form>
and this is the action defined in the App/Http/Livewire/Dashboard.php file
<?php
namespace App\Http\Livewire;
use Illuminate\Support\Facades\Http;
use Livewire\Component;
class Dashboard extends Component
{
public $stats, $searchText;
public $showResultsTable = false;
protected $accountAPIRootURL = 'https://example.com/api/v2/';
public function render()
{
$response = Http::withHeaders([
'Accept' => 'application/json'
])->get($this->accountAPIRootURL . 'statistics/overview');
if ($response->successful()) {
$stats = $response['data'];
} else {
$stats = [
'total_users' => 0,
'new_users' => 0,
'invitations' => 0,
'new_invitations' => 0,
'requests' => 0,
'new_requests' => 0
];
}
$this->stats = $stats;
$this->searchText = '';
return view('livewire.dashboard');
}
public function search()
{
$response = Http::withHeaders([
'Accept' => 'application'
])->get($this->accountAPIRootURL . 'admin/search', [
'searchText' => $this->searchText
]);
if ($response->successful()) {
$this->showResultsTable = true;
$this->searchText = '';
}
}
}
This is my template.blade.php file, where the #livewire component is called
#extends('layouts.app')
#section('content')
#livewire('dashboard')
#endsection
I am not worrying too much about displaying the result table now because it seems like the search() function is not being triggered when I click on the Search button within the blade. How do I know that, I put a dd() within the search() function and it is not being executed.
I would appreciate any help!
You don't need to use the parenthesis, wire:click="search"
UPDATE: Try this different syntax while you are handle a form in livewire
<form wire:submit.prevent="search">
//.....
<div class="mt-1 flex rounded-md shadow-sm">
//.....
<button class="-ml-px relative inline-flex items-center space-x-2 px-4 py-2 border border-gray-300 text-sm font-medium rounded-r-md text-gray-700 bg-gray-50 hover:bg-gray-100 focus:outline-none focus:ring-1 focus:ring-indigo-500 focus:border-indigo-500">
Search
</button>
</div>
</form>
I wanted to post the variables initiated in the MenuItemList.php and SubCategoryList.php located in the App/Http/Livewire directory to a single blade file i.e. menu-item.blade.php. So I can further use the CRUD functionality for the above said tables i.e. menu-items and sub-categories from a single view, i.e. menu-item.blade.php.
When I run it through the different routes with separate views, it works flawlessly, but as soon as I try to combine them into one and try to view it all, in a single blade file, it gives me all sort of errors. Here is my source code.
App\Models\MenuItem.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class MenuItem extends Model
{
use HasFactory;
protected $table = "menu_items";
protected $fillable = ['sub_category_id', 'item_name', 'item_description'];
}
App\Http\Livewire\MenuItemList.php
<?php
namespace App\Http\Livewire;
use Livewire\Component;
use Livewire\WithPagination;
use App\Models\MenuItem;
class MenuItemList extends Component
{
use WithPagination;
public $search;
public $itemId,$sub_category_id,$item_name,$item_description;
public $isOpen = 0;
public function render()
{
$searchParams = '%'.$this->search.'%';
return view('livewire.menu-item', [
'menuitemlist' => MenuItem::where('item_name','like', $searchParams)->latest()->paginate(5)
]);
}
public function showModal() {
$this->isOpen = true;
}
public function hideModal() {
$this->isOpen = false;
}
public function store(){
$this->validate(
[
'sub_category_id' => 'required',
'item_name' => 'required',
]
);
MenuItem::updateOrCreate(['id' => $this->itemId], [
'sub_category_id' => $this->sub_category_id,
'item_name' => $this->item_name,
'item_description' => $this->item_description
]);
$this->hideModal();
session()->flash('info', $this->itemId ? 'Post Update Successfully' : 'Post Created Successfully' );
$this->itemId = '';
$this->sub_category_id = '';
$this->item_name = '';
$this->item_description = '';
}
public function edit($id){
$menuitem = MenuItem::findOrFail($id);
$this->itemId = $id;
$this->sub_category_id = $menuitem->sub_category_id;
$this->item_name = $menuitem->item_name;
$this->item_description = $menuitem->item_description;
$this->showModal();
}
public function delete($id){
MenuItem::find($id)->delete();
session()->flash('delete','Post Successfully Deleted');
}
}
App\Models\SubCategory.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class SubCategory extends Model
{
use HasFactory;
protected $table = "sub_categories";
protected $fillable = ['category_id', 'sub_category_name'];
}
App\Http\Livewire\SubCategoryList.php
<?php
namespace App\Http\Livewire;
use Livewire\Component;
use Livewire\WithPagination;
use App\Models\SubCategory;
class SubCategoryList extends Component
{
use WithPagination;
public $search;
public $itemId,$category_id,$sub_category_name;
public $isOpen = 0;
public function render()
{
$searchParams = '%'.$this->search.'%';
return view('livewire.sub-category', [
'subcategorylist' => SubCategory::where('sub_category_name','like', $searchParams)->latest()->paginate(5)
]);
}
public function showModal() {
$this->isOpen = true;
}
public function hideModal() {
$this->isOpen = false;
}
public function store(){
$this->validate(
[
'category_id' => 'required',
'sub_category_name' => 'required',
]
);
SubCategory::updateOrCreate(['id' => $this->itemId], [
'category_id' => $this->category_id,
'sub_category_name' => $this->sub_category_name
]);
$this->hideModal();
session()->flash('info', $this->itemId ? 'Post Update Successfully' : 'Post Created Successfully' );
$this->itemId = '';
$this->category_id = '';
$this->sub_category_name = '';
}
public function edit($id){
$subcategory = SubCategory::findOrFail($id);
$this->itemId = $id;
$this->category_id = $subcategory->category_id;
$this->sub_category_name = $subcategory->sub_category_name;
$this->showModal();
}
public function delete($id){
SubCategory::find($id)->delete();
session()->flash('delete','Post Successfully Deleted');
}
}
Routes\Web.php
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Livewire\MenuItemList;
use App\Http\Livewire\SubCategoryList;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
return view('welcome');
});
Route::get('/menu-item', MenuItemlist::class);
Route::get('/sub-category', SubCategorylist::class);
Route::middleware(['auth:sanctum', 'verified'])->get('/dashboard', function () {
return view('dashboard');
})->name('dashboard');
EDITED
Here is my menu-item.blade.php for referencing, I am using the exact same code for the sub-category.blade.php, just using the variables from the SubCategory.php. As I am unable to show them in a single view, I have made two separate views for the above said files.
Resources\Views\Livewire\menu-item.blade.php
<x-slot name="header">
<h2 class="text-xl font-semibold leading-tight text-gray-800">
Manage Menu Item
</h2>
</x-slot>
<div class="py-12">
<div class="mx-auto max-w-5xl sm:px-6 lg:px-8">
<div class="bg-white overflow-hidden shadow sm:rounded-lg px-4 py-4 my-8 text-sm">
<div class="flex mb-4">
<div class="w-full md:w-1/2 px-3 mb-6 md:mb-0">
<button wire:click="showModal()" class="px-4 py-2 my-3 font-bold text-white bg-blue-500 rounded hover:bg-blue-700 focus:outline-none">Create Menu Item</button>
</div>
<div class="w-full md:w-1/2 px-3 mb-6 md:mb-0">
<input wire:model="search" type="text" class="shadow appearance-none border rounded w-full py-2 px-2 my-3 text-blue-900 focus:outline-none" placeholder="Search Post...">
</div>
</div>
#if($isOpen)
#include('livewire.create')
#endif
#if(session()->has('info'))
<div class="bg-green-500 border-2 border-green-600 rounded-b mb-2 py-3 px-3">
<div>
<h1 class="text-white font-bold">{{ session('info') }}</h1>
</div>
</div>
#endif
#if(session()->has('delete'))
<div class="bg-red-500 border-2 border-red-600 rounded-b mb-2 py-3 px-3">
<div>
<h1 class="text-white font-bold">{{ session('delete') }}</h1>
</div>
</div>
#endif
<table class="w-full table-fixed">
<thead>
<tr class="bg-gray-100">
<th class="w-20 px-4 py-2">Sr. No.</th>
<th class="px-4 py-2">Sub-Category ID</th>
<th class="px-4 py-2">Item Name</th>
<th class="px-4 py-2">Item Description</th>
<th class="px-4 py-2">Action</th>
</tr>
</thead>
<tbody>
#foreach($menuitemlist as $key=>$menuitem)
<tr style="background-color: {{ $key % 2 == 0 ? '#fdfdfd': '#f5f5f5' }};">
<td class="px-4 py-2">{{ $menuitemlist->firstitem() + $key }}</td>
<td class="px-4 py-2">{{ $menuitem->sub_category_id }}</td>
<td class="px-4 py-2">{{ $menuitem->item_name }}</td>
<td class="px-4 py-2">{{ $menuitem->item_description }}</td>
<td class="px-4 py-2">
<button wire:click="edit({{ $menuitem->id }})" class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-1 px-4 rounded">
Edit
</button>
<button wire:click="delete({{ $menuitem->id }})" class="bg-red-500 hover:bg-red-700 text-white font-bold py-1 px-4 rounded">
Delete
</button>
</td>
</tr>
#endforeach
</tbody>
</table>
<div class="mt-4">
{{$menuitemlist->links()}}
</div>
</div>
</div>
</div>