Eloquent query to blade on view styled better? - laravel

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>

Related

Undefined variable: categories in user.blade.php

I was trying to extend my user.blade.php to my views menu.blade.php. Everything works fine with my other views that use the same user.blade.php too. But not with my menu.blade.php, I get an error saying "Undefined variable: categories (View: D:\xampp\htdocs\mieaceh\resources\views\layouts\user.blade.php)" with "Possible typo $categories
Did you mean $errors?"
Here are the codes to my user.blade.php
#foreach($categories as $category)
<a href="{{ route('menu.index', ['category' => $category->slug]) }}">
<div class="card-category" style="width: 10rem; height: 4rem;">
{{ $category->name }}
</div>
</a>
#endforeach
How do I solve it?
If you want to make a piece of view that appears in multiple places, you can use blade components https://laravel.com/docs/8.x/blade#components.
This will help encapsulating this partials behavior and required data.

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

Laravel - pagination sorting by created_at

So guys I add pagination to my project and I'm almost finishing it, witch by the way is my first project ever, and all I need to do right now is to set pagination by created_at.So I need to put posts from the same day on same page link. Right now it shows me posts from different days on one page. And after that I just need to show price sum of that day. If you know please help me, this would be my first project as a student, I'm still learning. Thank you !!
Here is my HomeController
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\User;
use App\Post;
use DB;
use Auth;
class HomeController extends Controller
{
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('auth');
}
/**
* Show the application dashboard.
*
* #return \Illuminate\Contracts\Support\Renderable
*/
public function index()
{
$posts = Post::where('user_id', Auth::id())->orderBy('created_at', 'DESC')
->paginate(3);
return view('home')->with('posts', $posts);
}
}
Here is my home.blade.php
#extends('layouts.theme')
#section('content')
<style>
body{
margin: 0;
background-color: #EBEBEB;
}
</style>
<div class="mainl">
<div class="row">
<div class="columna">
<h1>{{ Auth::user()->name }}</h1>
<hr>
</div>
<div class="columns">
<a href="{{ route('logout') }}" id="logout"
onclick="event.preventDefault();
document.getElementById('logout-form').submit();">
{{ __('LOGOUT') }}
</a>
<form id="logout-form" action="{{ route('logout') }}" method="POST" style="display: none;">
#csrf
</form>
</div>
</div>
</br></br></br>
#if(count($posts)> 0)
<table>
<thead>
<tr>
<th>BR.KESICE</th>
<th>IME I PREZIME</th>
<th>BR.TELEFONA</th>
<th>POSAO</th>
<th>CIJENA</th>
<th>PLACANJE</th>
<th>POPUST</th>
<th>DATUM PREUZ.</th>
<th>DATUM IZDAV.</th>
<th>SMJENA</th>
<th>RADNIK</th>
<th>STATUS</th>
<th>IZMIJENI</th>
</tr>
</thead>
<tbody>
#foreach($posts as $post)
<tr>
<td>{{$post->br_kesice}}</td>
<td>{{$post->ime}}</td>
<td>{{$post->br_telefona}}</td>
<td>{{$post->posao}}</td>
<td>{{$post->cijena}}</td>
<td>{{$post->placanje}}</td>
<td>{{$post->popust}}</td>
<td>{{$post->datum_preuz}}</td>
#if($post->status == 1)
<td>/</td>
#else
<td>{{$post->datum_izdav}}</td>
#endif
<td>{{$post->smjena}}</td>
<td>{{$post->radnik}}</td>
<td>
#if($post->status == 0)
<span class="label label-primary" id="statusdeaktivan">Deaktivan</span>
#elseif($post->status == 1)
<span class="label label-success" id="statusaktivan">Aktivan</span>
#elseif($post->status == 2)
<span class="label label-danger" id="statusdeaktivan">Rejected</span>
#else
<span class="label label-info" id="statusdeaktivan">Deaktivan</span>
#endif
</td>
#if($post->status == 3)
#else
<td><i class="far fa-edit"></i></td>
#endif
</tr>
#endforeach
</tbody>
<tfoot>
<tr>
<th>UKUPAN IZNOS: {{ Auth::user()->posts->sum('cijena')}}€</th>
<th>KARTICA: {{ Auth::user()->posts->where('placanje', 'Kartica')->sum('cijena')}}€</th>
<th>GOTOVINA: {{ Auth::user()->posts->where('placanje', 'Gotovina')->sum('cijena')}}€</th>
<th>VIRMAN: {{ Auth::user()->posts->where('placanje', 'Virman')->sum('cijena')}}€</th>
</tr>
</tfoot>
</table>
{{ $posts->links()}}
#else
<p>Trenutno nema unosa.</p>
#endif
</div>
#endsection
And I found something from past questions here in stack overflow and it's working but I have a problem with that, so
public function index()
{
$posts = Post::where('user_id', Auth::id())->where('created_at', '>=', \Carbon\Carbon::now()->subDays(10))->get();
return view('home')->with('posts', $posts);
}
When I add this ->where('created_at', '>=', \Carbon\Carbon::now()->subDays(10))->get(); it shows me all posts from past 10 days but after that 10 days nothing, could I use this but to sort it by all days, not to set maximum days?
I also add this code to my price sum and it is working but as I said just for past 10 days
<tfoot>
<tr>
<th>UKUPAN IZNOS: {{ Auth::user()->posts->where('created_at', '>=', \Carbon\Carbon::now()->subDays(10))->sum('cijena')}}€</th>
<th>KARTICA: {{ Auth::user()->posts->where('placanje', 'Kartica')->where('created_at', '>=', \Carbon\Carbon::now()->subDays(10))->sum('cijena')}}€</th>
<th>GOTOVINA: {{ Auth::user()->posts->where('placanje', 'Gotovina')->where('created_at', '>=', \Carbon\Carbon::now()->subDays(10))->sum('cijena')}}€</th>
<th>VIRMAN: {{ Auth::user()->posts->where('placanje', 'Virman')->where('created_at', '>=', \Carbon\Carbon::now()->subDays(10))->sum('cijena')}}€</th>
</tr>
</tfoot>
Thank you again and I would really appreciate it if you help me with this. It's my first project and I'm very happy about it.
What your current code is doing is taking all the posts, sort it by created_at and then show 3 at a time. It doesn't care about what day it is or how many $post are there for that particular day.
What I understand that, you want to do is to show it by date. In that case, your query should filter based on date.
What you need to do is pass the date to the controller and fetch only posts from that day. It is a bit tricky. You need to pass today's date to controller.
In HTTP GET method your URL should contain the date. For example, it can be something like http://example.com/index?date=20190716. Notice that "date=20190716" part. You can get this in controller. Then you can get the posts of that day by writing,
$date = new Carbon(request('date'));
$posts = Post::where('user_id', Auth::id())
->whereDate('created_at','=',$date)
->orderBy('created_at', 'DESC')
->paginate(3);
Now, what it will do is get only the posts from 16th July, 2019.
This is the main idea. How you pass the date is entirely on you. You can do that in several ways. You can use JS, HTTP GET method and HTTP POST method.
Try
public function index()
{
$posts = Post::where('user_id', Auth::id())->get();
return view('home')->with('posts', $posts);
}
Try this also, I hope helps you
public function index()
{
$dateFromUrl = \Carbon\Carbon::createFromFormat('d/m/Y', request()->date);
$posts = Post::where('user_id', Auth::id())->where('created_at',$dateFromUrl)->orderBy('created_at', 'DESC')
->get();
$sum = 0;
foreach($posts as $post){
$sum+=$post->price;
}
return view('home', compact("posts","sum"));
}

How to get all records for current year?

How to get all articles for current year?
Articles::all()->where('created_at',$current_year);
You can do this:
Articles::whereBetween('created_at', [
Carbon::now()->startOfYear(),
Carbon::now()->endOfYear(),
]);
Another way is to use whereYear() as in #xhulio answer. But I'd recommend you to use this code instead as it's more readable:
Articles::whereYear('created_at', date('Y'))->get();
Try the following query
Articles::whereYear('created_at', '=', Carbon::parse($date)->format('Y'))->get();
Laravel has the helper functions whereDate, whereDay, whereMonth and whereYear to better deal with datetime queries.
Get Data via carbon in single line
Articles::whereYear('created_at', Carbon::now()->year)->get();
i found this way to collect all years only is good
#if(isset($years) && $years != '')
#foreach($years as $yrs)
#php($year[] = $yrs->created_at)
#endforeach
#if(isset($year))
#php( $collection = collect($year)->unique()->values()->all())
#foreach($collection as $created)
#php($year_only[] = $created->format('Y'))
#endforeach
#php( $collections = collect($year_only)->unique()->values()->all())
#foreach($collections as $created_year)
#if($created != '')
<div class="lab-item">
<div class="lab-inner" style="border: #ee3725 2px solid;border-radius: 25px;background: bisque;">
<div class="lab-content">
<h4> {{ $created_year }} </h4>
</div>
</div>
</div>
#endif
#endforeach
#endif
#endif

Laravel Form - Sent as an email in a table

I have a form on my website, which has required fields, and non required fields. The user fills in there details and submits the form. This is then emailed to the owner, and the data is then presented in a table.
However is it possible to show only the data that has been filled in and then remove the fields where no data was entered.
So far I have:
Blade Template:
div class="col-md-6">
<div class="row">
<div class="col-md-6">
<p><b>First Names</b></p>
</div>
<div class="col-md-6">
<p>{{ $first_names }}</p>
</div>
</div>
Which is then sent and is outputted as a table below:
<?php
if (!empty($titles)) {?>
<td class="tg-031e">Title:</td>
<td class="tg-031e">{{ $titles }}</td>
<?php }
?>
But I am assuming an else or else if statement would be required. So how would I have it so that only the fields that where filled in where shown in the table please.
Thanks
If you want to return nothing when there is no title the code below shoud make it work.
#if (isset($titles))
<td class="tg-031e">Title:</td>
<td class="tg-031e">{{ $titles }}</td>
#endif
Let me know if this worls :)
ps: #if(isset($titles)) does not work try #if($titles == NULL)
You can also try something like this:
http://laravel.com/docs/4.2/templates#other-blade-control-structures
Sometimes you may wish to echo a variable, but you aren't sure if the variable has been set. Basically, you want to do this:
{{{ isset($name) ? $name : 'Default' }}}
However, instead of writing a ternary statement, Blade allows you to use the following convenient short-cut:
{{{ $name or 'Default' }}}

Resources