how to display many to many relationship data in laravel livewire? - php

Good night all. I have a problem when I want to display many to many relationship data, namely postal data based on tags with livewire. Previously I tried in laravel can appear.
Now I want to display post data by tag with livewire but still can't.
the following is the code that I have made.
web.php
Route::get('tag/{tag:slug}',[FrontController::class, 'tag'])->name('tag');
FrontController.php
public function tag(Tag $tag)
{
$categories = Category::all();
$general = General::find(1);
$locale = App::currentLocale();
$search = request("search");
$posts = $tag->posts()->where([
['status','PUBLISH'],
['lang',$locale],
])->latest()->paginate(12);
if ($this->search !== null) {
$posts = $tag->posts()->where([
['title','like', '%' . $search . '%'],
['lang',$locale],
['status','PUBLISH'],
])->latest()->paginate(12);
}
// dd($posts);
$tags = Tag::all();
$top = Post::where('status','PUBLISH')->orderBy('views','desc')->limit(5)->get();
return view ('front.tag',compact('categories','general','locale','posts','tags','top'));
}
tag.blade.php
#extends('layouts.front')
#section('content')
<main id="main">
<section class="post-category">
<div class="container-fluid">
<div class="row mt-3">
<div class="col-lg-3 col-md-12 col-sm-12 d-none d-lg-block">
<div class="sticky-top" style="top: 90px;">
<div class="card mb-3 rounded-3">
<div class="card-body">
<a href="#" target="_blank" rel="noreferrer">
<img src="{{ asset('front/img/ads.png') }}" alt="..." height="300" width="279" class="card-img-top" />
</a>
</div>
</div>
<div class="d-flex flex-column mb-3 bg-light shadow bg-body rounded">
<div class="card-header bg-primary bg-gradient text-white fw-bold fs-5">
{{ __('sentence.category') }}
</div>
<ul class="list-group list-group-flush">
#foreach ($categories as $category)
<li class="list-group-item d-flex justify-content-between align-items-center">
{{ $category->name }}
</li>
#endforeach
</ul>
</div>
<div class="d-flex flex-column bg-light bg-body shadow-lg rounded-3">
<div class="card-header bg-primary bg-gradient text-white fw-bold fs-5">
Tags
</div>
<div class="p-3 overflow-auto" style="max-height: 42vh">
<div class="nav tag-cloud">
#foreach ($tags as $tag)
{{ $tag->name }}
#endforeach
</div>
</div>
</div>
</div>
</div>
<livewire:tag-index>
<div class="col-lg-3 col-md-12 col-sm-12">
<div class="sticky-top" style="top: 90px;">
<div class="card rounded-3 shadow-lg mb-3">
<div class="card-body">
<img src="{{ asset('front/img/ads1.png') }}" height="117" width="279" class="card-img-top" alt="...">
</div>
</div>
<div class="bg-light shadow bg-body rounded-3 mb-3">
<div class="card-header bg-primary bg-gradient text-white fw-bold fs-5">
{{ __('sentence.top_article') }}
</div>
<ul class="list-group list-group-flush mb-2">
#foreach ($top as $top)
<li class="list-group-item">
{{ $top->title }}
<div class="d-flex justify-content-between mt-3">
<small class="text-muted">{{ Carbon\Carbon::parse($top->created_at)->format("d F, Y") }}</small>
<small class="text-muted">{{ $top->views }} views </small>
</div>
</li>
#endforeach
</ul>
</div>
<div class="d-flex flex-column mb-3 bg-light shadow bg-body rounded d-lg-none d-xl-none">
<div class="card-header bg-primary bg-gradient text-white fw-bold fs-5">
{{ __('sentence.category') }}
</div>
<ul class="list-group list-group-flush">
#foreach ($categories as $category)
<li class="list-group-item d-flex justify-content-between align-items-center">
{{ $category->name }}
</li>
#endforeach
</ul>
</div>
<div class="d-flex flex-column bg-light bg-body shadow-lg rounded-3 d-lg-none d-xl-none">
<div class="card-header bg-primary bg-gradient text-white fw-bold fs-5">
{{ __('sentence.tag') }}
</div>
<div class="p-3 overflow-auto" style="max-height: 42vh">
<div class="nav tag-cloud">
#foreach ($tags as $tag)
{{ $tag->name }}
#endforeach
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
</main>
#endsection
#push('scripts')
#livewireScripts
<script type="text/javascript">
window.onscroll = function (ev) {
if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
window.livewire.emit('tag-index');
}
};
</script>
<script>
document.getElementById('load-more').onclick = function() {
window.livewire.emit('tag-index');
};
</script>
#endpush
livewire\TagIndex.php
<?php
namespace App\Http\Livewire;
use Livewire\Component;
use App\Models\{Tag, Post};
use Illuminate\Support\Facades\App;
class TagIndex extends Component
{
public $limitPerPage = 10;
public $search;
protected $listeners = [
'tag-index' => 'TagIndex'
];
protected $updatesQueryString = [
['search' => ['except' => '']],
];
public function TagIndex()
{
$this->limitPerPage = $this->limitPerPage + 6;
}
public function render(Tag $tag)
{
$locale = App::currentLocale();
$posts = $tag->posts()->where([
['status','PUBLISH'],
['lang',$locale],
])->latest()->paginate($this->limitPerPage);
if ($this->search !== null) {
$posts = $tag->posts()->where([
['title','like', '%' . $this->search . '%'],
['status','PUBLISH'],
['lang',$locale],
])->latest()->paginate($this->limitPerPage);
}
$this->emit('postStore');
return view('livewire.tag-index', ['posts' => $posts]);
}
}
livewire\tag-index.blade.php
<div class="col-lg-6 col-md-12 col-sm-12">
<div id="section-title" class="section-title p-1 pt-3">
<h2 class="text-center fw-bold">{{ trans('sentence.recent_posts')}}</h2>
</div>
<div class="form-group has-search mb-3">
<span class="bi bi-search form-control-feedback"></span>
<input type="text" wire:model="search" class="form-control" placeholder="{{ __('sentence.search_form') }}">
</div>
#foreach ($posts as $data)
<div class="card bg-light shadow bg-body rounded-3 mb-2">
<div class="card-header bg-primary text-white d-flex justify-content-between">
<small>by {{$data->admin->name}}</small>
<small>{{ Carbon\Carbon::parse($data->created_at)->format("d F, Y") }}</small>
</div>
<div class="card-body">
<h2 class="card-title">
{{ $data->title }}
</h2>
<div class="card-footer bg-body d-flex justify-content-between align-items-center pb-0 px-0">
<div class="d-flex my-1">
#foreach ($data->tags as $tag)
{{ $tag->name }}
#endforeach
</div>
</div>
</div>
</div>
#endforeach
#if ($posts->count() == 0)
<div class="alert alert-danger" role="alert">
Data not found!
</div>
#endif
#if($posts->count() >= 10)
<div class="text-center d-md-none d-lg-none d-xl-none">
<button id="load-more" class="btn btn-primary my-3">
Load More
</button>
</div>
#endif
</div>
what is the correct way or code to display many to many relationship data with livewire? in this case, I want to display post data by tag. thank you

There is a lot of additional stuff going on in your question so I have put together a simplified example for you. You will need to do the remainder of the work to get it into your project.
I don't know how you're displaying your tag labels or anything, so I have gone with checkboxes as it seems the most sensible. These could be styled to be hidden so they more closely resemble the tag labels on SO but again, I will leave the bike shedding to you.
I created a Livewire component called Tags with an associated blade view.
tags.blade.php
<div>
{{-- loop over each of the tags --}}
#foreach ($this->tags as $tag)
{{-- wire:key is important here as Livewire requires it for effective DOM diffing! --}}
<div wire:key="tag-{{ $tag->id }}" class="block px-4 py-2">
{{--
this is where we bind the checkboxes
to a property on the Livewire component
--}}
<input wire:model="selectedTags" type="checkbox" id="tag-{{ $tag->id }}" name="{{ $tag->title }}" value="{{ $tag->id }}">
<label for="{{ $tag->title }}">{{ $tag->title }}</label>
</div>
#endforeach
{{-- loop over each of the posts --}}
#foreach ($this->posts as $post)
{{-- again, don't overlook wire:key! --}}
<div wire:key="post-{{ $post->id }}" class="block px-4 py-2">
<h4 class="text-sm">{{ $post->title }}</h4>
</div>
#endforeach
</div>
The above should be mostly self explanatory, the only bit that might not be is wire:model="selectedTags". A public property called selectedTags is defined on the Tags component (as you'll see in a moment) and what this does is allow us to manage elements in that array when one of the checkboxes is selected. So for example when someone checks the checkbox for tag with id of 12, the selectedTags array has an element added with the value of 12.
Tags.php
class Tags extends Component
{
// array of selected tags (checked checkboxes)
public $selectedTags = [];
// get just the id and title of each tag
public function getTagsProperty()
{
return Tag::select('id', 'title')->get();
}
public function getPostsProperty()
{
$tags = array_filter($this->selectedTags);
// if no tags are selected, return all posts
// you might decide to return nothing, up to you
if (!$tags) {
return Post::all();
}
// if there are some selected tags
// query the database for posts with the selectedTags
// this is an `OR` operation on tags
// if you want `AND` you'll need to change it
return Post::whereHas('tags', function ($query) use ($tags) {
$query->whereIn('tags.id', $tags);
})->get();
}
public function render()
{
return view('livewire.tags');
}
}
Again the above should be self explanatory as there is nothing out of the ordinary going on.
The getPostsProperty() and getTagsProperty() functions define computed properties which are optional, you could just use normal properties if you wish. However, if you're referencing $tags and $posts multiple times in your component views, a computed property is more performant as it doesn't make a call to the backend component each time.

SOLVED
thanks #Peppermintology for helping my two issues and now this issue is solved with below code.
FrontController.php
public function tag(Tag $tag)
{
$categories = Category::all();
$general = General::find(1);
$locale = App::currentLocale();
$tag_id = $tag->id;
$search = request("search");
$posts = $tag->posts()->where([
['status','PUBLISH'],
['lang',$locale],
])->latest()->paginate(12);
if ($this->search !== null) {
$posts = $tag->posts()->where([
['title','like', '%' . $search . '%'],
['lang',$locale],
['status','PUBLISH'],
])->latest()->paginate(12);
}
$tags = Tag::all();
$top = Post::where('status','PUBLISH')->orderBy('views','desc')->limit(5)->get();
return view ('front.tag',compact('categories','general','locale','posts','tags','tag_id','top'));
}
livewire\TagIndex.php
<?php
namespace App\Http\Livewire;
use Livewire\Component;
use App\Models\{Tag, Post};
use Illuminate\Support\Facades\App;
class TagIndex extends Component
{
public $limitPerPage = 10;
public $search, $tagId;
protected $listeners = [
'tag-index' => 'TagIndex'
];
protected $updatesQueryString = [
['search' => ['except' => '']],
];
public function TagIndex()
{
$this->limitPerPage = $this->limitPerPage + 6;
}
public function render()
{
$locale = App::currentLocale();
$tag_id = $this->tagId;
$tag = Tag::find($tag_id);
$posts = $tag->posts()->where([
['status','PUBLISH'],
['lang',$locale],
])->latest()->paginate($this->limitPerPage);
if ($this->search !== null) {
$posts = $tag->posts()->where([
['title','like', '%' . $this->search . '%'],
['status','PUBLISH'],
['lang',$locale],
])->latest()->paginate($this->limitPerPage);
}
$this->emit('postStore');
// dd($posts);
return view('livewire.tag-index', ['posts' => $posts, 'tag' => $tag]);
}
}

Related

How to show image from database with eager loading?

I want to display multiple product image from database with eager loading, and when i tried to displaying it, console said localhost:8000/storage/ 404 not found. Any ideas how to solve this? this is my first time using eager loading & relationship on Laravel. Thank you!
Here is my controller :
public function homeProduct(){
$products = Product::with('productCategory')->get();
$images = Product::with('productImage')->get();
return view('home.index', compact('products', 'images'));
}
Product Model :
public function productImage()
{
return $this->hasMany(ProductImage::class, 'product_id', 'id');
}
Product Image Model :
public function product()
{
return $this->belongsTo(Product::class, 'id');
}
Here are the index.blade.php View :
#foreach ($products as $p)
<div class="col-lg-6 col-12">
<div class="portfolio-thumb mb-5" data-aos="fade-up">
<div id="yoreBeans" class="carousel slide" data-bs-ride="carousel">
<div class="carousel-inner">
#foreach ($images as $key => $image)
<div class="carousel-item {{ $key == 0 ? 'active' : '' }}">
<a href="{{ asset('storage/'.$image->path) }}" class="image-popup">
<img src="{{ asset('storage/'.$image->path) }}" class="img-fluid portfolio-image" alt="">
</a>
</div>
#endforeach
</div>
</div>
<div class="portfolio-info">
<h3 class="text-black">{{ $p->name }}</h3>
<h4 class="text-danger">{{ $p->productCategory->name }}</h4>
</div>
</div>
</div>
#endforeach
Your method $images = Product::with('productImage')->get(); will also return Product objects with images.
What you exactly want is to eager load both realtions and then reference it at the same time:
public function homeProduct(){
$products = Product::with(['productCategory', 'productImage'])->get();
return view('home.index', compact('products'));
}
And your view like this:
#foreach ($products as $p)
<div class="col-lg-6 col-12">
<div class="portfolio-thumb mb-5" data-aos="fade-up">
<div id="yoreBeans" class="carousel slide" data-bs-ride="carousel">
<div class="carousel-inner">
<!-- // this line changed --->
#foreach ($p->productImage as $key => $image)
<div class="carousel-item {{ $key == 0 ? 'active' : '' }}">
<a href="{{ asset('storage/'.$image->path) }}" class="image-popup">
<img src="{{ asset('storage/'.$image->path) }}" class="img-fluid portfolio-image" alt="">
</a>
</div>
#endforeach
</div>
</div>
<div class="portfolio-info">
<h3 class="text-black">{{ $p->name }}</h3>
<h4 class="text-danger">{{ $p->productCategory->name }}</h4>
</div>
</div>
</div>
#endforeach

Larapoll results in admin panel

Hello i'm using inani larapoll it's works great but in admin panel i can't see results of voting i can see only question, how many answers it have and how many vote was added i want to create custom page in admin where will be results of current vote like it is on WEB
like this
question - > why its don't working
answer1 -> don't know <- this option has 10 votes
answer2 -> because i'm doing something wrong <- this option has 100 votes
i added route
Route::get('/results', ['uses' => 'PollManagerController#results', 'as' => 'poll.results']);
pollmanager controller
public function results(Poll $poll)
{
$total = $poll->votes->count();
$results = $poll->results()->grab();
$options = collect($results)->map(function ($result) use ($total){
return (object) [
'votes' => $result['votes'],
'percent' => $total === 0 ? 0 : ($result['votes'] / $total) * 100,
'name' => $result['option']->name
];
});
$question = $poll->question;
echo view(config('larapoll_config.results') ? config('larapoll_config.results') : 'larapoll::dashboard.results', compact('options', 'question'));
}
and i copied results blade to my new blade
#if(Session::has('errors'))
<div class="alert alert-danger">
{{ session('errors') }}
</div>
#endif
#if(Session::has('success'))
<div class="alert alert-success">
{{ session('success') }}
</div>
#endif
<div class="w-80 m-auto">
<div class="font-size-14 font-medium-caps text-blue-100">{{ $question }}</div>
#foreach($options as $option)
<div class="mt-20px">
<div class="font-size-14 font-size-xs-12 text-blue-100">{{ $option->name }}</div>
<div class="w-100 d-flex justify-content-between pb-5px">
<div class="w-100 d-flex align-items-center">
<div class="w-100 bg-lighter-gray h-4px position-relative">
<div class="position-absolute top-0 bg-yellow h-4px" style='width: {{ $option->percent }}%'> </div>
</div>
</div>
<div class="font-size-14 font-size-xs-12 text-blue-100 pl-10px">{{ $option->percent }}%</div>
</div>
</div>
#endforeach
<div class="d-flex justify-content-between mt-auto pt-30px align-items-center">
<div class="d-flex">
<span class="fas fa-calendar text-light-gray pr-5px"></span>
<p class="mr-20px font-medium font-size-12 text-light-gray"></p>
</div>
<div class="d-flex align-items-center text-light-black flex-end font-base font-size-14 font-size-xs-12"></div>
</div>
</div>
but's its showing nothing... empty

Laravel Live Search Results Display Issue on the View

I'm trying to implement a live search in my laravel application.
Following is my index function in the controller (ParticipantController.php). Here if there is no search happens, then displaying the participants by default.
public function index(Request $request)
{
if($request->ajax()){
$data = User::orderBy('id','DESC')
->WHERE('role_id','=','3')
->where('email','LIKE','%'.$request->search."%")
->paginate(12);
return view('admins.participants.index',compact('data'))
->with('i', ($request->input('page', 1) - 1) * 12 );
}
else{
$data = User::orderBy('id','DESC')->WHERE('role_id','=','3')->paginate(12);
return view('admins.participants.index',compact('data'))
->with('i', ($request->input('page', 1) - 1) * 12 );
}
}
following is my view (only included the relevant part)
<div class="row mt-5 ">
<div class="col-md-12 mb-2 text-right">
<input type="text" class="form-controller" id="search" name="search"></input>
</div>
</div>
<div class="row mt-2 participant-row">
#foreach ($data as $key => $user)
<div class="col-md-3 d-flex align-items-stretch mb-4">
<div class="white-panel w-100 ">
<div class="card p-2 ">
<div class="row no-gutters ">
<div class="col-auto my-auto">
#if(empty($user->image_id))
<img src="/propics/default-avatar.png" class="img_participant">
#else
<?php if(file_exists('propics/'.$user->image_id.'')){
echo '<img src="/propics/'.$user->image_id.'" class="img_participant">
';
}else{
echo '<img src="/propics/default-avatar.png" class="img_participant">
';
}?>
#endif
</div>
<div class="col my-auto">
<div class="card-block px-2">
<div class="text-right">
<a class="btn btn-default btn_icon" href="{{ route('participants.edit',$user->id) }}"><i class="fas fa-edit"></i></a>
{!! Form::open(['method' => 'DELETE','route' => ['participants.destroy', $user->id],'style'=>'display:inline']) !!}
{!! Form::button('<i class="fas fa-trash-alt"></i>', ['class' => 'btn btn-default btn_icon','type'=>'submit','onclick'=>'return confirm("Are you sure want to remove this User?")']) !!}
{!! Form::close() !!}
</div>
<hr>
<h4 class="card-title participant_name alas">{{ $user->first_name }} {{ $user->last_name }}</h4>
<p class="card-text participant_email alas">{{ $user->email }}</p>
</div>
</div>
</div>
</div>
</div>
</div>
#endforeach
</div>
And set my route as (web.php),
Route::resource('/admins/participants','Admin\ParticipantController');
Following is my Javascript which I included at the bottom of my view
<script type="text/javascript">
jQuery('#search').on('keyup',function(){
$value=jQuery(this).val();
$.ajax({
type : 'get',
url:"{{ route('participants.index') }}",
data:{'search':$value},
success:function(data){
jQuery('.participant-row').html(data);
}
});
})
</script>
Now the issue is when I search for something, as the result, the current code provides me a whole new view inside the old view. It loads a new view (with the menus and all) inside the target div class whichi mentioned in my javascript code.

how to display post data by category with laravel livewire

Good afternoon, how to display post data by category in laravel livewire? here I want to try to display post by category data in the following way but it still doesn't work:
web.php
Route::get('category/{category:slug}',[FrontController::class, 'category'])->name('category');
FrontController.php
public $search;
public function category(Category $category)
{
$categories = Category::all();
$general = General::find(1);
$locale = App::currentLocale();
$category_id = $category->id;
$search = request("search");
$posts = Post::where([
['lang',$locale],
['category_id',$category_id],
['status','PUBLISH'],
])->latest()->paginate(12);
if ($this->search !== null) {
$posts = Post::where([
['title','like', '%' . $this->search . '%'],
['lang',$locale],
['category_id',$category_id],
['status','PUBLISH'],
])->latest()->paginate(12);
}
// dd($category_id);
$tags = Tag::all();
$top = Post::where('status','PUBLISH')->orderBy('views','desc')->limit(5)->get();
return view ('front.category',compact('categories','category_id','general','locale','posts','tags','top'));
}
category.blade.php
#extends('layouts.front')
#section('content')
<main id="main">
<section class="post-category">
<div class="container-fluid">
<div class="row mt-3">
<div class="col-lg-3 col-md-12 col-sm-12 d-none d-lg-block">
<div class="sticky-top" style="top: 90px;">
<div class="card mb-3 rounded-3">
<div class="card-body">
<a href="#" target="_blank" rel="noreferrer">
<img src="{{ asset('front/img/ads.png') }}" alt="..." height="300" width="279" class="card-img-top" />
</a>
</div>
</div>
<div class="d-flex flex-column mb-3 bg-light shadow bg-body rounded">
<div class="card-header bg-primary bg-gradient text-white fw-bold fs-5">
{{ __('sentence.category') }}
</div>
<ul class="list-group list-group-flush">
#foreach ($categories as $category)
<li class="list-group-item d-flex justify-content-between align-items-center">
{{ $category->name }}
</li>
#endforeach
</ul>
</div>
<div class="d-flex flex-column bg-light bg-body shadow-lg rounded-3">
<div class="card-header bg-primary bg-gradient text-white fw-bold fs-5">
Tags
</div>
<div class="p-3 overflow-auto" style="max-height: 42vh">
<div class="nav tag-cloud">
#foreach ($tags as $tag)
{{ $tag->name }}
#endforeach
</div>
</div>
</div>
</div>
</div>
<input type="hidden" name="category_id" value="{{ $category_id }}">
<livewire:category-index>
<div class="col-lg-3 col-md-12 col-sm-12">
<div class="sticky-top" style="top: 90px;">
<div class="card rounded-3 shadow-lg mb-3">
<div class="card-body">
<img src="{{ asset('front/img/ads1.png') }}" height="117" width="279" class="card-img-top" alt="...">
</div>
</div>
<div class="bg-light shadow bg-body rounded-3 mb-3">
<div class="card-header bg-primary bg-gradient text-white fw-bold fs-5">
{{ __('sentence.top_article') }}
</div>
<ul class="list-group list-group-flush mb-2">
#foreach ($top as $top)
<li class="list-group-item">
{{ $top->title }}
<div class="d-flex justify-content-between mt-3">
<small class="text-muted">{{ Carbon\Carbon::parse($top->created_at)->format("d F, Y") }}</small>
<small class="text-muted">{{ $top->views }} views </small>
</div>
</li>
#endforeach
</ul>
</div>
<div class="d-flex flex-column mb-3 bg-light shadow bg-body rounded d-lg-none d-xl-none">
<div class="card-header bg-primary bg-gradient text-white fw-bold fs-5">
{{ __('sentence.category') }}
</div>
<ul class="list-group list-group-flush">
#foreach ($categories as $category)
<li class="list-group-item d-flex justify-content-between align-items-center">
{{ $category->name }}
</li>
#endforeach
</ul>
</div>
<div class="d-flex flex-column bg-light bg-body shadow-lg rounded-3 d-lg-none d-xl-none">
<div class="card-header bg-primary bg-gradient text-white fw-bold fs-5">
{{ __('sentence.tag') }}
</div>
<div class="p-3 overflow-auto" style="max-height: 42vh">
<div class="nav tag-cloud">
#foreach ($tags as $tag)
{{ $tag->name }}
#endforeach
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
</main>
#endsection
#push('scripts')
#livewireScripts
<script type="text/javascript">
window.onscroll = function (ev) {
if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
window.livewire.emit('category-index');
}
};
</script>
<script>
document.getElementById('load-more').onclick = function() {
window.livewire.emit('category-index');
};
</script>
#endpush
livewire\CategoryIndex.php
<?php
namespace App\Http\Livewire;
use Livewire\Component;
use App\Models\{Category, Post};
use Illuminate\Support\Facades\App;
class CategoryIndex extends Component
{
public $limitPerPage = 10;
public $search;
protected $listeners = [
'category-index' => 'CategoryIndex'
];
protected $updatesQueryString = [
['search' => ['except' => '']],
];
public function CategoryIndex()
{
$this->limitPerPage = $this->limitPerPage + 6;
}
public function render()
{
$locale = App::currentLocale();
$category_id = request('category_id');
$posts = Post::where([
['lang',$locale],
['category_id',$category_id],
['status','PUBLISH'],
])->latest()->paginate($this->limitPerPage);
if ($this->search !== null) {
$posts = Post::where([
['title','like', '%' . $this->search . '%'],
['lang',$locale],
['category_id',$category_id],
['status','PUBLISH'],
])->latest()->paginate($this->limitPerPage);
}
$this->emit('postStore');
dd($category_id);
return view('livewire.category-index', ['posts' => $posts]);
}
}
livewire\category-index.blade.php
<div class="col-lg-6 col-md-12 col-sm-12">
<div id="section-title" class="section-title p-1 pt-3">
<h2 class="text-center fw-bold">{{ trans('sentence.recent_posts')}}</h2>
</div>
<div class="form-group has-search mb-3">
<span class="bi bi-search form-control-feedback"></span>
<input type="text" wire:model="search" class="form-control" placeholder="{{ __('sentence.search_form') }}">
</div>
#foreach ($posts as $data)
<div class="card bg-light shadow bg-body rounded-3 mb-2">
<div class="card-header bg-primary text-white d-flex justify-content-between">
<small>by {{$data->admin->name}}</small>
<small>{{ Carbon\Carbon::parse($data->created_at)->format("d F, Y") }}</small>
</div>
<div class="card-body">
<h2 class="card-title">
{{ $data->title }}
</h2>
<div class="card-footer bg-body d-flex justify-content-between align-items-center pb-0 px-0">
<div class="d-flex my-1">
#foreach ($data->tags as $tag)
{{ $tag->name }}
#endforeach
</div>
</div>
</div>
</div>
#endforeach
#if ($posts->count() == 0)
<div class="alert alert-danger" role="alert">
Data not found!
</div>
#endif
#if($posts->count() >= 10)
<div class="text-center d-md-none d-lg-none d-xl-none">
<button id="load-more" class="btn btn-primary my-3">
Load More
</button>
</div>
#endif
</div>
If I add($category_id); in FrontController.php the id of that category appears, but if I try to dd in livewire\CategoryIndex.php it shows null. what is the correct way to display posts by category? thank you
Livewire components work slightly differently to blade views, they do not automatically inherit variables from their parents.
What you need to do is pass your category_id to the Livewire component.
class CategoryIndex extends Component
{
public $categoryId;
}
<livewire:category-index :categoryId="$category_id" />

How can I get a single category of question in a quiz app using Laravel Eloquent

I want to select a single category of questions that the user can select with options. I have tried doing this with a resource I found online.
The category page:
#foreach($categories as $category)
<section>
<a href="#" class="image">
<img src="{{asset('images/pic09.jpg')}}" alt="" data-position="top center" />
</a>
<div class="content">
<div class="inner">
<header class="major">
<h3>{{$category->name}}</h3>
</header>
<p></p>
<ul class="actions">
<li>Learn more</li>
</ul>
</div>
</div>
</section>
#endforeach
Here is the TestController I'm using, the show controller is might to select questions and options with the category_id at random:
namespace App\Http\Controllers;
use App\Category;
use App\Http\Requests\StoreTestRequest;
use App\Option;
class TestsController extends Controller
{
public function show($id)
{
$categories = Category::find($id)->with(
['categoryQuestions' => function ($query) {
$query->inRandomOrder()
->with(
['questionOptions' => function ($query) {
$query->inRandomOrder();
}]
);
}]
)
->whereHas('categoryQuestions')
->get();
return view('client.test', compact('categories'));
}
public function store(StoreTestRequest $request)
{
$options = Option::find(array_values($request->input('questions')));
$result = auth()->user()->userResults()->create(
[
'total_points' => $options->sum('points')
]
);
$questions = $options->mapWithKeys(
function ($option) {
return [$option->question_id => [
'option_id' => $option->id,
'points' => $option->points
]
];
}
)->toArray();
$result->questions()->sync($questions);
return redirect()->route('client.results.show', $result->id);
}
}
web.php
// User
Route::group(['as' => 'client.', 'middleware' => ['auth']], function () {
Route::get('home', 'HomeController#redirect');
Route::get('dashboard', 'HomeController#index')->name('home');
Route::resource('/test', 'TestsController');
Route::get('results/{result_id}', 'ResultsController#show')->name('results.show');
Route::get('send/{result_id}', 'ResultsController#send')->name('results.send');
});
This is the Blade file from the resource I'm using:
#extends('layouts.home')
#section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">Test</div>
<div class="card-body">
#if(session('status'))
<div class="row">
<div class="col-12">
<div class="alert alert-success" role="alert">
{{ session('status') }}
</div>
</div>
</div>
#endif
<form method="POST" action="{{ route('client.test.store') }}">
#csrf
#foreach($categories as $category)
<div class="card mb-3">
<div class="card-header">{{ $category->name }}</div>
<div class="card-body">
#foreach($category->categoryQuestions as $question)
<div class="card #if(!$loop->last)mb-3 #endif">
<div class="card-header">{{ $question->question_text }}</div>
<div class="card-body">
<input type="hidden" name="questions[{{ $question->id }}]" value="">
#foreach($question->questionOptions as $option)
<div class="form-check">
<input class="form-check-input" type="radio" name="questions[{{ $question->id }}]" id="option-{{ $option->id }}" value="{{ $option->id }}"#if(old("questions.$question->id") == $option->id) checked #endif>
<label class="form-check-label" for="option-{{ $option->id }}">
{{ $option->option_text }}
</label>
</div>
#endforeach
#if($errors->has("questions.$question->id"))
<span style="margin-top: .25rem; font-size: 80%; color: #e3342f;" role="alert">
<strong>{{ $errors->first("questions.$question->id") }}</strong>
</span>
#endif
</div>
</div>
#endforeach
</div>
</div>
#endforeach
<div class="form-group row mb-0">
<div class="col-md-6">
<button type="submit" class="btn btn-primary">
Submit
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
#endsection
How can the Testcontroller be made to select questions and answer from a single category and save the result from the user's answers?
public function index()
{
$questions = Category::select('categories.name', 'question_result.points')
->join('questions', 'categories.id', '=', 'questions.category_id')
->join('question_result', 'questions.id', '=', 'question_result.question_id')
->join('results', 'question_result.result_id', '=', 'results.id')
->where('results.user_id', auth()->id())
->get();
return view('client.home', compact('questions'));
}

Categories