How can I filter the data of foreach? - laravel

I have this design:
I need to say: last post that I add it put it in the head of design then other put them down.
My shut :) Html and foreach code:
#if ($user->projects->count() > 0)
<section class="latest section shadow-sm">
<h1>Projects</h1>
<div class="section-inner">
#foreach ($user->projects->sortByDesc('id')->take(1) as $project)
<div class="item featured text-center ">
// head post
</div>
#endforeach
#foreach ($projects_last->sortByDesc('id') as $project)
<div class="item row">
// other post
</div>
#endforeach
</div><!--//section-inner-->
</section><!--//section-->
#endif
Code of controller for $projects_last:
$projects_last = $user->projects;
$projects_last->pop();
return view('frontend.user_profile',compact('user','projects_last'));
I have the problem with when I say if the #if ($user->projects->count() > 0) do not show any thing but still show me the <h1>Projects</h1> even it is empty!
And if you have any suggest to making my code better pls do it with thankful :)

To iterate Collections you have to get them. So you have to use get() to get the results.
...
#foreach ($user->projects->sortByDesc('id')->take(1)->get() as $project)
...
and
...
#foreach ($projects_last->sortByDesc('id')->get() as $project)
...
You can see here the documentation: Laravel query documentation
Note: if you want to get just one element in your first foreach loop you can use first() instead of take(1). You code will be like that:
#php($first_project = $user->projects->sortByDesc('id')->first())
#if (!is_null($first_project))
// Use $first_project as $project variable
#enif

Related

Laravel - Element displaying twice while looping inside a condition

This is the example while looping
despite having a condition and relation many too many it seems that the case
#foreach (\App\ClientDocument::where('id_client', $clients->id)->get() as $item)
#if (\App\Document::where('id',$item->id_document)->get())
<a class="img-fluid " href="{{asset('images/'.$item->file)}}" download="{{asset('images/'.$item->file)}}" alt="" name="download" > Telecharger </a>
#endif
#endforeach
in the above snippet
#foreach (\App\ClientDocument::where('id_client', $clients->id)->get() as $item)
#if (\App\Document::where('id',$item->id_document)->get())
<a class="img-fluid " href="{{asset('images/'.$item->file)}}" download="{{asset('images/'.$item->file)}}" alt="" name="download" > Telecharger </a>
#endif
#endforeach
code is absolutely fine, but there might be the possibility, you are running with duplicate data, you can use this also.
\App\ClientDocument::where('id_client', $clients->id)->distinct('id_client')->get()
and instead of using #if (\App\Document::where('id',$item->id_document)->get())
you can use
#if (\App\Document::where('id',$item->id_document)->firstOrFail())
#if (\App\Document::where('id',$item->id_document)->count())
That's it.
first you shouldn't loading data inside blade files
do it inside controller function
then you should create relationship inside ClientDocument model name document
and in your blade you can do that
$item->document
or whatever you want

How can I hide a block in Laravel?

There is one div inside which foreach works for me. Before this div I do a check
#if($events)
<div class="card mb-5">
....
If true, then show the block, if false, do not show. But the block is still visible, it returns me an empty collection. How to fix it?
public function index($id) {
$user = User::find($id);
$events = $user->events()->orderBy('eventdata', 'desc')->limit(3)->get();
Because you are using get() method it always returns Collection of items but sometimes empty. I think you are checking whether $events collection is empty or not. So, you have to use $events->count() inside if
#if($events->count())
<div class="card mb-5">
....
#forelse($events as $event)
<div class="card mb-5">
....
#empty
Do something if there is no event
...
#endforelse
#forelse checks if $events variable empty or not. If it is empty then #empty block will be rendered else #forelse block will be rendered. #forelse is like a combination of #foreach #if and #else directives
You try this
#if(count($events)>0)
<div class="card mb-5">

Eloquent query to blade on view styled better?

I'm doing an assignment (never ending assignments).
I have a query in my controller that sums up certain table items by month and then I show them in a view.
However, I feel I could have done this in a better way as the output looks not great and I'm not sure how to style it.
Controller method
public function monthly()
{
$activity = DB::table('activities')
->select(
DB::raw("Month(date) as Month"),
DB::raw("SUM(minutes) as total_minutes"),
DB::raw("SUM(distance) as total_distance"))
->orderBy("month")
->groupBy(DB::raw("month"))
->get();
return view ('summary/monthly',compact('activity')); }
* View *
#extends('layouts.app')
#section('content')
{{$activity}}
#endsection
Output in view
Any tips on what I could do better?
Edit
Oh man I was definitely over thinking my approach and thought it was an error with my controller. Thank you for the help!
You need something like this:
#foreach($activity as $singleActivity)
{{$singleActivity->Month}}
{{$singleActivity->total_minutes}}
{{$singleActivity->total_distance}}
#endforeach
You need to iterate the loop on your blade file.
#extends('layouts.app')
#section('content')
#foreach($activity as $acti )
<div class="activity">
<div class="month">{{ $acti->Month }}
</div>
<div class="minutes">{{ $acti->total_minutes }}
</div>
<div class="distance">{{ $acti->total_distance }}
</div>
</div>
#endforeach
#endsection
You can iterate your data using #forelse and displa it with table
#forelse ($activity as $act)
<li>
Month: {{ $act->Month }} Total Minutes: {{ $act->total_minutes}} Total Distance: {{ $act->total_distance}}
</li>
#empty
<p>No Activities</p>
#endforelse
I don't know what you like, but how is it?
<table>
<thead>
<tr>
<th>Month</th>
<th>TotalMinutes</th>
<th>TotalDistance</th>
</thead>
<tbody>
#foreach($activity as $act)
{{$act->Month}}
{{$act->total_minutes}}
{{$act->total_distance}}
#endforeach
</tbody>
</table>

I want to count in if statement in foreach loop laravel 5.6

As I am new to Laravel so facing this problem and tried it in other ways but it is not working.
Here my blade file
products.blade.php
#foreach($products as $product)
<div class="women">
<h6>{{$product->title}}</h6>
<span class="size">XL / XXL / S </span>
<p ><em class="item_price">Rs.{{$product->price}}</em></p>
</div>
#if(count($product) == 3)
<div class="clearfix"></div>
#endif
#endforeach
Why this is not working
#if(count($product) == 3)
<div class="clearfix"></div>
#endif
Or how can I count the product in iteration and compare the count number in if statement?
You can use loop variable like this.
Instead of:
#if(count($product) == 3)
<div class="clearfix"></div>
#endif
you should use:
#if($loop->iteration == 3)
<div class="clearfix"></div>
#endif
But it's quite possible that you might need it after every 3 elements (3, 6, 9 and so on), so maybe better solution would be:
#if($loop->iteration % 3 == 0)
<div class="clearfix"></div>
#endif
You example didn't work because $product is just an object so count($product) will not have expected value. Also if you used count($products) (notice trailing s) it won't work because count of products is the same in each loop iteration.
If you have more or less than 3 products, your if statement is never going to show. What you're looking for is the third item in the products array, which you can do like this:
#foreach($products as $key => $product)
<div class="women">
<h6>{{$product->title}}</h6>
<span class="size">XL / XXL / S </span>
<p><em class="item_price">Rs.{{$product->price}}</em></p>
</div>
#if($key == 2)
<div class="clearfix"></div>
#endif
#endforeach
To get the index of the loop, use
#foreach ($athletes as $key=>$athlete)
// Some html goes here
{ { ++$key } }
#endforeach
add if condition to key
let me know how it goes
The array count will always be the same, inside or outside of the loop.
If you want to make a decision based on the current iteration, ex. "on every third product put a clearfix div", then apply the condition to the key if the key is numeric.
Blade provides a loop variable with an iteration property (starts at 1) to help with this, see here https://laravel.com/docs/5.6/blade#the-loop-variable
Example for every third product:
#foreach($products as $product)
...
#if ($loop->$loop->iteration%3 == 0)
<div class="clearfix"></div>
#endif
...
#endforeach
Example for the third product only:
#if ($loop->$loop->iteration == 3)
<div class="clearfix"></div>
#endif

Recursive display of data with blade, laravel

My Controller:
class Comments extends Controller {
public function GenerateComments($id){
$theme = DB::table('New_Themes')
->where('id', $id)
->get();
$Comments = NewTheme_Comment::where('id_theme', $id)->get();
return view('comments', ['Themes'=>$theme, 'Comments'=>$Comments]);
}
My Table(NewTheme_Comment):
id
parent_id
id_theme
user
text
upVotes
downVotes
My view(contains the recursive display of the tree of comments like the same in reddit), ......(data) contains the bootstrap media object, and the </div>'s things are used to round up (visually) the tree of comments as it should be:
<?php
tree($Comments, 0, 0);
$var = -1;
function tree($Comments, $parent_id = 0, $level=0, $c=0) {
global $var;
foreach($Comments as $Comment) {
if($Comment['parent_id'] == $parent_id) {
If ($level > $var) $var++; else {
for ($i = $var-$level+1; $i>0; $i--) { if ($c < 0) echo '</div> </div>'; else $c--; };
$var=$level;
};
echo '........(data)';
tree($Comments, $Comment['id'], $level+1,$c);
};
};
};
?>
The problem is that .........(data) should contain this stuff:
<div class="media">
<div class="media-left">
<img class="media-object" style="height:40px; width:40px;" src="{{ URL::asset("images/upVote.svg") }}" >
<div>{{$Comment->upVotes-$Comment->downVotes}}</div>
<img class="media-object" style="height:40px; width:40px;" src="{{ URL::asset("images/downVote.svg") }}" >
</div>
<div class="media-body">
<p class="media-heading">{{ $Comment->text }}</p>
<p class="media-heading">{{ $Comment->user }} / {{ $Comment->created_at }} </p>
And I am using the blade above this line | , which I can't integrate into that echo in view, replacing the ..........(data).
I have the intuition that the function I should integrate into the controller but I am broken(I spent to much time on recursive method of displaying comments) and I don't know how to take the data and print out it as whole unit recursively.
Any help is GREATLY appreciated to find a way out of this mess, thank you very much
Edit 1:
This is an example if i am filling with bootstrap media object in ........(data):
<div class="media">
<a class="media-left" href="#">
<img class="media-object" src="..." alt="...">
</a>
<div class="media-body">
<h4 class="media-heading">Media heading</h4>
Without 2 x </div>
You are approaching the views in a wrong way, as blade templates are not meant to use functions, it's better to follow the below recommendations.
The best way for that is to place the function code inside a blade file, for example recursive.blade.php:
recursive.blade.php
#foreach($comments as $comment)
//place your code here
#endforeach
Then in your main blade you can call it several times:
main.blade.php
<div>
#include('recursive', ['comments' => $comments])
</div>
The below example works for me and is the most widely used approach. remember the default value for parent_id is -1.
Model
public function children(){
return $this->hasMany(self::class,'parent_id','id')->with('children');
}
Controller
$comments = Comments::where('parent_id','=',-1)->get();
return view('comments',['comments'=> $comments]);
Blade (comments.blade.php)
<div class="tree">
#include('comment-list-widget',['comments' => $comment])
</div>
Blade (comment-list-widget.blade.php)
<ul>
#foreach($comments as $comment)
<li>
<a>{{$comment->text}}</a>
#if(!empty($comment->children) && $comment->children->count())
#include('comment-list-widget',['comments' => $comment->children])
#endif
</li>
#endforeach
</ul>

Resources