Here is a blade template of my table, where I have issues changing rows depending on a value. If the command number changes I want the row and all the following rows with that command number to change and then alternate between white/grey colors everytime it's a different one.
I know it looks pretty basic but I can't make the condition in my algorithm. My first if looks if the previous iteration has a different command number and change the class, but I'm missing the one checking if the previous iteration has the same command number so keep the same background. I don't know how to check something css class and alternate the 2 backgrounds white/grey. I tried with $attributes from Laravel but it is always undefined.
I hope I was clear with my issue, also the table is already sorted by increasing command_number.
If you need the controller I can provide it.
Thanks
tr.second th, tr.second td {
background-color: #D1D1D1;
}
//////
<tbody>
#foreach($data as $key => $line)
#if($key > 0)
<tr #if ($data[$key]['command_number'] != $data[$key-1]['command_number']) class="second"
#elseif()
#endif>
#foreach($line as $item)
#if(($item == $line['quantity']) || ($item == $line['delivery']))
<td>
<strong>{{$item}}</strong>
</td>
#elseif($item == $line['hours'])
<td>
<strong style="color: red;">{{$item}}</strong>
</td>
#else
<td>
{{$item}}
</td>
#endif
#endforeach
</tr>
#endif
#endforeach
</tbody>
If you want to change the class based on a previous result, why don't you track the css class to use with a toggle variable outside of the loop like so:
// in your blade file
#php
$toggle = false;
#endphp
#foreach(range(0, 10) as $number)
<div class="#if($toggle) someClass #else otherClass #endif unrelatedClasses">
</div>
#php
$toggle = !$toggle
#endphp
#endforeach
Alternatively, the toggle should function in your case:
// You could change the value of toggle based on your use case, like:
#php
$toggle = ($data[$key]['command_number'] != $data[$key-1]['command_number']);
#endphp
Instead of using $key, you can also use $loop->index to get the current iteration.
Loop variable for even/odd cases
For other use cases, the loop variable has several properties and methods you can use (like even, odd). Check out the Blade documentation.
CSS selector for even/odd cases
There are also CSS solutions using selectors like: nth-child(even) and nth-child(odd) for even and odd numbers respectively.
<tbody>
#php($currentKey = null)
#foreach($data as $key => $line)
#if($key > 0)
<tr #if ($data[$key]['command_number'] != $currentKey) class="second"
#elseif()
#endif>
#foreach($line as $item)
#if(($item == $line['quantity']) || ($item == $line['delivery']))
<td>
<strong>{{$item}}</strong>
</td>
#elseif($item == $line['hours'])
<td>
<strong style="color: red;">{{$item}}</strong>
</td>
#else
<td>
{{$item}}
</td>
#endif
#endforeach
</tr>
#endif
#php($currentKey = $data[$key]['command_number'])
#endforeach
</tbody>
Related
I tried to generate PDF using barryvdh/laravel-dompdf in Laravel 8. My table is using rowspan. I could generate the PDF successfully, but it's not build the rowspan correctly on the page break like this. This only happened on the last two page. I already tried to setting my CSS and style, used page-break-after:always; , and $loop->iteration but it's still didn't work. This is my code:
View:
<tbody>
#foreach($sasarans as $i => $sasaran)
#foreach($sasaran->indikator as $indikator)
#foreach($indikator->pertanyaan as $pertanyaan)
<tr style="margin-top:-20px; margin-bottom:-25px;">
//Some data here
#foreach($pertanyaan->data_laporan as $data)
//Some data
#if($loop->iteration % 15 == 0)
<div class="page-break"></div>
#endif
#endforeach
</tr>
#endforeach
#endforeach
#endforeach
</tbody>
CSS:
.page-break {
display:block;
page-break-after: always;
}
Please help me because I'm still a beginner. Thank you for your help.
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
--}}
I am trying to show the table like below image
And i write the logic for this table creation is below
#foreach($users as $key => $user)
<tr>
<td>{{$key+1}}</td>
<td>{{$user->name}}</td>
<td rowspan="{{count($users->where('area',$user->area))}}">
{{$user->userarea->name}}</td>
<td rowspan="{{count($user->candidate->election->candidates)}}">{{$user->candidate->election->name}}</td>
</tr>
#endforeach
</tbody>
But this code produce me the following code like this
Here The Election and Candidate has one to many relationships and candidate and user has one one to one relationshipHelp me achieve my expected results.
You could keep track of which elections/area's have been rendered already. This could be done by creating an array containing a reference to these objects. Then in the template just add an if statement checking whether an election/area has been rendered:
<?php $renderedElections = []; ?>
<?php $renderedAreas = []; ?>
#foreach($users as $key => $user)
<tr>
<td>{{$key+1}}</td>
<td>{{$user->name}}</td>
#if (!in_array($user->userarea->name, $renderedAreas))
<?php $renderedElections[] = $user->userarea->name ?>
<td rowspan="{{count($user->userarea->name)}}">
{{$user->userarea->name}}
</td>
#endif
#if (!in_array($user->candidate->election->name, $renderedElections))
<?php $renderedElections[] = $user->candidate->election->name ?>
<td rowspan="{{count($user->candidate->election->candidates)}}">
{{$user->candidate->election->name}}
</td>
#endif
</tr>
This is not the best solution, but its simple and easy. For this to work, the users must be sorted perfectly by election and area.
This code is untested but should theorethically work. I tryied to gather informations about your model relationships from the code you posted, but it might need some tweaking with the model names and relations.
The following code basically fetches all the users each with their area, candidate and candidate.election relationships, then group users by 'election name' (first criteria), then 'area name' (second criteria).
The resulting array will be something like this:
// $elections will be:
// [
// 'Presidential' => [
// 'Dhaka-5' => [ candidates for that area in that election type ],
// 'Dhaka-1' => [ candidates for that area in that election type ],
// ...
// ],
// ...
// ]
In your controller do:
$elections = User::with('area', 'candidate.election')->get()->groupBy(function ($user) {
return $user->candidate->election->name;
}, function ($user) {
return $user->area->name;
});
// then pass $elections to the view...
Then in your view:
<table>
#php ($i = 1)
#foreach ($elections as $election => $areas)
#foreach ($areas as $area => $candidates)
#php ($areaLoop = $loop)
#foreach ($candidates as $user)
<tr>
<td>{{ $i++ }}</td>
<td>{{ $user->name }}</td>
#if ($loop->first)
<td rowspan="{{ $candidates->count() }}">{{ $area }}</td>
#endif
#if ($areaLoop->first)
<td rowspan="{{ $areas->sum(function ($area) { return $area->count(); }); }}">{{ $election }}</td>
#endif
</tr>
#endforeach
#endforeach
#endforeach
</table>
Note that $candidates->count() will be the number of candidates for that particular election area of the current election type. $areas->sum(...) will sum the number of candidates for each area to get the total count of candidates in that election type.
If you need further explaination or something doesn't work, just let me know. All the documentation about the collection functions I used is available here.
Here i have a 'work' array (generating from excel file) which has values employee_id(here id),projects ands hours.I also have another array 'employees' which has all the employees in my database. Here i need to check if the employee exist in my database by comparing with the ids. If employee exists, i need to change the background color of the table row.I tried this method but not working, please help .
#foreach($val['work'] as $k3=> $val3)
#if(isset($val3['hours']) && isset($val3['projects']))
<tr #foreach($employees as $employee) #if($employee->emp_id ==$val3['id'][1]) style="background-color:#ffe1df;" #endif #endforeach>
<td>{{$val3['id'][1]}}</td>
<td>{{$val3['name'][2]}}</td>
</tr>
#endif
#endforeach
Try setting a flag value :
#foreach($val['work'] as $k3=> $val3)
#if(isset($val3['hours']) && isset($val3['projects']))
#php $flag=0; #endphp
#foreach($employees as $employee) #if($employee->emp_id == $val3['id'][1]) #php $flag=1 #endphp #endif #endforeach
<tr #if($flag==0) style="background-color:#ffe1df;" #endif>
<td>{{$val3['id'][1]}}</td>
<td>{{$val3['name'][2]}}</td>
</tr>
#endif
#endforeach
So here I want to append the id of the currently logged in user to the name of a table, like for example Rating_User_1, but the 1 here comes from the id of the logged in user. I assigned the id of the logged in user to $id, as shown below in the code, and append it to the table column name, but this doesn't work. I tried echoing the $id by itself and it works (i.e. it spits out the id of the logged in user but that's not what I want), but when I try to append it to the string in order to "emulate" the table name it doesn't work. Any tips on workarounds?
#foreach($data as $data)
<tr>
<td> {{$loop->iteration}} </td> <!-- add number to the row -->
<td>
<a href="{{ Url('reply_thread') }}/{{ $data->id }}" class="text" >{{ $data->Judul }}</a>
</td>
<td><?php $id = Auth::user()->id;
echo $data->Rating_user_[$id]; ?> </td>
</tr>
#endforeach
My controller:
function threads() {
$data=Thread::all();
return view('thread.thread', ['data'=>$data]);
}
and some of the tables in the table Thread has columns named Rating_user_1, Rating_user_2, etc.
Variable expansion sometimes needs curly braces to function properly. The following should work:
echo $data->{'Rating_user_' . $id}
See Variable Parsing - Complex Syntax for info on "curly brace" variable expansion.
While it doesn't look like you need it here, Variable Variables may also be useful to read up on. (aka, $a = 'b'; $b = 'hello'; echo $$a; // Same as "echo $b", outputs 'hello')
You could try:
#foreach($data as $data)
<tr>
<td> {{$loop->iteration}} </td> <!-- add number to the row -->
<td>
<a href="{{ Url('reply_thread') }}/{{ $data->id }}" class="text" >
{{ $data->Judul }}
</a>
</td>
<td>{{ $data->{'Rating_user_' . $id} }}</td>
</tr>
#endforeach
You have multiple options to achieve this, the first would be to call the property/method with the name stored in a variable:
$tableName = 'Rating_user_' . $id;
$tableName = "Rating_user_$id";
$data->$tableName;
You could also use curly braces to make a hot concat on the property/method call itself as #romellem suggested:
$data->{'Rating_user_' . $id}
$data->{"Rating_user_$id"}
If you are going to access the $data->Rating_user more than once I would recommend you the first approach, if not the second one is okey aswell.
I think that your code is almost correct, and I think it's better if you use double curly than use echo like:
#foreach($data as $data)
<tr>
<td> {{$loop->iteration}} </td> <!-- add number to the row -->
<td>
<a href="{{ Url('reply_thread') }}/{{ $data->id }}" class="text" >{{ $data->Judul }}</a>
</td>
<td>{{ $data->{'Rating_user_' . Auth::id()} }}</td>
</tr>
#endforeach