Durandal and jqGrid - jqgrid

There is already an example of jqxGrid that is labeled "jqGrid integration with existing Durandal solution". However, I don't have the option of using jqxGrid.
Does any one have an example of using jqGrid with durandal. This is what I'm trying now and it is not working.
Unable to parse bindings.
Bindings value: attr: { href: 'animals/' + id, title: name }, text: id
Message: id is not defined;
viewmodel.js
///
define(['durandal/app', 'jqgrid', 'kojqgrid'], function (app) {
var initialData = [
{ id: 1, name: "Well-Travelled Kitten", sales: 352, price: 75.95 },
{ id: 2, name: "Speedy Coyote", sales: 89, price: 190.00 },
{ id: 3, name: "Furious Lizard", sales: 152, price: 25.00 },
{ id: 4, name: "Indifferent Monkey", sales: 1, price: 99.95 },
{ id: 5, name: "Brooding Dragon", sales: 0, price: 6350 },
{ id: 6, name: "Ingenious Tadpole", sales: 39450, price: 0.35 },
{ id: 7, name: "Optimistic Snail", sales: 420, price: 1.50 }
];
var ctor = function () {
this.animals = ko.observableArray([]);
this.disabled = ko.observable(false);
this.activate = function () {
this.animals(initialData);
return true;
}
};
//Note: This module exports a function. That means that you, the developer, can create multiple instances.
//This pattern is also recognized by Durandal so that it can create instances on demand.
return ctor;
});
View
-------------------------------------------------------------------
<h3>Customers</h3>
<table id="animals" data-bind="grid: { data: animals }" >
<caption>Amazing Animals</caption>
<thead>
<tr>
<th data-field="actions" style="width:27px;"></th>
<th data-field="name" width="150px">Item Name</th>
<th data-field="sales">Sales Count</th>
<th data-field="price">Price</th>
</tr>
</thead>
<tbody>
<tr>
<td data-field="actions">
<a class="grid-edit" data-bind="attr: { href: 'animals/' + id, title: name }, text: id"></a>
</td>
</tr>
</tbody>
</table>
Any help would be greatly appreciated.

The reason you are getting id is undefined is because the ctor function does not expose id or name attribute but the animals observableArray. In your view you need to loop over the animals obserbavbleArray to get access to id and name attribute for each animal. Try the following code:
<tbody data-bind='foreach:animals'>
<tr>
<td data-field="actions">
<a class="grid-edit" data-bind="attr: { href: 'animals/' + id, title: name }, text: id"></a>
</td>
</tr>
</tbody>

You need to put your activate handler on the prototype:
ctor.prototype.activate = function () {...}
Durandal likely cannot find your activate handler and, therefore, never initializes the data.
Also, I can only assume that the jqGrid binding is looking at the table definition and harvesting from the DOM what it needs to build a proper binding. The reason I say that is that, strictly speaking, #nimrig is right: there needs to be a foreach somewhere. It must be that the jqGrid is building that foreach.

Related

Initialization datatable via Ajax - No data displayed

I have a datatable that I would like to initialize with an Ajax call http://url/api/v1/shocks
table.blade.php
<div class="card-body p-0">
<div class="table-responsive">
<table class="table table-striped table-md" id="table-raw-shocks" width="100%" cellspacing="0">
<thead>
<tr>
<th>Record Id</th>
<th>Count</th>
<th>Date</th>
<th>Amplitude 1 (G)</th>
<th>Amplitude 2 (G)</th>
<th>Time 1 (s)</th>
<th>Time 2 (s)</th>
<th>Freq 1 (Hz)</th>
<th>Freq 2 (Hz)</th>
</tr>
</thead>
<tfoot>
<tr>
<th>Record Id</th>
<th>Count</th>
<th>Date</th>
<th>Amplitude 1 (G)</th>
<th>Amplitude 2 (G)</th>
<th>Time 1 (s)</th>
<th>Time 2 (s)</th>
<th>Freq 1 (Hz)</th>
<th>Freq 2 (Hz)</th>
</tr>
</tfoot>
</table>
</div>
</div>
Javascript part
$(document).ready(function () {
initShocksActivityTable();
});
function initShocksActivityTable() {
var url = '{{ route("api:v1:shocks.index") }}'; //http://url/api/v1/shocks
var table = $('#table-raw-shocks-all').DataTable({
responsive: true,
responsive: {
details: {
type: "column",
target: "tr"
}
},
orderCellsTop: true,
fixedHeader: true,
dom: "Bfrtip",
buttons: ["copy", "csv", "excel", "pdf", "print"],
columnDefs: [{
sortable: true
}],
"ajax": url,
"columns": [{
"data": "attributes.record_id"
},
{
"data": "attributes.count"
},
{
"data": "attributes.date_time"
},
{
"data": "attributes.amplitude_1"
},
{
"data": "attributes.amplitude_2"
},
{
"data": "attributes.time_1"
},
{
"data": "attributes.time_2"
},
{
"data": "attributes.freq_1"
},
{
"data": "attributes.freq_2"
},
],
lengthMenu: [
[10, 25, 50, -1],
[10, 25, 50, "All"]
],
iDisplayLength: 10,
order: [
[2, "desc"]
]
});
}
My data looks like this :
Attributes contains all the necessary data that I would like to add on my datatable.
When I do that, I have no data displayed. I suspect that it is because, my data is an array ( [0], 1...)
I tried to add this piece of code (https://datatables.net/reference/option/ajax.dataSrc)
"dataSrc": "data.attributes"
But it still does not work.
I'm sure, it's something that I missed but I have some difficulties to find what is the problem to fetch correctly the data.
Could you please help me on that ? Thank

Sort table Vue.js

I am trying to sort a table by columns. That when pressing the ID button all the column is ordered from highest to lowest or vice versa, and the same by pressing the other two. How can I do it?
<table id="mi-tabla">
<thead>
<tr class="encabezado-derecha" >
<th>ID</th>
<th>Nombre de sección</th>
<th>Potencial (€)</th>
</tr>
</thead>
<tbody>
<tr class="item" v-for="user in userInfo" #click="openDiv(), showInfo1(user.id_section)">
<td>{{user.id_section}}</td>
<td>{{user.desc_section}}</td>
<div class="acceder">
<td>{{user.sale_potential | currency}}</td>
<img src="../../iconos/icon/chevron/right#3x.svg" alt />
</div>
</tr>
</tbody>
</table>
{
"id_store": 4,
"id_section": 1,
"desc_section": "MATERIALES DE CONSTRUCCION yeh",
"id_rule": 1,
"sale_potential": "69413.5525190617"
},
{
"id_store": 4,
"id_section": 2,
"desc_section": "CARPINTERIA Y MADERA",
"id_rule": 1,
"sale_potential": "74704.3439572555"
},
{
"id_store": 4,
"id_section": 3,
"desc_section": "ELECTR-FONTAN-CALOR",
"id_rule": 1,
"sale_potential": "101255.89182774"
}
]
Here's what it might look like if you want to implement yourself, note that this is very basic functionality and as you start to add additional features, you might see more benefit from using a component that already does it all.
Anyhow, the way you can do it is by using a computed (sortedList) to store a sorted version of the array. Then use another data variable to store which column you want to store by (sortBy), and optionally, you can store a sort direction (sortOrder)
then add a sort method that passes the sort key and updates the sortBy value and/or the sortOrder. When either of these values (or even the source array) changes, the computed will re-sort the array using the sort function.
new Vue({
el: "#app",
data: {
sortBy: "id_section",
sortOrder: 1,
userInfo: [
{
"id_store": 4,
"id_section": 1,
"desc_section": "MATERIALES DE CONSTRUCCION yeh",
"id_rule": 1,
"sale_potential": "69413.5525190617"
},
{
"id_store": 4,
"id_section": 2,
"desc_section": "CARPINTERIA Y MADERA",
"id_rule": 1,
"sale_potential": "74704.3439572555"
},
{
"id_store": 4,
"id_section": 3,
"desc_section": "ELECTR-FONTAN-CALOR",
"id_rule": 1,
"sale_potential": "101255.89182774"
}
]
},
computed: {
sortedList() {
return [...this.userInfo]
.map(i => ({...i, sale_potential:parseFloat(i.sale_potential)}))
.sort((a,b) => {
if (a[this.sortBy] >= b[this.sortBy]) {
return this.sortOrder
}
return -this.sortOrder
})
}
},
methods: {
sort: function(sortBy){
if(this.sortBy === sortBy) {
this.sortOrder = -this.sortOrder;
} else {
this.sortBy = sortBy
}
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="app">
[{{sortBy}}] [{{sortOrder}}]
<table id="mi-tabla">
<thead>
<tr class="encabezado-derecha">
<th #click='sort("id_section")'>{{ sortBy === 'id_section' ? '*' : '' }}ID</th>
<th #click='sort("desc_section")'>{{ sortBy === 'desc_section' ? '*' : '' }}Nombre de sección</th>
<th #click='sort("sale_potential")'>{{ sortBy === 'sale_potential' ? '*' : '' }}Potencial (€)</th>
</tr>
</thead>
<tbody>
<tr class="item" v-for="user in sortedList">
<td>{{user.id_section}}</td>
<td>{{user.desc_section}}</td>
<div class="acceder">
<td>{{user.sale_potential | currency}}</td>
<img src="../../iconos/icon/chevron/right#3x.svg" alt />
</div>
</tr>
</tbody>
</table>
</div>
I would recommend you to use bootstrap Vue tables which come with filtering and sorting. All you have to do is pass your data to the table.
Here is a link you can check it out.
https://bootstrap-vue.js.org/docs/components/table#complete-example
< script >
export default {
data() {
return {
items: [{
"id_store": 4,
"id_section": 1,
"desc_section": "MATERIALES DE CONSTRUCCION yeh",
"id_rule": 1,
"sale_potential": "69413.5525190617"
},
{
"id_store": 4,
"id_section": 2,
"desc_section": "CARPINTERIA Y MADERA",
"id_rule": 1,
"sale_potential": "74704.3439572555"
},
{
"id_store": 4,
"id_section": 3,
"desc_section": "ELECTR-FONTAN-CALOR",
"id_rule": 1,
"sale_potential": "101255.89182774"
}
],
fields: [{
key: 'id_store',
label: 'id',
sortable: true
}, {
key: 'desc_section',
label: 'Nombre de sección'
}, {
key: 'sale_potential'
},{key:'actions'}]
}
},
} <
/script>
<b-table striped hover :items="items" :fields="fields">
<template v-slot:cell(sale_potential)="row">
<p>{{row.item.sale_potential |currency}}</p>
<img src="../../iconos/icon/chevron/right#3x.svg" alt />
</template>
<template v-slot:cell(actions)="row">
<button #click="openDiv(); showInfo1(row.item.id_section);"
class="btn" variant="primary">Action</button>
</template>
</b-table>
If you want to add this functionality yourself you can achieve it using a computed value to sort your data.
data () => ({
...
sortBy : null,
}),
computed : {
userInfoSorted () {
const sortBy = this.sortBy
if (!sortBy) return this.userInfo
return this.userInfo.sort((a,b)=> a[sortBy] > b[sortBy] ? 1 : -1)
}
}
Then update your sortBy value within the <th> tags in your template:
<th #click="sortBy='id_section'">ID</th>
and link your rows to the computed value:
<tr class="item" v-for="user in userInfoSorted">
EDIT: CHANGE SORT ORDER
To add an option to toggle the order, start by adding the headers to your data object:
data () => ({
...
headers : {
id_section : {
text : 'ID',
reverse : true
}
}
})
Then update your template to also change the reverse value on click:
<th v-for="(val,key) in headers" #click="sortBy=key; val.reverse=!val.reverse">
{{ val.text }}
</th>
Finally include the reverse value in your sort function:
userInfoSorted () {
const sortBy = this.sortBy
const r = this.headers[sortBy].reverse ? -1 : 1;
if (!sortBy) return this.userInfo
return this.userInfo.sort((a,b)=> a[sortBy] > b[sortBy] ? 1*r : -1*r)
}

Laravel Yajra DataTable - Fetch content via Ajax with supplied search parameters

After searching as to how to fill up a Yajra DataTable with data from an ajax call with user supplied search parameters, I came to this page for the official documentation.
It has a code snippet as follows...
$builder->ajax([
'url' => route('users.index'),
'type' => 'GET',
'data' => 'function(d) { d.key = "value"; }',
])
However, I cannot make anything out of it. Where does the $builder variable come from? How do I use the data received from the Ajax call to fill up the table? This page lists the callback functions with no details.
What I need
A full-blown example of how to fill up my data table with data received from an Ajax call initiated by the search button #btn_search after selecting a value from the drop-down #param.
For simplicity, lets assume that the table structure looks like...
<select id="param">
<option value="">Select </option>
<option value="1">One</option>
<option value="2">Two</option>
</select>
<button id="btn_search" value="Search">Search</button>
<table>
<thead>
<tr>
<th>Serial</th>
<th>Col1</th>
<th>Col2</th>
<th>Col3</th>
</tr>
</thead>
</table>
The controller method that returns the data...
<?php
public function getBasicData()
{
$users = User::select(['id','name','email','address']);
return Datatables::of($users)->make();
}
The user selects a value from the dropdown and clicks on the search button. In the actual scenario, several dropdowns are there to collect the search parameters. Relevant jQuery code is...
$("#btn_search").click(function() {
var param_value = $("#param").val().trim();
// make ajax call probably
});
How can I make the Ajax call inside the click handler and fill up the data table with the received data?
The $builder variable is the class id of the table that would view the information ,
Here is an example :
<table id="data" class="table table-bordered table-hover" >
<thead>
<tr class="table-head">
<th>#</th>
<th>namr</th>
<th>email</th>
<th>date</th>
<th>auth</th>
<th>control</th>
<th>control</th>
</tr>
</thead>
<tbody>
</tbody>
<tfoot>
<th> </th>
<th> </th>
<th> </th>
<th> </th>
<th></th>
<th></th>
<th></th>
</tfoot>
</table>
and this is ajax code
<script type="text/javascript">
var lastIdx = null;
var table = $('#data').DataTable({
processing: true,
serverSide: true,
ajax: '{{ url('/adminpanel/users/data') }}',
columns: [
{data: 'id', name: 'id'},
{data: 'name', name: 'name'},
{data: 'email', name: 'email'},
{data: 'created_at', name: 'created_at'},
{data: 'admin', name: 'isadmin'},
{data: 'edit', name: 'edit', orderable: false, searchable: false},
{data: 'action', name: 'action', orderable: false, searchable: false}
],
"language": {
"url": "{{ Request::root() }} /admin/cus/Arabic.json"
},
"stateSave": false,
"responsive": true,
"order": [[0, 'asc']],
"pagingType": "full_numbers",
aLengthMenu: [
[25, 50, 100, 200, -1],
[25, 50, 100, 200, "All"]
],
iDisplayLength: 25,
fixedHeader: true,
"oTableTools": {
"aButtons": [{
"sExtends": "csv",
"sButtonText": "ملف إكسل",
"sCharSet": "utf16le"
},
{
"sExtends": "copy",
"sButtonText": "نسخ المعلومات",
},
{
"sExtends": "print",
"sButtonText": "طباعة",
"mColumns": "visible",
}
],
"sSwfPath": "{{ Request::root() }} /website/admin/cus/copy_csv_xls_pdf.swf"
},
"dom": '<"pull-left text-left" T><"pullright" i><"clearfix"><"pull-right text-right col-lg-6" f > <"pull-left text-left" l><"clearfix">rt<"pull-right text-right col-lg-6" pi > <"pull-left text-left" l><"clearfix"> '
,initComplete: function ()
{
var r = $('#data tfoot tr');
r.find('th').each(function(){
$(this).css('padding', 8);
});
$('#data thead').append(r);
$('#search_0').css('text-align', 'center');
}
});
table.columns().eq(0).each(function(colIdx) {
$('input', table.column(colIdx).header()).on('keyup change', function() {
table
.column(colIdx)
.search(this.value)
.draw();
});
});
table.columns().eq(0).each(function(colIdx) {
$('select', table.column(colIdx).header()).on('change', function() {
table
.column(colIdx)
.search(this.value)
.draw();
});
$('select', table.column(colIdx).header()).on('click', function(e) {
e.stopPropagation();
});
});
$('#data tbody')
.on( 'mouseover', 'td', function () {
var colIdx = table.cell(this).index().column;
if ( colIdx !== lastIdx ) {
$( table.cells().nodes() ).removeClass( 'highlight' );
$( table.column( colIdx ).nodes() ).addClass( 'highlight' );
}
} )
.on( 'mouseleave', function () {
$( table.cells().nodes() ).removeClass( 'highlight' );
} );
</script>
this is a full table with ajax example ,like Yajara documentation help .

Relation is DS.PromiseMany instead model and data

What I need is:
1) Represent list of partners
App.Partner= DS.Model.extend(
{
name: attr(),
site: attr(),
contacts: DS.hasMany('partner-contact', { async: true, polymorphic: true })
}
);
2) and names of partners contacts
App.PartnerContact = DS.Model.extend(
{
name: attr(),
phone: attr(),
post: attr(),
email: attr(),
partnerId: attr(),
partner: DS.belongsTo('partner')
}
);
So I have route:
App.CallsMyContactsRoute = Ember.Route.extend({
//needs: "partner-contacts",
model: function () {
return this.store.find('partner');
}
});
And template:
{{#each partner in model}}
<tr class="gradeA even" role="row">
<td class="sorting_1">{{partner.name}}</td>
<td>{{partner.name}}</td>
<td>{{partner.phone}}</td>
<td class="center">
{{partner.contacts}}
{{#each contact in partner.contacts}}
{{contact.name}}
{{/each}}
</td>
<td class="center">A</td>
</tr>
{{/each}}
But {{partner.contacts}} is DS.PromiseManyArray
And it ever doesn't make a query to server.
Answer from server (Partners)
{
"Partner":[
{
"id":4,
"name":"CompanyNamej",
"site":"www.no-site.ru"
},
{
"id":13,
"name":"test",
"site":"sdasdasd"
},
{
"id":14,
"name":"",
"site":""
}
]
}
What is the problem?
DEBUG: Ember : 1.10.0
vendor.js:16928DEBUG: Ember Data : 1.0.0-beta.15
vendor.js:16928DEBUG: jQuery : 2.1.3

kendo observable array sorting

I have a observable array in a viewmodel.
I show the date of array with a template:
<table align="center">
<thead>
<tr>
<th>Name</th>
<th>Surname</th>
</tr>
</thead>
<tbody data-template="row-template" data-bind="source: client"></tbody>
</table>
But if i want to sort array? and show the 'client' order by name or surname?
If your data array is like this (as json, if not convert to json or databind using server)
[{name:'name1',surname:'surname1'},{name:'name2',surname:'surname2'},{name:'name3',surname:'surname3'}]
You can use this code for client side sorting.
$("table").kendoGrid({
dataSource: {
data:[{name:'name1',surname:'surname1'},{name:'name2',surname:'surname2'},{name:'name3',surname:'surname3'}],
sort: {
field: "name",
dir: "desc"
}
},
sortable: true,
columns: [
{
field: "name",
title: "Name"
},
{
field: "surname",
title: "Surname"
}
]});
If i understand you right, this will solve your problem.

Resources