I'm trying to display product images in a Bootstrap carousel on index view (each product has many images).
PS: I already did the same thing in a previous project and it worked fine. But in this project, I don't know why it didn't work.
Here is the index() method that returns all products with their images:
public function index()
{
$salles = Salle::all();
return view('index', compact('salles'));
}
Here is the part of the index view that I'm trying to display images on:
#forelse ($salles as $salle)
<div class="col-lg-4 mb-5 mb-lg-0 p-4 text-center box-container" data-aos="fade-up" data- aos-duration="1000">
<div class="card">
<div id="carouselExampleControls{{ $salle->id }}" class="carousel slide" data-bs-ride="carousel">
<div class="carousel-inner">
#foreach ($salle->images as $index => $image)
<div class="carousel-item {{ $index == 0 ?'active' : '' }}" style="height: 200px">
<img src="{{ asset('/storage/images/uploads/'.$image) }}" class="d-block w-100" alt="{{ $image }}" style="object-fit: cover">
</div>
#endforeach
It is possible same sales still does not have image. So use this code
#forelse ($salles as $salle)
#if(empty($salle->images))
#continue
#endif
<div class="col-lg-4 mb-5 mb-lg-0 p-4 text-center box-container" data-aos="fade-up" data- aos-duration="1000">
<div class="card">
<div id="carouselExampleControls{{ $salle->id }}" class="carousel slide" data-bs-ride="carousel">
<div class="carousel-inner">
#foreach ($salle->images as $index => $image)
<div class="carousel-item {{ $index == 0 ?'active' : '' }}" style="height: 200px">
<img src="{{ asset('/storage/images/uploads/'.$image) }}" class="d-block w-100" alt="{{ $image }}" style="object-fit: cover">
</div>
#endforeach
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]);
}
}
I want to go to specific page after click show button but after click show will get this error Undefined offset: 1
web.php
Route::get('/product/{id}', 'ProductController#show')->name('product.show');
ProductController.php
public function show($id)
{
$product = Product::find($id);
return view('product.show')->with(compact('product'));
}
home.blade.php
<div class="row">
#foreach($products as $product)
<div class="col-lg-4 col-md-6 mb-4">
<div class="card h-100">
<img class="card-img-top" src="http://placehold.it/700x400" alt="">
<div class="card-body">
<h4 class="card-title">
{{ $product->name }}
</h4>
<h5>{{ $product->price }}</h5>
<p class="card-text">{{ $product->description }}</p>
<td><a class="btn btn-primary" href="{{ route('product.show', $product->id ) }}">Show</a></td>
</div>
<div class="card-footer">
<small class="text-muted">★ ★ ★ ★ ☆</small>
</div>
</div>
</div>
#endforeach
</div>
Your are doing wrong in blade file. Note here php array start from 0. So array is [0,1,2,3] and database id is start from 1.
this is the correct link
{{ route('product.show', ['Product' => $product->id]) }}
You have to use like below code
{{ route('product.show', ['id' => $product->id]) }}
return view('product.show', compact('product'));
And in your show.blade.php you have to use like below
{{$product->id}} or {{$product->name}} //etc //But not use foorloop
The find method will return only one item. You can't use the loop on it.
Try the following code.
web.php
Route::get('/product/{product}', 'ProductController#show')->name('product.show');
ProductController.php
public function show(Product $product)
{
return view('product.show')->with(compact('product'));
}
home.blade.php
<div class="row">
<div class="col-lg-4 col-md-6 mb-4">
<div class="card h-100">
<img class="card-img-top" src="http://placehold.it/700x400" alt="">
<div class="card-body">
<h4 class="card-title">
{{ $product->name }}
</h4>
<h5>{{ $product->price }}</h5>
<p class="card-text">{{ $product->description }}</p>
<td><a class="btn btn-primary" href="{{ route('product.show', $product->id ) }}">Show</a></td>
</div>
<div class="card-footer">
<small class="text-muted">★ ★ ★ ★ ☆</small>
</div>
</div>
</div>
</div>
you are in wrong blade
you are returning product.show blade in your controller:
return view('product.show')->with(compact('product'));
but you put home.blade code!!!
put the right blade code
show.php: Why not try it $_ Get["id"]
HTML Code
#foreach($posts as $post)
<div class="container card mt-2" style="width: 32rem;">
<img src="{{ asset('images')."/".$post->img_url }}" class="card-img-top" alt="img not found">
<div class="card-body">
<h5 class="card-title">{{ $post->champion }} </h5>
<p class="card-text">{{ $post->owner_user->username }}</p>
</div>
</div>
#endforeach
Laravel code
public function testpage()
{
return Posts::with(['OwnerUser','like'])->get();
}
when I just return Posts table, it has column owner_user with user information in it.
relations work, but somehow I get "Null" as a result in {{ $post->owner_user->username }} when I return it in HTML code.
because that is not a single object try
#foreach($posts as $post)
<div class="container card mt-2" style="width: 32rem;">
<img src="{{ asset('images')."/".$post->img_url }}" class="card-img-top" alt="img not found">
<div class="card-body">
<h5 class="card-title">{{ $post->champion }} </h5>
<p class="card-text">#(foreach $post->owner_user as $user){{$user->username }}#endforeach</p>
</div>
</div>
#endforeach
I'm trying to get a list of the staffs on my application.
So now I got this view:
#foreach($getteam as $team)
<!-- Begin row -->
<div class="panel-group col-sm-offset-1 col-sm-10">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">{{ $team->role->name }}</h3>
</div>
<div class="panel-body">
<ul class="list-group">
<li class="list-group-item">
<img src="{{ Config::get('app.url') }}/public/img/avatar.jpg" style="float:left;margin-right:15px;padding-bottom:5px;" class="img-circle" alt="{{ $team->username }}" width="75" height="75">
<h4 style="color:{{ $team->role->colour }};">{{ $team->username }}</h4>
<p>Een klein beetje info over wie ik ben enzo... :p</p>
</li>
</ul>
</div>
</div>
</div>
<!-- End row -->
#endforeach
With this query:
SELECT * FROM `user`
INNER JOIN `role` ON `user`.`role_id` = `role`.`id`
WHERE `role_id` >= '4'
ORDER BY `role`.`id` DESC
or
User::with('Role')
->join('role', 'user.role_id', '=', 'role.id')
->where('role_id', '>=', '4')
->orderBy('role.id', 'DESC')
->get();
Now, so for so good,
This works to get the users exept this is the result:
http://prntscr.com/8a6v60
That is not what I want.
This is what I want: http://prntscr.com/8a6vgo
So when the groups are the same, they need to be in the same UL.
Edit
This is my view now:
<!-- Begin row -->
<div class="panel-group col-sm-offset-1 col-sm-10">
#foreach($roles as $role)
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">{{ $role->name }}</h3>
</div>
<div class="panel-body">
<ul class="list-group">
#foreach($role->user() as $user)
<li class="list-group-item">
<img src="{{ Config::get('app.url') }}/public/img/avatar.jpg" style="float:left;margin-right:15px;padding-bottom:5px;" class="img-circle" alt="{{ $user->username }}" width="75" height="75">
<h4 style="color:{{ $role->colour }};">{{ $user->username }}</h4>
<p>Een klein beetje info over wie ik ben enzo... :p</p>
</li>
#endforeach
</ul>
</div>
</div>
#endforeach
</div>
<!-- End row -->
This is the controller:
public function ForumTeam()
{
$roles = Role::all();
$getTeam = User::with('Role')->join('role', 'user.role_id', '=', 'role.id')->where('role_id', '>=', '4')->orderBy('role.id', 'DESC')->get();
return View::make('team')->with('getteam', $getTeam)->with('roles', $roles);
}
And this one is the model.
<?php
class Role extends Eloquent
{
protected $table = 'role';
public function user()
{
return $this->belongsTo(User::class);
}
}
Now I only get all the role names, not the correct stuff.
Use the reverse of the relationship between users and roles. Instead of fetching the users, get the roles and for each role you can get the corresponding users (this of course requires the Role model to have a users() method with a relation defined:
// You can of course use conditions here to filter out what roles you want loaded
$roles = Role::all();
Then iterate through the roles, and for each role iterate through its users:
<div class="panel-group col-sm-offset-1 col-sm-10">
#foreach($roles as $role)
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">{{ $role->name }}</h3>
</div>
<div class="panel-body">
<ul class="list-group">
#foreach($role->users as $user)
<li class="list-group-item">
<img src="{{ Config::get('app.url') }}/public/img/avatar.jpg" style="float:left;margin-right:15px;padding-bottom:5px;" class="img-circle" alt="{{ $user->username }}" width="75" height="75">
<h4 style="color:{{ $role->colour }};">{{ $user->username }}</h4>
<p>Een klein beetje info over wie ik ben enzo... :p</p>
</li>
#endforeach
</ul>
</div>
</div>
#endforeach
</div>