I will try to be as clear as possible. I have a table with ng-repeat in blade file.
I want to send parameters to a Laravel function, inside the repeat loop.
Here is the example:
The angular
app = angular.module("myApp",[], function($interpolateProvider) {
$interpolateProvider.startSymbol('<%');
$interpolateProvider.endSymbol('%>');
});
The blade file : $idVal needs to be the id from the loop.
<tr ng-repeat="rec in recomends" ng-init="recomends = {{ $recomends }}">
<td ><% $index + 1 %></td>
<td><% rec.name %></td>
<td>{{ HelperAdmin::getTotalParam('quality',$idVal) }}</td>
</tr>
The laravel Function:
public static function getTotalParam($field,$reco_id){
$total = DB::select("SELECT AVG($field) AS mysum FROM recommendation_measure WHERE reco_id = $reco_id ");
return number_format($total[0] ->mysum,2);
}
I need to push $idVal as the id of the loop data. But I can't find a way to send it. Any idea?
Hope this question is clear.
Related
In a django project, templates are used on the backend which render html that is displayed on the page. But when dealing with Channels (websockets) which receive 'notifications' from the server, I find that I have to re-write code in javascript to render the same html elements.
As an example, I started out with a HTML table element that in a django template page:
{% for t in tickets %}
<tr class="ticket-row">
<td>{{ t.id }}</td>
<td>
<a href="/tickets/{{ t.id }}">
{{ t.subject }}
</a>
</td>
<td>
<a href="/users/{{ t.user.id }}">
{{ t.user.name}}
</a>
</td>
<td class="tooltipped" data-tooltip="{{ t.date_time_updated }}">
{{ t.date_time_updated|naturaltime }}
</td>
<td class="tooltipped" data-tooltip="{{ t.date_time_created }}">
{{ t.date_time_created|naturaltime }}
</td>
....
When channels receives a notification in javascript, I want to insert another row to the table without refresh, so I write JS code to do so like this:
function insertTicketRow(ticket) {
document.getElementById("results").innerHTML = "Server: " + data.subject;
var table = document.getElementById('ticket_table');
var row = table.insertRow(1);
// Insert new cells (<td> elements) at the 1st and 2nd position of the "new" <tr> element:
var cellId = row.insertCell(0);
var cellSubject = row.insertCell(1);
var cellFrom = row.insertCell(2);
cellId.innerHTML = data.id;
cellSubject.innerHTML = linkElement("/tickets/" + data.id, data.subject);
cellFrom.innerHTML = linkElement("/users/" + data.user, data.author_name);
cellLastUpdated.innerHTML = data.date_time_updated;
cellCreatedOn.innerHTML = data.date_time_created;
....
}
Obviously this is not maintainable and I suspect the worst approach possible. What if I have 30 columns and not just a few? What about the attributes? Adding all this via javascript is doing the same work twice, AND, I have to put in extra logic to make the rendered HTML in javascript look the same like django's.
The question is, is there some method I can use to not write the same thing twice, but still be able to work with websockets and add elements to the page dynamically?
Currently I have a table called tblOrders
with the query like this
public function getIndex()
{
$cart = Cart::orderby('cart_date','DESC')
->orderby('cart_no','DESC')
->select('id','cart_no','client_id','cart_title')->limit(1000)->get();
return View::make('_admin.orders.orders', compact('cart'));
}
on my blade file I have this datatable.js
<table id="table-order" class="parennt-table uk-table-hover">
<thead>
<tr>
<th>id</th>
<th>cart_no</th>
<th>cart_title</th>
<th>cart_date</th>
</tr>
</thead>
<tbody>
#if(count($orderData))
#foreach ($orderData as $field)
<tr>
<td>{{ $field->id }}</td>
<td>{{ $field->cart_no }}</td>
<td>{{ $field->cart_title }}</td>
<td>{{ date('M j, Y',strtotime($field->cart_date)) }}</td>
</tr>
#endforeach
#endif
</tbody>
and my js like this
<script>
oTable = $('#table-order').DataTable({
"order": [[ 0, 'desc' ]]
});
</script>
This datatable loads 8k rows. but needed to limit it by 1000 rows
How can I load only 20 rows per page? and query the next 1 when user tries to click specific pagination
You should use pagination, the first parameter passed to the paginate() function is the number of results returned.
public function getIndex()
{
$cart = Cart::orderby('cart_date','DESC')
->orderby('cart_no','DESC')
->select('id','cart_no','client_id','cart_title')
->paginate(50);
return View::make('_admin.orders.orders', compact('cart'));
}
However, I don't suggest you to use such a high number as 1000 but use more reasonable numbers to reduce the page loading and rendering time.
Anyway, using DataTables I suggest you to install this package yajra/laravel-datatables
Code prints out tasks information. I want to pass tasks array to JS. How could I do that? Some of my twig code:
<div>
{% for task in tasks %}
<tr>
<td id>{{ task.Id }}</td>
<td>{{ task.Status }}</td>
<td>{{ task.Name }}</td>
<td>{{ task.Description }}</td>
<td>{{ task.Category }}</td>
<td>{{ task.Author }}</td>
<td>{{ task.CreationDate|date("m/d/Y") }}</td>
<td><a id="myLink" href="/edit/{{ task.ID }}" > Edit </a></td>
<td><a id="myLink" href="/delete/{{ task.ID }}" >Delete</a></td>
<?php echo 2+2; ?> </tr>
{% endfor %}
</table>
</div>
I want to pass array to this js class:
$(function(){
$('#calendar').fullCalendar({
});
});
You can serialize the array in json format: {{ tasks | json_encode() }}.
If your javascript is inside a <script> element of the twig template, you can just do: var data = {{ tasks | json_encode() }}.
Otherwise, you can put the serialized array somewhere in the twig template as an element's attribute:
<div id="data-element" data-tasks="{{ tasks | json_encode() }}">.
Then just get the data with
var jsonString = $('#data-element').data('tasks');
var data = JSON.parse(jsonString);
First of all , you need to know that there are a big deference between PHP arrays and Javascript arrays.
you need to convert your array to a common understood format that both PHP and Javascript can understand , which is JSON .
so I will assume that you are sending your tasks from your controller to twig as a json format, then you can set your javascript variable as follows :
<script>
var tasks = '{{ tasks }}';
var tasksObj = JSON.parse(tasks); // to convert json into a javascript object
</script>
I want to get the values of the two object in thesame ng-repeat
$http.get('/api/PreviewPayroll').success(function (data){
//alert(data[0].empID);
$scope.allowance = data;
});
$http.get('/api/Deduction').success(function (data){
//alert(data[0].empID);
$scope.Deduction = data;
});
<tr ng-repeat="item in allowance && ng-repeat="value in Deduction">
<td>{{ item.empID }}</td>
<td>{{ value.empID }}</td>
</tr>
how can I get the two scope object on thesame ng-repeat
So you will want to combine the data.
You can use $q.all(promises):
var promise1 = $http.get('/api/PreviewPayroll');
var promise2 = $http.get('/api/Deduction');
$q.all([promise1, promise2]).then(function (results) {
var allowances = results[0];
var deductions = results[1];
var combinedList = /* some combination logic */;
});
By using $q.all() you are ensuring you have both lists of data before trying to combine anything. You can easily play around with this to get the desired effect. For example, if you don't care if the other list isn't available.
Then you can use the ng-repeat in order to iterate over that new combined list:
<tr ng-repeat="item in combinedList">
<td>{{ item.allowance.empID }}</td>
<td>{{ item.deduction.empID }}</td>
</tr>
The sub properties allowance and deduction are based on your combined list.
However
It is in my honest opinion that, the server side gives you the data in the format you need to display it in. (i.e. the business logic remains server side in a controlled environment). I believe the view should only deal with view logic, like button actions etc..
But this is my opinion, and is what I find easiest.
Another note
I prefer to also keep the view logic in the JavaScript, hence why I combine the data there. Rather than trying to do some overly complicated angular expression in the HTML.
You could either have a nested ng-repeat and also combine the two objects into one.
<table>
<tbody ng-repeat="row in mainCombinedObject">
<tr>
<th>{{row.empID}}</th>
</tr>
<tr ng-repeat="sub in row.subObject">
<td>{{sub.empID}}</td>
</tr>
</tbody>
</table>
Combine $scope.allowance and $scope.Deduction to one list of objects "combined" then do your ng-repeat:
<tr ng-repeat="c in combined">
<td>{{ c.someField }}</td>
<td>{{ c.someOtherField }}</td>
</tr>
You can't do that in such way! If your allowance and Deduction have the same size you have to mix them in the collection like this:
var array = [
{ allowance: value1, Deduction: value2},
{ allowance: value3, Deduction: value4},
...
];
and them use it in the view:
<tr ng-repeat="item in array">
<td>{{ item.allowance.empID }}</td>
<td>{{ item.Deduction.empID }}</td>
</tr>
I am using Django 1.7 and nginx.
My sample view file is,
def testing(request):
return render_to_response('pages/testing.html', )
def testing1(request):
return render_to_response('pages/comingsoon.html',)
def testing2(request):
x= User.objects.all()
return render_to_response('pages/index1.html',{'users': x,})
def testing3(request):
context = User.objects.all()
return render_to_response('pages/testing.html',)
pages/testing.html - contains only text.(pure text)
pages/testing1.html - contains css and js
pages/testing2.html -
<body>
<h1>Users</h1>
{% for e in users %}
<table>
<tr>
<td class="active">{{ e.username }}</td>
<td>{{ e.email }}</td>
</tr>
</table>
{% endfor %}
</body>
pages/testing3.html - contains same as testing1.html
But while running this .
testing, testing1 take less than 3seconds in server.
But testing3 takes 40seconds and testing2 takes more that 1 Min.
How could I reduce that?
Thanks In Advance.
You may use values_list or values
and specify the values you need in templates inside values_list or values, instead of User.objects.all(). This is going to make a huge diffrence.