my application basically generate reports for some users
I fetch the rows from the database
every row contains a 'name' and 'work time' and others...
every user has multiple rows with the same name but a different work time value
I calculated the total of the 'work time' in the blade depending on the next row if its the same name I 'll keep adding work time, if the next row is for another user then I will show the total for the current user and start calculating the total for the next user
my problem is with pagination:
at the end of each page, the rows of the same user do not appear all of it
and my blade logic calculate only what appears on that page (see the picture)
notice here that other rows with the same name exist in the second page
and their total calculated separately
is there is any way to tell the paginator to devise rows on a condition besides that number ->paginate(15+condition) because I want all the rows for a specific user to stay on the same page.
this is the query:
$shifts = DB::table('driver_shifts')
->join('drivers','drivers.PermitNumber','=','driver_shifts.driver_badge_id')
->where ('driver_shifts.shift_start_time','>',$startDate)
->where ('driver_shifts.shift_start_time','<',$endDate)
->orderby('drivers.LastName')
->orderby('driver_shifts.shift_start_time')
->paginate(20)
->appends(request()->query());
this is the blade logic inside a table. Ps: I know it not a good practice but I coudn't find a better way to do it in the controller:
$total_time = 0.00;
$break_time = 0.00;
$work_time = 0.00;
for ($i = 0; $i < count($shifts); $i++)
{
$break_time_item = $shifts[$i]->total_time - $shifts[$i]->work_time;
echo '<tr>';
echo '<td>' . $shifts[$i]->FirstName . ' ' . $shifts[$i]->LastName . '</td>';
echo '<td>' . $shifts[$i]->vehicle_id . '</td>';
echo '<td>' . $shifts[$i]->shift_start_time . '</td>';
echo '<td>' . $shifts[$i]->shift_end_time . '</td>';
echo '<td>' . $shifts[$i]->total_time . '</td>';
echo '<td>' . $break_time_item . '</td>';
echo '<td>' . $shifts[$i]->work_time . '</td>';
echo '</tr>';
//calculation totals for the current driver
//dd($shifts[$i]->break_time);
$total_time = $total_time + $shifts[$i]->total_time;
$work_time = $work_time + $shifts[$i]->work_time;
if (isset($shifts[$i + 1]))
{
if ($shifts[$i]->LastName !== $shifts[$i + 1]->LastName)
{
//calculating break time
$break_time = $total_time - $work_time;
//converting minutes to houres
$total_time_hours = floor($total_time / 60);
$total_time_min = $total_time - ($total_time_hours * 60);
$work_time_hours = floor($work_time / 60);
$work_time_min = $work_time - ($work_time_hours * 60);
$break_time_hours = floor($break_time / 60);
$break_time_min = $break_time - ($break_time_hours * 60);
echo '<tr class="table-primary text-uppercase ">';
echo '<td colspan="4">' . $shifts[$i]->FirstName . ' ' . $shifts[$i]->LastName . ' TOTAL ' . '</td>';
if ($total_time_hours == 0 && $total_time_min == 0)
{
echo '<td>-</td>';
}
else
{
echo '<td>' . $total_time_hours . "h:" . $total_time_min . "min" . '</td>';
}
if ($break_time_hours == 0 && $break_time_min == 0)
{
echo '<td>-</td>';
}
else
{
echo '<td>' . $break_time_hours . "h:" . $break_time_min . "min" . '</td>';
}
if ($work_time_hours == 0 && $work_time_min == 0)
{
echo '<td>-</td>';
}
else
{
echo '<td>' . $work_time_hours . "h:" . $work_time_min . "min" . '</td>';
}
echo '</tr>';
$total_time = 0;
$break_time = 0;
$work_time = 0;
}
}
I am having two functions printBefore(json1) and printAfter(json2).
Both are having json object as parameter.jsons are coming from database. They are parsing json and displaying it in correct format.
But it is taking more than 30 seconds.
When I removed functon and displays json as it is. It is not taking time more than second.
I am not able isolate problem. Please Help.
foreach ($records as $record) {
echo '<tr>';
echo '<td>' . $userNames['users'][$record->uid] . '</td>';
echo '<td>' . $userNames['users'][$record->uid] . '</td>';
echo '<td>' . $record->val . '</td>';
echo '<td>' . $record->mi. '</td>';
echo '<td>' . $record->created_on . '</td>';
echo '<td>' . printBefore($record->newData) . '</td>';
echo '<td>' . printAfter($record->oldData) . '</td>';
echo '</tr>';
}
Code for printAfter($oldData)
$oldData = json_decode($oldData, true);
if (isset($OldData['sub_category'])) {
$str = $str . "|Category : " . $this->category[$OldData['sub_category']] . "|";
}
code for PrintBefore($newData)
$newData = json_decode($newData, true);
if (isset($newData['sub_category'])) {
$str = $str . "|Category : " . $this->category[$newData['sub_category']] . "|";
}
How can I properly do the the numbering of the results? What i did was
<?php
if($results)
{
$x = 1;
foreach ($results as $data)
{
echo '<tr>';
echo '<td>' . $x++. '</td>';
echo '<td>' . $data->item_id . '</td>';
echo '<td>' . $data->item_name . '</td>';
echo '<td>' . $data->item_category . '</td>';
echo '<td>' . $data->item_costprice . '</td>';
echo '<td>' . $data->item_retailprice . '</td>';
echo '<td>' . $data->item_tax . '%</td>';
echo '</tr>';
}
}
?>
But it has the same numbering per page.
The numbering starts with 1 because thats the value you assign to it before the loop starts.
Assuming you pass the page number to your controller your could do the following:
$x = count($results) * ($pagenumber-1);//use count or some other type of count method
This will make the $x value 1 on the first page, 31 on the second page, 61 on the third page etc...
Then inside the loop change $x++ to ++$x otherwise the first page will be counted from 0 to 29.
I have this table "city" in my database:
|id |id_city_a |id_city_b|distance|
|1 |1 | 1 | 0 |
|2 |1 | 2 | 8 |
|3 |1 | 3 | 6 |
|4 |2 | 1 | 8 |
|5 |2 | 2 | 0 |
|6 |2 | 3 | 9 |
|7 |3 | 1 | 6 |
|8 |3 | 2 | 9 |
|9 |3 | 3 | 0 |
I want the end result to be in a matrix, such as:
| | 1 | 2 | 3 |
| 1 | 0 | 8 | 6 |
| 2 | 8 | 0 | 9 |
| 3 | 6 | 9 | 0 |
This is my code :
function random()
{
include('config/koneksi.php');
$result = mysql_query("select * from temp_hasil");
$n =mysql_num_rows(mysql_query("SELECT * FROM temp_hasil"));
for ($i = 1; $i <= $n; $i++)
{
for ($j = 1; $j <= $n; $j++)
{
$rows = mysql_fetch_array($result);
$this->table[$i][$j] = $i == $j ? INF : $rows['id'];
}
}
}
function __toString()
{
$str = '<table class="table table-bordered" id="tableInput"> <tbody>';
$str .= '<tr><td></td>';
foreach ($this->table as $rowName => $row)
{
$str .= "<td>$rowName</td>";
}
$str .= '</tr>';
foreach ($this->table as $rowName => $row)
{
$str .= "<tr><td>$rowName</td>";
foreach ($row as $columnName => $value)
{
$str .= "<td>";
$str .=
'<input class="form-control" type="text" value="' . $value . '" name="table[' . $rowName . '][' .
$columnName . ']" requied' . ($columnName == $rowName ? ' disabled' : '') . '>';
$str .= "</td>";
}
$str .= '</tr>';
}
$str .= '</tbody></table>';
return $str;
}
}
$str .= '</tr>';
foreach ($this->table as $rowName => $row)
{
$str .= "<tr><td>$rowName</td>";
foreach ($row as $columnName => $value)
{
$str .= "<td>";
$str .=
'<input class="form-control" type="text" value="' . $value . '" name="table[' . $rowName . '][' .
$columnName . ']" requied' . ($columnName == $rowName ? ' disabled' : '') . '>';
$str .= "</td>";
}
$str .= '</tr>';
}
$str .= '</tbody></table>';
return $str;
}
`
How do I code it in php? please help me.
Make city_a index completely different from city_b index so it is easy to check.
// generate a two-dimensional matrix in here
$distMatrix = array();
foreach($tableRows as $cityDist) {
$from = $cityDist['id_city_a'];
$to = $cityDist['id_city_b'];
$dist = $cityDist['distance'];
$distMatrix[$from][$to] = $dist;
}
Display as an HTML Table...
echo '<table border="1">';
echo '<tr>';
echo '<td>', '#', '</td>';
foreach(array_keys(current($distMatrix)) as $city_b) { // city_b headings
echo '<td>', $city_b ,'</td>';
}
echo '</tr>';
foreach(array_keys($distMatrix) as $city_a) { // need the city_a as row index
echo '<tr>';
echo '<td>', $city_a, '</td>'; // city_a ad
foreach(array_keys($distMatrix[$city_a]) as $city_b) { // need the city_b as column index
echo '<td>', $distMatrix[$city_a][$city_b], '</td>'; // distance from the matrix;
}
echo '</tr>';
}
echo '</table>';
Test data - used data from #ashkufaraz
// changed the city ids so we can easily see city_a and city_b
$tableRows[0]=array("id"=>1, "id_city_a"=>1, "id_city_b"=>11, "distance"=>0);
$tableRows[1]=array("id"=>2, "id_city_a"=>1, "id_city_b"=>12, "distance"=>8);
$tableRows[2]=array("id"=>3, "id_city_a"=>1, "id_city_b"=>13, "distance"=>6);
$tableRows[3]=array("id"=>4, "id_city_a"=>2, "id_city_b"=>11, "distance"=>8);
$tableRows[4]=array("id"=>5, "id_city_a"=>2, "id_city_b"=>12, "distance"=>0);
$tableRows[5]=array("id"=>6, "id_city_a"=>2, "id_city_b"=>13, "distance"=>9);
$tableRows[6]=array("id"=>7, "id_city_a"=>3, "id_city_b"=>11, "distance"=>6);
$tableRows[7]=array("id"=>8, "id_city_a"=>3, "id_city_b"=>12, "distance"=>9);
$tableRows[8]=array("id"=>9, "id_city_a"=>3, "id_city_b"=>13, "distance"=>0);
Output:
# 11 12 13
1 0 8 6
2 8 0 9
3 6 9 0
try like this
Online Demo
$tableRows[0]=array("id"=>1,"id_city_a"=>1,"id_city_b"=>1,"distance"=>0);
$tableRows[1]=array("id"=>2,"id_city_a"=>1,"id_city_b"=>2,"distance"=>8);
$tableRows[2]=array("id"=>3,"id_city_a"=>1,"id_city_b"=>3,"distance"=>6);
$tableRows[3]=array("id"=>4,"id_city_a"=>2,"id_city_b"=>1,"distance"=>8);
$tableRows[4]=array("id"=>5,"id_city_a"=>2,"id_city_b"=>2,"distance"=>0);
$tableRows[5]=array("id"=>6,"id_city_a"=>2,"id_city_b"=>3,"distance"=>9);
$tableRows[6]=array("id"=>7,"id_city_a"=>3,"id_city_b"=>1,"distance"=>6);
$tableRows[7]=array("id"=>8,"id_city_a"=>3,"id_city_b"=>2,"distance"=>9);
$tableRows[8]=array("id"=>9,"id_city_a"=>3,"id_city_b"=>3,"distance"=>0);
$counter=0;
$result=array();
foreach($tableRows as $tableRow)
{
$result[$tableRow["id_city_a"]][$tableRow["id_city_b"]]=array("id_city_a"=>$tableRow["id_city_a"],"id_city_b"=>$tableRow["id_city_b"],"distance"=>$tableRow["distance"] );
}
now in $result[cityA][cityB]=distance
get unique_id_city_a for column
$unique_id_city_a = array_unique(array_map(function ($i) { return $i['id_city_a']; }, $tableRows));
echo "\t";
foreach($unique_id_city_a as $R)
{
echo $R."\t";
}
echo "\n";
get unique_id_city_b for rows
$unique_id_city_b = array_unique(array_map(function ($i) { return $i['id_city_b']; }, $tableRows));
foreach($result as $R1)
{
echo $unique_id_city_b[$counter++]."\t";
foreach($R1 as $R2)
{
echo $R2["distance"]."\t";
}
echo "\n";
}
<?php
include ("config.php");
$results = $mysqli->query
("
SELECT orders_history.transaction_id,
orders_history.items,
orders_history.quantity,
orders_history.one_product_price,
orders_list.status,
orders_list.invoices,
orders_list.payment_method,
orders_list.order_method,
delivery_orders.address,
delivery_orders.service,
delivery_orders.cost,
delivery_orders.city
FROM orders_history
LEFT JOIN orders_list
ON orders_history.transaction_id = orders_list.transaction_id
LEFT JOIN infistall_order
ON orders_history.transaction_id = infistall_order.transaction_id
LEFT JOIN delivery_orders
ON orders_history.transaction_id = delivery_orders.transaction_id
WHERE orders_list.customer_name = 'Klaudia'"
);
$orders = array();
$html = '';
if ($results) {
while($obj = $results->fetch_object()) {
$orders[$obj->transaction_id][$obj->items] = array(
'invoices' => $obj->invoices,
'status' => $obj->status,
'payment_method' => $obj->payment_method,
'service' => $obj->service,
'cost' => $obj->cost,
'quantity' => $obj->quantity,
'one_product_price' => $obj->one_product_price,
'city' => $obj->city);
}
$html .= '<table width="70%"><tr>';
$html .= '<td>transaction_id</td>';
$html .= '<td>items</td>';
$html .= '<td>quantity</td>';
$html .= '<td>one_product_price</td>';
$html .= '<td>status</td>';
foreach ($orders AS $order_id => $order) {
$html .= '<tbody><tr><td rowspan="' . count($order) . '">' . $order_id . '</td>';
$row = 1;
foreach ($order AS $item => $data) {
if ($row > 1) { $html .= '</tr><tr>'; }
$html .= '<td>' . $item . '</td>';
$html .= '<td>' . $data['quantity'] . '</td>';
$html .= '<td>' . $data['one_product_price'] . '</td>';
$row++;
$html .= '<td rowspan="' . count($order) . '">' . $data['status'] . '</td>';
}
$html .= '</tr><tbody>';
}
$html .= '</table>';
}
echo $html;
?>
The code above will result like this:
-----------------------------------------------------------------------
id_cart products quantity invoices status
-----------------------------------------------------------------------
this 2 $20
-------------------------------------------------------
0001 that 1 $20 pending
-------------------------------------------------------
those 2 $20 pending pending
-----------------------------------------------------------------------
Total Invoices: $60
-----------------------------------------------------------------------
this 2 $20
-------------------------------------------------------
0002 that 1 $20 approved
-------------------------------------------------------
those 2 $20 approved approved
-----------------------------------------------------------------------
Total Invoices: $60
Have a look at the column of status, where the result is looping.
What I want is it shouldn't be looping and only get one result as how the column of id_cart looks like. This is the code for the column of status
$html .= '<td rowspan="' . count($order) . '">' . $data['status'] . '</td>';
I need to solve it!
[EDIT]
When I move the code like this:
foreach ($orders AS $order_id => $order) {
$html .= '<tbody><tr><td rowspan="' . count($order) . '">' . $order_id . '</td>';
$row = 1;
foreach ($order AS $item => $data) {
if ($row > 1) { $html .= '</tr><tr>'; }
$html .= '<td>' . $item . '</td>';
$html .= '<td>' . $data['quantity'] . '</td>';
$html .= '<td>' . $data['one_product_price'] . '</td>';
$row++;
}
$html .= '<td rowspan="' . count($order) . '">' . $data['status'] . '</td>';
$html .= '</tr><tbody>';
-----------------------------------------------------------------------
id_cart products quantity invoices status
-----------------------------------------------------------------------
this 2 $20
-------------------------------------------------------
0001 that 1 $20
-------------------------------------------------------
those 2 $20 pending
-----------------------------------------------------------------------
Total Invoices: $60
-----------------------------------------------------------------------
this 2 $20
-------------------------------------------------------
0002 that 1 $20
-------------------------------------------------------
those 2 $20 approved
-----------------------------------------------------------------------
Total Invoices: $60
The resultin the column of status in at the very bottom of the tbody. I want it as how the column of id_cart is.
You need 1 value of status per tbody, so put it outside your loop. Also, because you're reusing $order, I've put count($order) in a seperate variable. Also, close your </tbody> tag.
foreach ($orders AS $order_id => $order) {
$orderCount = count($order);
$html .= '<tbody><tr><td rowspan="' . $orderCount . '">' . $order_id . '</td>';
$row = 1;
foreach ($order AS $item => $data) {
if ($row > 1) { $html .= '</tr><tr>'; }
$html .= '<td>' . $item . '</td>';
$html .= '<td>' . $data['quantity'] . '</td>';
$html .= '<td>' . $data['one_product_price'] . '</td>';
if ($row == 1)
$html .= '<td rowspan="' . $orderCount . '">' . $data['status'] . '</td>';
$row++;
}
$html .= '</tr></tbody>';
}
Use valign attribute for td element to get the value aligned center vertically.
$html .= '<td rowspan="' . $orderCount . '" valign="middle">' . $data['status'] . '</td>';
Hope it will work for you.
Check this out:
foreach ($order AS $item => $data) {
if ($row > 1) { $html .= '</tr><tr>'; }
$html .= '<td>' . $item . '</td>';
$html .= '<td>' . $data['quantity'] . '</td>';
$html .= '<td>' . $data['one_product_price'] . '</td>';
if( $row == 1 )
{
$html .= '<td style="vertical-align: middle" rowspan="' . count($order) . '">'. $data['status'] . '</td>';
}
$row++;
}