I want to count in if statement in foreach loop laravel 5.6 - 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

Related

How do I use a row count in an #if in a Laravel view?

I am brand new to Laravel and I'm running Version 6.
I want my view to display a button if one of my MySQL tables has rows that meet a specific condition but I'm having trouble figuring out how to code it - and even WHERE to code it - within my Laravel application.
My MySQL table is called diary_entries and various users of the system will contribute zero to n rows to it. Each row of the table contains a user id called client. When a given user goes to the Welcome view, I want the view to determine if that user currently has any rows in the diary_entries table. If he does, I want to display a button that will take him to another page where the entries can be displayed or edited or deleted.
I think I want to construct an #if that counts the number of records for that user; if the count is greater than zero, I want to display the button, otherwise the button is not displayed.
The problem is that I can't figure out how to code this. I've looked at the examples in the Eloquent section of the manual but they aren't particularly clear to me. I found a note near the top that said the count() function expects a Collection as an argument and that the result of an Eloquent statement is always a Collection so I guessed that I just have to execute an Eloquent query, then apply count() to the resulting Collection. But every variation of that idea which I've tried has thrown exceptions.
Here was the guess that seemed most logical to me:
#extends('layout');
#section('content');
<div class="content">
<img class="centered" src="/images/sleeping-cat.jpg" alt="sleeping cat" height="250">
<div class="title m-b-md">
<h1> Sleep Diary </h1>
</div>
<div>
<h3>{{Auth::user()->name }}</h3>
</div>
<div>
#if (count(App\DiaryEntry::select('*')->where('client', Auth::user()->name) > 0))
<p>
<a class="btn btn-primary"> View / edit existing sleep diary entries </a>
</p>
#endif
</div>
<div>
<p>
<a class="btn btn-primary" href="/diaryEntries"> Create a new sleep diary entry </a>
</div>
</div>
#endsection
This is obviously wrong because it throws an exception so how do I make it right? Does the building of the collection have to move into the Controller? If so, how do I invoke the method and see its result? Or can I do something like I have already done but just adjust the syntax a bit?
EDIT
I've imitated Sehdev's suggestion but I get this error:
$count is undefined
Make the variable optional in the blade template. Replace {{ $count }} with {{ $count ?? '' }}
Here is my welcome view:
#extends('layout');
#section('content');
<div class="content">
<img class="centered" src="/images/sleeping-cat.jpg" alt="sleeping cat" height="250">
<div class="title m-b-md">
<h1>Sleep Diary</h1>
</div>
<div>
<h3>{{ Auth::user()->name }}</h3>
</div>
<div>
#if ($count) > 0))
<p>
<a class="btn btn-primary">View/edit existing sleep diary entries</a>
</p>
#endif
</div>
<div>
<p><a class="btn btn-primary" href="/diaryEntries">Create a new sleep diary entry</a>
</div>
</div>
#endsection
And this is the relevant function from DiaryEntryController:
public function countEntriesOneUser()
{
$count = DiaryEntry::select('*')->where('client', Auth::user()->name)->count();
view("welcome", compact("count"));
}
Should the compact function be returning $count instead of count? I can't find the compact function in the manual with the search function so I'm not clear what it does or what the proper syntax is. I just tried changing the last line of the function to
view("welcome", $count);
but that produced the same error.
Try this,
#php
$count=\App\DiaryEntry::where('client', Auth::user()->name)->count();
#endphp
#if($count>1)
<p><a class="btn btn-primary">View/edit existing sleep diary entries</a></p>
#endif
Using App\DiaryEntry::select('*')->where('client', Auth::user()->name) directly on your blade template is a bad practise.
You can execute your question in your controllers method and then pass the result on your view file
Your function
function test(){
$count = DiaryEntry::select('*')->where('client', Auth::user()->name)->count(); // get the total no of records using count
view("index", compact("count")) // pass your count variable here
}
then you can directly use $count in your #if condition
Your blade template
<div>
#if ($count > 0)
<p><a class="btn btn-primary">View/edit existing sleep diary entries</a></p>
#endif
</div>

How can I filter the data of foreach?

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

modulus with remainder laravel

I am trying to setup columns of 4 from a laravel array which works correctly. The problem is how do you handle remainders? With my loop I end up with 2 extra divs that are empty at the end of my output. I have 10 items that i'm looping over which would give me a remainder of 2.5 Here is my code.
<div class="serviceListingColumn">
<ul>
#foreach($serviceListings as $serviceListing)
#if ($serviceListing->service_category == $services->title)
<li class="serviceListingItem">{{$serviceListing->service_name}}</li>
#endif
#if($loop->iteration % 4 === 0)
</ul>
</div>
<div class="serviceListingColumn">
<ul>
#endif
#endforeach
</ul>
I would suggest chunking the original array into groups, then just looping those. Easier for the template logic.
// Use the Collection's group() functionality in your controller.
// Use collect() if it isn't a Collection already.
$array = collect($array)->chunk(4);
// Your template then doesn't need to worry about modulus,
// and can focus on displaying the chunked groups.
#foreach ($array as $group)
<div class="serviceListingColumn">
<ul>
#foreach ($group as $serviceListing)
<li class="serviceListingItem">{{ $serviceListing->service_name }}</li>
#endforeach
</ul>
</div>
#endforeach

How to put div in every 5th row laravel

I would like to put another code of div in every 5th row. Something like:
#foreach ($vip_ads as $key=>$ad)
#if($key%30==0) {
<div></div>
}
#include('front.ad.ad_template.view')
#endforeach
#foreach ($ads as $key=>$ad)
#if($key%30==0) {
<div></div>
}
#include('front.ad.ad_template.view')
#endforeach
My laravel version is 4. So I can't use new loop->iteration function. The problem is that it doesn't give a new block to a div. Everything in one line, meanwhile I need to close 5th row (6 columns total 30 elements) and put a new div, after that continue with the given $key value until it gets for example 60. And the next problem is that I could have less than 10 values in $vip_ads, but in total it has to be 30 for both $vip_ads and $ads. Sorry, for my english. Example of this can seen at http://zaza.iknobel.kz/catalog-ad/index/17
I use only laravel 5.x but your code is not bad, be carefull your key have to be numeric, or add $i=0; before with php and $i++ in the loop
#foreach ($vip_ads as $key=>$ad)
#if($key%5==0)
<div></div>
#endif
#include('front.ad.ad_template.view')
#endforeach
or
<?php $id=0;?>
#foreach ($vip_ads as $ad)
<?php $i++;?>
#if($i%5==0)
<div></div>
#endif
#include('front.ad.ad_template.view')
#endforeach
Edit :
Use something like bootstrap with col-md-3 for ad_template (A) and col-md-12 for div (-----) it will look like this :
A A A A
-------
A A A A

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