list multiple in one row in one column - php

I am sorry but I don't even know how to title this question since I have no clue what to look for.
Here is my problem: I have the following list:
name
word
hit
Bill
performance
2
Anna
performance
5
John
performance
3
Bill
java
0
Anna
java
1
John
java
3
Bill
test
4
Anna
test
5
John
test
1
What I am trying to get is the following:
name
sum(hit)
words_count
Bill
6
performance = 2 java = 0, test = 4
Anna
11
performance = 5 java = 1, test = 5
John
7
performance = 3 java = 3, test = 1
I could sum all hits and group by words and so but I only need one dataset each name.
I think I need a subquery or so. How can I get the words_count column in that way?
Actually I need it a Laravel controller to display it in a datatable but an SQl statement would help me a lot also.
Appreciate your help.

Hi guys i thank you a lot for your answers.
I could manage it in SQL. So the statement is the following:
SELECT name, sum(hit) as points,
GROUP_CONCAT(concat(word, '->'), concat(hit, ' ') separator ' ' ) as words
FROM results
GROUP BY name;
This gives me exactly what i need.
I am display my data in a datatable (yajra). I will now "translate" this code to "laravel / php" code to feed my datatable.

Let's consider, you have a model named UserPerformance
$userPerformance = UserPerformance::all();
$result = $userPerformance->groupBy('name');
And in your blade template:
<table>
<thead>
<tr>
<th>name</th>
<th>sum(hit)</th>
<th>words_count</th>
</tr>
</thead>
<tbody>
#foreach($userPerformance as $name => $performance)
<tr>
<td>{{ $name }}</td>
<td>{{ $performance->sum('hit') }}</td>
<td>
{{ $performance->map(function($p) { return $p->word.' = '.$p->hit; })->implode(', ') }}
</td>
</tr>
#endforeach
</tbody>
</table>
You can also add your map() code to your model using an accessor to keep the blade template clean:
class UserPerformance extends Model
{
public function getWordCountAttribute()
{
return $performance->map(function($p) {
return $p->word.' = '.$p->hit;
})->implode(', ');
}
}
You can access it like this: $userPerformanceModel->word_count;
That also enables you, to re-use the code. You can also append this accessor during serialization to use it client-side.

Related

how to find the rows of my table in which the value of remaining field is more than zero in laravel

i have a layout that shows all the orders placed in which i have record of paid and remaining amount also , so i am trying to display the background color of rows as red if remaining field data is more than 0 for this i am trying this method
public function noBalance() {
return Order::where('remaining', '>', 0)->first();
}
i am creating this in model file of Order
also tried this
return Order::where('remaining', '>', 0);
and
#foreach ($orders as $order)
<tr style="{{ $order->noBalance() ? 'background-color: lightcoral;' : '' }}">
(here i am using that function in my allorder.blade.php)
<td>{{$order->id}}</td>
<td>{{$order->client}}</td>
<td>{{$order->salesmanRelation->employee_name}}</td>
<td>{{$order->orderBooker->employee_name}}</td>
<td>{{$order->total_amount}}</td>
<td>{{$order->paid}}</td>
<td>{{$order->remaining}}</td>
<td>{{$order->discount}}</td>
<td>{{$order->created_at->toFormattedDateString()}}</td>
<td>Detail</td>
<td>Edit</td>
</tr>
#endforeach
but after using this all the rows of my table gets light coral not only the rows with the remaining >0
please help!
If there is a field 'remaining' in your database you can access it with:
$order->remaining;
So your if statement should look like this:
{{ $order->remaining > 0 ? 'background-color: lightcoral;' : '' }}
And the function noBalance() can be removed.
yes that is the right answer

Octobercms - Order frontend list by page variable (variable not on database)

So i'm trying to create a leaderboard with frontend user data on octobercms,
the leaderboard will be based on the sum of variables that are currently in the database. I've only recently started to look into twig and october, so please look at this patiently
The general Variable:
{% set totalScore = totalPoints + user.xp + user.progress %}
The List (simplified)
{% for user in activatedUsers %}
<div class="card">
<p class="name"><span class="rank-title">NAME</span><br>{{ user.name }}</p>
<p><span class="rank-title">LEVEL</span><br>{{ user.level }}</p>
<p><span class="rank-title">TOTAL POINTS</span><br>{{ totalPoints }} </p>
<p><span class="rank-title">PROGRESS</span><br>{{ user.progress }}</p>
<p><span class="rank-title">XP</span><br>{{ user.xp }}</p>
</div>
{% endfor %}
I can't really use the query to sort, since some variables are not in the database, but instead are being defined in the page.
I've looked into the sort twig function but i can't get it to work correctly.
I've tried this solution, but i get an exception.
I've added the following code in order for the "usort" function to work to the modules/twig/extension file but it did not work, and there has to be a simpler solution...
new \Twig_SimpleFilter('usort', array($this, 'usortFilter'))
public function usortFilter($item){
usort($item, function ($item1, $item2) {
if ($item1['orderNo'] == $item2['orderNo']) return 0;
return $item1['orderNo'] < $item2['orderNo'] ? -1 : 1;
});
return $item;
}
I've also tried the logical thing to do after reading the twig documentation:
{% for user in activatedUsers|sort('totalPoints') %}
But no luck there.
I can be walking in the wrong paths, so please feel free to suggest another or point out something i've missed.
Thanks in advance
Hmm i am not sure where you are setting your activatedUsers but before set that you can simply define this loop to sort them
you should use this only if your dataset is limited in numbers like 10 or 30 entry in list, no more then that its not efficient to sort db records in code
$activatedUsers = <<some code to fetch users>>
$sortedPointsWithUserId = [];
$sortedActivatedUsers = [];
foreach($activatedUsers as $user) {
// if $totalPoints is page variable you can use it directly $this->page['totalPoints'] from components and from page lifecycle $this['totalPoints']
$sortedPointsWithUserId[$user->id] = $totalPoints + $user->xp + $user->progress;
}
// sort array in descending order as we are storing totalpoints as value and key as user ID
// arsort maintain key value association
arsort($sortedPointsWithUserId);
foreach($sortedPointsWithUserId as $key => $value) {
$user = $activatedUsers[$key];
// create variable in model to hold totalPoints so we dont need to calculate again
$user->totalPoints = $value;
$sortedActivatedUsers[] = $user;
}
// $sortedActivatedUsers <-- this is your sorted array and you can use it
if you have any query please comment

Laravel 5.3 Blade foreach loop : show data in loop from two different database eloquent queries

I have two tables.
contenttype
content
contenttype returns me list of content types and I show them on page with foreach. e.g. Ambulance service, Blood Bank , clinic etc. as shown in snapshot.
At the same time I am fetching total number of contents of each type from another table(contents).
I was successful to get total number of contents of each type and show on the blade with foreach.
But situation is I want to show the number of contents on every content type.
Like this
Ambulance sevice 8,
Blood Bank 7,
Clinic 4.
My controller method is:
public function index()
{
if (Gate::allows('edit-content', auth()->user())) {
// below line returns list of content type e.g Ambulance service
$type = DB::table('contenttype')->distinct('label')->orderBy('label', 'asc')->paginate(10);
//below line counts the number of each content type e.g. Ambulance service 10.
$count = Content::selectRaw('type, count(*)total')->groupBy('type')->get();
return view('admin.content_listing', compact('type', 'count'));
} else {
abort(403, "Unauthorized");
}
}
This is blade code:
#foreach ($count as $c)
<span class="label label-danger">{{ $c->total }} </span>
#endforeach
This red number list is output:
#foreach ($type as $t)
<div class="list-group-item">
<a href="{{ route('content.type.listing', $t->type ) }}" > {{ $t->label }}
<span class=" pull-right glyphicon glyphicon-search"></span></a>
<span class="col-md-1 glyphicon glyphicon-plus-sign"></span>
</div>
#endforeach
Output is:
If I place above loop in second loop then Of course it will become nested loop that I don't want.
I need to show Ambulance 8,
Beauty clinic 8,
Blood Bank 1,
etc.
If anybody knows the solution kindly share it!
I have tried different ways but no success.
Rather than creating two queries and attempting to combine their results in the view, have you tried performing a join in a single query? Making certain assumptions about your column names and leaving aside the pagination, the actual SQL would be something akin to:
SELECT contenttype.*, count(content.id) FROM contenttype LEFT JOIN content ON contenttype.id = content.type GROUP BY contenttype.label ORDER BY contenttype.label ASC;
The code necessary to implement this query with Laravel's query builder functionality is pretty well documented in the documentation.

Laravel time table

I am making a time table in Laravel where user can select one field at say 10:00, and reserve equipment until say 12:00.
I have trouble displaying the range from when to when the equipment is reserved
#while($scheduler_start_time < $scheduler_end_time)
<tr>
<td>{{$scheduler_start_time->format('H:i:s')}}</td>
#foreach($equipment as $instrument)
<td>
<a href="#">
#if($instrument->reservations->where('reserved_from','=', $scheduler_start_time)
->where('reserved_to','<=', $scheduler_end_time)->first() != null)
HERE
#else
#endif
</a>
</td>
#endforeach
<?php $scheduler_start_time->addMinutes(30) ?>
</tr>
#endwhile
One instrument can have many reservations:
And this is what I get when getting reservation where reserved_from equals time. If I use >= I am fetching both records. I need a way to see that for example: Instrument3 is reserved from 6:30 up to 7:30, and then from 9:30 to 10:00
Unless I misunderstood your problem, I think you just need to add an upper limit on the 'reserved_from'. Would this work?
#if($instrument->reservations->where('reserved_from','>=', $scheduler_start_time)->where('reserved_from', '<', $scheduler_end_time)->where('reserved_to','<=', $scheduler_end_time)->first() != null)
UPDATE: Solved by OP
#if($instrument->reservations ->where('reserved_from','<=', $scheduler_start_time) ->where('reserved_to','>=', $scheduler_start_time)->first() != null

Populate table in Laravel with ajax?

I have a Laravel application where I create a page layout, adding a table to it as a "content" variable (pretty much all from tutorials I found). Here's the controller action:
public function getMain() {
$js_config = Category::all();
$resources = Resource::all()->take(100);
$this->layout->content = View::make('categories.show')->with('js_config', $js_config)->with('resources', $resources);
}
This uses the main layout template and inserts this table using the content variable:
<table class="table table-striped table-bordered">
<thead>
<tr>
<td>ID</td>
<td>Name</td>
</tr>
</thead>
<tbody>
#foreach($resources as $key => $value)
<tr>
<td>{{ $value->id }}</td>
<td>{{ $value->title }}</td>
</tr>
#endforeach
</tbody>
</table>
But then comes the problem: I have a jstree where the user can select nodes, triggering a jQuery method:
$('#jstree2').on("changed.jstree", function (e, data) {
console.log(data.selected);
$.get("filter", { category: data.selected })
.done(function (resultdata) {
//Test only, this returns the data wanted in json, which I stringify just to display in test
alert("Data Loaded: " + JSON.stringify(resultdata));
});
});
The jQuery calls this action method in the controller:
public function getFilter()
{
$input = Input::get('category.0');
$categories = Category::find($input);
//category is the name from the model below
return Response::json(array(
'error' => false,
'category' => $categories->toArray()),
200
);
}
(The reason there's an array as input is I eventually want to be able to allow picking multiple nodes in the tree)
This action gets the data from the DB correctly and returns it as json. The callback in the jQuery above then alerts this at the moment, just as a test.
But what I really want to do, of course, is to repopulate the table. Now, as you can see I have used Bootstrap to create a pretty table and all, and I just want to be able to let the user repopulate it at will, without refreshing the page.
But I don't know how to do that, except by painstakingly recreate this table in some sort of string return value, but that doesn't seem like a good idea.
I'm hoping there's some way of passing the return value back to the view and have it reload the values in the table, utilizing the same "sub view" that I loaded in the php variable "content" as described above?
Any help greatly appreciated!
EDIT:
As requested, here's a sample of the json (taken from the browser console output, and it's actually not the categories table, but the same format):
[{"id":"1","title":"Transportation AC 4494","created_by":"4","modified_by":null},{"id":"2","title":"Safety First AC 4294","created_by":"3","modified_by":null},{"id":"3","title":"Warranty AC 34066","created_by":"4","modified_by":null}]
EDIT 2 (Just realized there was some crap from the controller in the previous edit of the json, so I changed it to a cleaner sample now)
EDIT 3:
I have made this work by creating the table rows in jQuery:
var trHTML = '';
$.each(resultdata, function (i, item) {
trHTML += '<tr><td>' + item.id + '</td><td>' + item.title + '</tr>';
});
$('#ajaxtable').html(trHTML);
But mainly I'm hoping this might explain my question better: this is not what I wanted to do. What I would have wanted was to just create a partial view and then load that ready-made view with the jquery:
A partial view like this:
<table class="table table-striped table-bordered" id="resultstable">
<thead>
<tr>
<td>ID</td>
<td>Name</td>
</tr>
</thead>
<tbody id="ajaxtable">
#foreach($resources as $key => $value)
<tr>
<td>{{ $value->id }}</td>
<td>{{ $value->title }}</td>
</tr>
#endforeach
</tbody>
</table>
I tested this by creating and calling a new function in the controller from the jquery code:
public function getTable()
{
$resources = Resource::all()->take(5);
return View::make('categories.results')->with('resources', $resources);
}
But it doesn't work. Although it does indeed give me the html of that view, it is unprocessed. I.e, the foreach loop is not resolved, but still there as code in the table. See the image:
So how can I load this view with the jquery code? It feels to me that even if the jquery creation of table rows works, doing the view in php and then just loading it with jquery should be the more correct way of doing it...?
Have you looked into the Datatables jQuery plugin? There is actually a nice package for Laravel that helps integrate Laravel and Datatables. The Laravel package generates the json and you can use Datables+AJAX to repopulate the data. Might be working checking out...
https://github.com/Chumper/datatable
http://datatables.net/
Otherwise, you'll just need to use AJAX to repopulate the table.
As Sirago answered, using jQuery Datatables is a good option to load data into tables in ajax manner.
In addition to what Sirago suggested, here is another great Laravel 4 package which is dedicated to generate JSON data from server side.
https://github.com/bllim/laravel4-datatables-package
But apart from server side configuration(modifying files like composer.json, config/app.php etc.), you need to code in Javascript, utilizing Datatables as well.

Categories