foreach in foreach in if blade php - php

#foreach ($capacityGroups as $capacityGroupFather)
#foreach ($exampleProjects as $k => $exampleProject)
#foreach ($exampleProject->capacityGroups as $j => $exampleCapacity)
#if ($exampleCapacity->id == $capacityGroupFather->id)
Only the first result of the loop
<div class="carousel-item active">
The rest of the loop
<div class="carousel-item">
We have the example Projects collection, each of which has capacityGroups.
I need to bring all the example Projects for each capacity Group. But the first of each goes into a special div (carousel-item active)
and the rest of each goes into (carousel-item) how can I fix this problem

Simply use the loop variable.
#foreach ($exampleProjects as $k => $exampleProject)
<div class="carousel-item{{ $loop->first ? ' active' : '' }}">
</div>
#endforeach

Related

setting variables inside a Laravel foreach loop

I've just started using the framework. In plain PHP after the opening foreach I would then set the variables then close the php tag but then from what I can work out you have to then do the Laravel #foreach tags and then open and close #php. Is there a way around this as it seems like a lot of extra work and code?
#foreach($steps as $row)
#php
$title = $row->title;
$text = $row->text;
$i = 1;
#endphp
<div class="steps-item grid-wrap">
<div class="number"
#if($text || $title)
<div class="text-wrap">
#if($title)
<h2>{{$title}}</h2>
#endif
{!! $text !!}
</div>
#php
$i++;
#endphp
#endif
</div>{{--END steps-item--}}
#endforeach
Since blade is no PHP, you have to return to PHP with that directive. But you can set/use the variables without doing that in your case:
#foreach($steps as $i => $row)
<div class="steps-item grid-wrap">
<div class="number"
#if($text || $title)
<div class="text-wrap">
#if($title)
<h2>{{ $row->title }}</h2>
#endif
{!! $row->text !!}
</div>
#php
$i++;
#endphp
#endif
</div>{{--END steps-item--}}
#endforeach
If you still want to set variables, there's a Laravel package called alexdover/blade-set. But as #brombeer pointed out, in most cases it's highly recommended to set all necessary variables in the controller before passing them to the view.
Use laravel provided loop variables:
$loop->iteration The current loop iteration (starts at 1).
It will increment in every loop iteration automatically.
e.g:
First iteration = $loop->iteration => 1 ;
Second iteration = $loop->iteration => 2 ;
so on until loop ends.
Check docs:
The Loop Variables
You can use a #for directive with sizeof($steps) like that:
#for($i=0; $i<= sizeof($steps)-1; $i++)
#endfor
#foreach ($steps as $row)
<div class="steps-item grid-wrap">
<div class="number">
<div class="text-wrap">
#if ($row->title != '')
<h2>{{$row->title}}</h2>
/* if you want to display another title when its blank you can
use if-else here otherwise not need to use if conditions for
title and text */
#endif
#if ($row->text != '')
{!! $row->text !!}
#endif
</div>
</div>
</div>
#endforeach
{{--
for an example you have $steps values like
$steps =
Array(
[0] -> 1,
[1] -> 'title',
[2] -> 'text'
);
if you want this array key value pair you have to use #foreach like
#foreach ($steps as $key=>$value)
#endforeach
you can use key value in #foreach loop only
--}}

Display text on each iteration laravel Livewire

I need your help. Lets say I have array with 10 elements and every record to be shown on every iteration and I want to be done with Livewire, let me share with you some code and will tell you what I have tried till now.
public $content;
public $array = ['first', 'second', 'third' ,'fourth'];
foreach ($array as $item) {
sleep(1);
$this->content[] = "Element ${item}";
}
<div class="modal-body">
#if ($content)
<ul class="listree">
#foreach ($content as $element)
<li>
<div class="listree-submenu-heading">
{!! $element['title'] !!}
</div>
<ul class="listree-submenu-items">
#foreach ($element['elements'] as $sub)
<li>
<div class="listree-submenu-heading">
{!! $sub['title'] !!}
</div>
</li>
#endforeach
</ul>
</li>
#endforeach
</ul>
#endif
</div>
My idea is display first record, wait 1 second, display first and second record, wait 1 second, display first, second and third records and so on... How I can do this with livewire. The problem is that $content is filled with the information after all iteration and then the component is refreshed.
I tried on every iteration to send custom event which will call refresh method, but without succes. I will appreaciate any advice, and if you need more information, I will provide it.
Assumming you're also using alpinejs, this can be done pretty easily.
<x-app-layout>
<div class="text-gray-800 ml-10">
<ul class="bg-green-200">
<!-- The main foreach loop. -->
#foreach (range('a', 'z') as $element)
<!-- render al <li> tags with display:none. -->
<!-- Show the 1st after 0s, the 2nd after 1s, the 3rd after 2s, ... -->
<li class="bg-blue-200 m-5"
x-data="{show: false, index: {{ $loop->index }} }"
x-init="setTimeout(() => show = true, index * 1000)">
<div x-show="show">
{{ $element }}
...
</div>
</li>
#endforeach
</ul>
</div>
</x-app-layout>
$loop is a special object you can access within a #foreach block.

add rows and columns base on condition in laravel blade

I'm trying to create UI for cinema seats in laravel blade. i have seat_rows and seat_coulmns in my database and seat_rows will be the same for 2 rows. i mean first row is like this: id:1 seat_row:1 seat_column:1 and second row is like this: id:2 seat_row:1 seat:column:2. so i using bootstrap row and col classes and i wanna add row class only when number of seat_row changes. how can I DO that?
#foreach ($allseats as $seat)
{{-- #while ($seat->seat_row !== $seat->seat_row) --}}
<div id="{{$seat->seat_row}}" class="row ">
{{-- #for ($i = 1; $i <= 2; $i++) --}}
<div id="{{$seat->id}}" class="col-2 seats ">
<img src="{{asset('assets/img/seats/seat1.png')}}" alt="" style="height:50px;width:50px">
</div>
{{-- #endfor --}}
</div>
{{-- #endwhile --}}
{{$newrow=$seat->seat_row}}
#endforeach
you need to compare it with the previous seat.
Instead of using #foreach ($allseats as $seat) you can use #foreach ($allseats as $key => $seat)
and then check in your loop if $seat !== $allseats[$key-1]
I hope that guides you on the correct track.

How to figure the question into 100 in relationship in laravel

I have two models 1. Subject 2. Question and it has One to many relation. And a student can choose many subjects he want. And now I want to take a test through the subjects. And the test should be 100 marks test.Now i need a way how to accomplish the 100 marks test. Suppose a student choose 3 subjects and if we divide 3 form 100 then it will be 33 (floor) or 34 (ceil) per subject but i want to round it to 100, how i accomplish this. Here is my code for getting the questionsn
foreach ($student->departments as $key => $department){
$majorSubjects[] =$department->subject_id;
}
$no_of_questions =100;
$uniqueSubjects=array_unique($majorSubjects);
$div = ceil($no_of_questions/count($uniqueSubjects));
$mul = $div*count($uniqueSubjects);
$subjects=Subject::whereIn('id',$majorSubjects)->get();
}
and in my blade
#foreach($subjects as $key => $subject)
<li class=" {{$key == 0 ? 'active' : ''}}">{{$subject->name}}</li>
#endforeach
</ul>
<div class="tab-content">
#if(!empty($subjects))
#foreach($subjects as $key => $subject)
<div class="tab-pane {{$key == 0 ? 'active' : ''}}" id="tab_{{ $subject->id }}">
#foreach($subject->questions->random($div) as $num => $question)
<form></form>
#endforeach
You can use modulus to get the remaining mark test.
$additional_mark_test = $no_of_questions % count($uniqueSubjects);
Put it in here.
foreach ($student->departments as $key => $department){
$majorSubjects[] =$department->subject_id;
}
$no_of_questions =100;
$uniqueSubjects=array_unique($majorSubjects);
$div = ceil($no_of_questions/count($uniqueSubjects));
$mul = $div*count($uniqueSubjects);
// Get the remaining test
$additional_mark_test = $no_of_questions % count($uniqueSubjects);
$subjects=Subject::whereIn('id',$majorSubjects)->get();
}
In your blade, this will check first if $additional_mark_test is empty.
#if(!empty($additional_mark_test))
#foreach($subject->questions->random($additional_mark_test) as $num => $question)
<form></form>
#endforeach
#php $additional_mark_test = 0; #endphp
#endif
Put it in here.
#foreach($subjects as $key => $subject)
<li class=" {{$key == 0 ? 'active' : ''}}">{{$subject->name}}</li>
#endforeach
</ul>
<div class="tab-content">
#if(!empty($subjects))
#foreach($subjects as $key => $subject)
<div class="tab-pane {{$key == 0 ? 'active' : ''}}" id="tab_{{ $subject->id }}">
#foreach($subject->questions->random($div) as $num => $question)
<form></form>
#endforeach
<!--Additional Mark Test(This will be add to first subject)-->
#if(!empty($additional_mark_test))
#foreach($subject->questions->random($additional_mark_test) as $num => $question)
<form></form>
#endforeach
#php $additional_mark_test = 0; #endphp
#endif

How to display something only for the first item from the collection in Laravel Blade template

I have a #foreach loop in the Blade template and need to apply special formatting to the first item in the collection. How do I add a conditional to check if this is the first item?
#foreach($items as $item)
<h4>{{ $item->program_name }}</h4>
#endforeach`
Laravel 5.3 provides a $loop variable in foreach loops.
#foreach ($users as $user)
#if ($loop->first)
This is the first iteration.
#endif
#if ($loop->last)
This is the last iteration.
#endif
<p>This is user {{ $user->id }}</p>
#endforeach
Docs: https://laravel.com/docs/5.3/blade#the-loop-variable
SoHo,
The quickest way is to compare the current element with the first element in the array:
#foreach($items as $item)
#if ($item == reset($items )) First Item: #endif
<h4>{{ $item->program_name }}</h4>
#endforeach
Or otherwise, if it's not an associative array, you could check the index value as per the answer above - but that wouldn't work if the array is associative.
Just take the key value
#foreach($items as $index => $item)
#if($index == 0)
...
#endif
<h4>{{ $item->program_name }}</h4>
#endforeach
As of Laravel 7.25, Blade now includes a new #once component, so you can do it like this:
#foreach($items as $item)
#once
<h4>{{ $item->program_name }}</h4> // Displayed only once
#endonce
// ... rest of looped output
#endforeach
Laravel 7.* provides a first() helper function.
{{ $items->first()->program_name }}
*Note that I'm not sure when this was introduced. So, it may not work on earlier versions.
It is only briefly mentioned in the documentation here.
The major problem with Liam Wiltshire's answer is the performance because:
reset($items) rewind the pointer of $items collection again and again at each loop... always with then same result.
Both $item and the result of reset($item) are objects, so $item == reset($items) requires a full comparison of its attributes... demanding more processor time.
A more efficient and elegant way to do that -as Shannon suggests- is to use the Blade's $loop variable:
#foreach($items as $item)
#if ($loop->first) First Item: #endif
<h4>{{ $item->program_name }}</h4>
#endforeach
If you want to apply a special format to the first element, then maybe you could do something like (using the ternary conditional operator ?: ):
#foreach($items as $item)
<h4 {!! $loop->first ? 'class="special"': '' !!}>{{ $item->program_name }}</h4>
#endforeach
Note the use of {!! and !!} tags instead of {{ }} notation to avoid html encoding of the double quotes around of special string.
Regards.
if you need only the first element you can use #break inside your #foreach or #if.see example:
#foreach($media as $m)
#if ($m->title == $loc->title) :
<img class="card-img-top img-fluid" src="images/{{ $m->img }}">
#break
#endif
#endforeach
you can do it by this way.
collect($users )->first();
To get the first element of a collection in Laravel, you can use :
#foreach($items as $item)
#if($item == $items->first()) {{-- first item --}}
<h4>{{$item->program_name}}</h4>
#else
<h5>{{$item->program_name}}</h5>
#endif
#endforeach

Categories