jqwidgets and angular integration issues - angularjs-directive

I'm having a terrible time trying to get a simple jQWidget treegrid working with Angular.
The example using an Angular SPA I'm referring to is here: https://www.jqwidgets.com/jquery-widgets-documentation/documentation/angularjs/angularjs-directives/angularjs-jquery-treegrid.htm
And the initial tutorial page is here: https://www.jqwidgets.com/jquery-widgets-documentation/documentation/angularjs/angularjs-directives.htm
The front end error I'm getting is:
`ReferenceError: dataAdapter is not defined
at eval (eval at link (localhost:49479/app/services/directives.js:234:59), <anonymous>:1:27)
at link (localhost:49479/app/services/directives.js:234:28)`
[app] [HT Error] dataAdapter is not defined
Object {exception: ReferenceError, cause: "<span id="jqxTreeGrid" ng-jqwidgets="jqxTreeGrid" …pageable, columns: columns, disabled: disabled}">"}
cause: "<span id="jqxTreeGrid" ng-jqwidgets="jqxTreeGrid" ng-jqxsettings="{theme: 'metro', source: dataAdapter, width: 850, sortable: sortable, pageable: pageable, columns: columns, disabled: disabled}">"
exception: ReferenceError
and dataAdapter is binded in ng-jqxsettings="{theme: 'metro', source: dataAdapter ...}".
I also noticed as I debug in chorme f12, that my $scope.dataAdapater is empty of the data I have in the source var. In other words, 'source' contains valid data but never gets assigned to dataApapter :
$scope.dataAdapter = new $.jqx.dataAdapter(source);
My dashboard.html contains the <span id="jqxTreeGrid" ...> , which is giving me trouble :
<section id="dashboard-view" class="mainbar" data-ng-controller="dashboard as vm">
<section class="matter">
<div class="container-fluid">
<div class="row-fluid">
<div class="col-md-12"> <!-- HIERARCHY GRID -->
<div class="widget wlightblue">
<div data-cc-widget-header title="{{'Hierarchy'}}" subtitle="" allow-collapse="true"></div>
<div class="widget-content text-left text-info" style="float:left; border:none;">
<span>THIS IS A TEST</span>
<span id="jqxTreeGrid" ng-jqwidgets="jqxTreeGrid"
ng-jqxsettings="{theme: 'metro', source: dataAdapter, width: 850, sortable: sortable, pageable: pageable, columns: columns, disabled: disabled}">
</span>
<div class="widget-foot">
<div class="clearfix"></div>
</div>
</div>
</div>
</div>
</div>
and my controller is :
(function () {
'use strict';
var controllerId = 'dashboard';
angular.module('app').controller(controllerId, ['common', 'datacontext', '$scope', dashboard ]);
function dashboard(common, datacontext, $scope) {
var getLogFn = common.logger.getLogFn;
var log = getLogFn(controllerId);
var vm = this;
vm.news = {
title: 'Test Online',
description: 'queries to dynamically aggregate data. .'
};
activate();
function activate($scope) {
var promises = [getMessageCount(), getCountries(), getMemberMtm(), initJqTreeGrid()];
common.activateController(promises, controllerId)
.then(function () { log('Activated Dashboard View'); });
}
///jQWidgets treegrid settings
function initJqTreeGrid() {
var source =
{
dataType: "array",
dataFields: [
{ name: "name", type: "string" },
{ name: "quantity", type: "number" },
{ name: "id", type: "string" },
{ name: "parentid", type: "number" },
{ name: "price", type: "number" },
{ name: "date", type: "date" },
{ name: "customer", type: "string" }
],
hierarchy:
{
keyDataField: { name: 'id' },
parentDataField: { name: 'parentid' }
},
id: 'id',
localData: generateordersdata()
};
$scope.dataAdapter = new $.jqx.dataAdapter(source);
$scope.theme = "metro";
$scope.sortable = true;
$scope.pageable = true;
$scope.disabled = false;
$scope.columns = [
{ text: 'Order Name', dataField: "name", align: 'center', width: 200 },
{ text: 'Customer', dataField: "customer", align: 'center', width: 200 },
{ text: 'Price', dataField: "price", cellsFormat: "c2", align: 'center', cellsAlign: 'right', width: 80 },
{
text: 'Order Date', dataField: "date", align: 'center', cellsFormat: "dd-MMMM-yyyy hh:mm", cellsRenderer: function (rowKey, column, cellValue, rowData, cellText) {
if (rowData.level === 0) {
return $scope.dataAdapter.formatDate(cellValue, "dd-MMMM-yyyy");
}
return cellText;
}
}
];
}
Your advice will be greatly appreciate by me.
regards,
Bob

I used a different example from their tutorial and was able to get it running. Slight difference, I am having my settings within controller definition, rather then inline. I had better luck with that. Loading order makes all the difference as well. Here is my code for the grid example.
JavaScript:
<script type="text/javascript">
var demoApp = angular.module("demoApp", ["jqwidgets"]);
demoApp.controller("demoController", function ($scope) {
// Grid data.
var data = new Array();
var firstNames = ["Nancy", "Andrew", "Janet", "Margaret", "Steven", "Michael", "Robert", "Laura", "Anne"];
var lastNames = ["Davolio", "Fuller", "Leverling", "Peacock", "Buchanan", "Suyama", "King", "Callahan", "Dodsworth"];
var titles = ["Sales Representative", "Vice President, Sales", "Sales Representative", "Sales Representative", "Sales Manager", "Sales Representative", "Sales Representative", "Inside Sales Coordinator", "Sales Representative"];
var city = ["Seattle", "Tacoma", "Kirkland", "Redmond", "London", "London", "London", "Seattle", "London"];
var country = ["USA", "USA", "USA", "USA", "UK", "UK", "UK", "USA", "UK"];
for (var i = 0; i < firstNames.length; i++) {
var row = {};
row["firstname"] = firstNames[i];
row["lastname"] = lastNames[i];
row["title"] = titles[i];
row["city"] = city[i];
row["country"] = country[i];
data[i] = row;
}
$scope.people = data;
$scope.bindingCompleted = "";
$scope.settings =
{
altrows: true,
width: 800,
height: 200,
editable: true,
ready: function()
{
$scope.settings.apply('selectrow', 1);
},
sortable: true,
source: $scope.people,
selectionmode: 'multiplecellsadvanced',
columns: [
{ text: 'First Name', datafield: 'firstname', width: 150 },
{ text: 'Last Name', datafield: 'lastname', width: 150 },
{ text: 'Title', datafield: 'title', width: 150 },
{ text: 'City', datafield: 'city', width: 150 },
{ text: 'Country', datafield: 'country' }
],
bindingcomplete: function (event) {
$scope.bindingCompleted = "binding is completed";
}
}
});
</script>
HTML:
<div ng-app="demoApp" ng-controller="demoController">
<jqx-grid jqx-settings="settings"></jqx-grid>
</div>

Related

Kendo Grid - how to remember selected row?

http://dojo.telerik.com/eWakO
Kendo Grid - here how should i modify above code to remember selected row? Example, if i have highlighted 4th row on 1st page and then scrolls to pages and come back to 1st page, then 4th row should be highlighted.
Thanks
Datha
Here is an example from the documentation:
http://docs.telerik.com/kendo-ui/controls/data-management/grid/how-to/Selection/persist-row-selection-while-paging
It relies on the change and dataBound events to save and restore selected rows by their IDs.
<div id="grid"></div>
<script>
$(function () {
var selectedOrders = [];
var idField = "OrderID";
$("#grid").kendoGrid({
dataSource: {
type: "odata",
transport: {
read: "http://demos.kendoui.com/service/Northwind.svc/Orders"
},
schema: {
model: {
id: "OrderID",
fields: {
OrderID: { type: "number" },
Freight: { type: "number" },
ShipName: { type: "string" },
OrderDate: { type: "date" },
ShipCity: { type: "string" }
}
}
},
pageSize: 10,
serverPaging: true,
serverFiltering: true,
serverSorting: true
},
height: 400,
selectable: "multiple",
pageable: {
buttonCount: 5
},
sortable: true,
filterable: true,
navigatable: true,
columns: [
{
field: "ShipCountry",
title: "Ship Country",
width: 300
},
{
field: "Freight",
width: 300
},
{
field: "OrderDate",
title: "Order Date",
format: "{0:dd/MM/yyyy}"
}
],
change: function (e, args) {
var grid = e.sender;
var items = grid.items();
items.each(function (idx, row) {
var idValue = grid.dataItem(row).get(idField);
if (row.className.indexOf("k-state-selected") >= 0) {
selectedOrders[idValue] = true;
} else if (selectedOrders[idValue]) {
delete selectedOrders[idValue];
}
});
},
dataBound: function (e) {
var grid = e.sender;
var items = grid.items();
var itemsToSelect = [];
items.each(function (idx, row) {
var dataItem = grid.dataItem(row);
if (selectedOrders[dataItem[idField]]) {
itemsToSelect.push(row);
}
});
e.sender.select(itemsToSelect);
}
});
});
</script>

Bootstrap datetimepicker glyphicon calendar doesn't open

I am trying to use Bootstrap 3 datetimepicker. But the glyphicon calendar doesn't open. See this fiddle:
http://jsfiddle.net/vqsss5fx/
$(function () {
var data = [
{ rank: 1, company: 'Exxon Mobil', DatePicker: '04/04/1990 00:00', revenues: '339938.0', profits: '36130.0' },
{ rank: 2, company: 'Wal-Mart Stores', DatePicker: '05/03/2014 00:00', revenues: '315654.0', profits: '11231.0' },
];
var obj = {
title: "ParamQuery Grid with JSON Data",
scrollModel:{autoFit:true, theme:true}
};
obj.colModel = [
{ title: "Rank", width: 100, dataType: "integer", dataIndx: "rank" },
{ title: "Company", width: 200, dataType: "string", dataIndx: "company" },
{ title: "DatePicker", width: 200, dataType: "string", dataIndx: "date",editable:false,
render : function(){
var date = '<div class="form-group" style="width:150px;margin-left:50px;text-align:center"><div class="input-group date" id="datetimepicker123"><input type="text" value="04/05/2012 00:00" class="form-control"><span class="input-group-addon"><span class="glyphicon-calendar glyphicon"></span></span></div></div>';
return date;
}
},
{ title: "Revenues ($ millions)", width: 150, dataType: "float", align: "right", dataIndx: "revenues" },
];
$('body').on('mouseover','.input-group',function() {
$("#datetimepicker123").datetimepicker();
});
obj.dataModel = { data: data };
$("#grid_json").pqGrid(obj);
});
<div id="grid_json" style="margin:100px;"></div>
I see three problems:
You have multiple HTML elements with the same ID (#datetimepicker123): please avoid it!
Instead of $("#datetimepicker123").datetimepicker(); you should use $(".input-group.date").datetimepicker(); to add a timepicker to every date input.
The timepicker appears, but it's truncated by the HTML Cell (you can see the arrow under the input field). Some CSS customization might be required:
.pq-grid-cell{
overflow:visible;
}
Result: http://jsfiddle.net/vqsss5fx/3/

AmStockChart by json did not display

I want to use AmChart and getting data for charts from MySQL by JSON.
But it display not things.
This is my js source:
<script type="text/javascript">
var chart2;
$(document).ready(function(){
$.getJSON("data", function (data) {
chart2.dataProvider = data;
chart2.dataDateFormat = "YYYY-DD-MM";
chart2.validateData();
});
});
var chart2 = AmCharts.makeChart("chartdiv2", {
type: "stock",
theme: "none",
pathToImages: "http://www.amcharts.com/lib/3/images/",
dataSets: [{
title: "Participants",
fieldMappings: [{
fromField: "student",
toField: "student"
}],
categoryField: "date"
}
],
dataDateFormat: "YYYY-MM-DD",
panels: [{
showCategoryAxis: false,
title: "Student",
percentHeight: 70,
stockGraphs: [{
id: "g1",
valueField: "student",
comparable: true,
compareField: "student",
balloonText: "[[title]]:<b>[[student]]</b>",
compareGraphBalloonText: "[[title]]:<b>[[student]]</b>"
}],
stockLegend: {
periodValueTextComparing: "[[percents.student.close]]%",
periodValueTextRegular: "[[value.close]]"
}
}],
chartScrollbarSettings: {
graph: "g1"
},
chartCursorSettings: {
valueBalloonsEnabled: true,
fullWidth: true,
cursorAlpha: 0.1,
valueLineBalloonEnabled: true,
valueLineEnabled: true,
valueLineAlpha: 0.5
},
periodSelector: {
position: "left",
periods: [{
period: "MM",
selected: true,
count: 1,
label: "1 month"
}, {
period: "YYYY",
count: 1,
label: "1 year"
}, {
period: "YTD",
label: "YTD"
}, {
period: "MAX",
label: "MAX"
}]
},
dataSetSelector: {
position: "left"
}
});
</script>
The json file output from data function
[{"date":"2011-01-10","student":"100"},{"date":"2012-02-11","student":"122"}]
Anyone know the solution please help. Thanks.
Try to parse your data,
For Eg,
$.getJSON("data", function (data) {
newData=JSON.parse(data);
chart2.dataProvider = newData;
chart2.dataDateFormat = "YYYY-DD-MM";
chart2.validateData();
});

dojo dgrig jsonrest put response format

So I have a JsonRest store with a dgrid attached to it.
I use php and the yii framework.
If I fire a PUT I get a response formatted like this:
[{id: 1, abbreviation: 'FL' }]
Is that the correct form for the row to be updated?
Or should I get only {id: 1, abbreviation: 'FL' } as a response?
Thanks!
Update #1:
<div
data-dojo-type="dijit.MenuBar"
data-dojo-props="region:'top', layoutPriority:2, style:'margin-top: 10px'">
<div
id="OrderButton"
data-dojo-type="dijit.form.Button">
<span>Submit Order</span>
<script type="dojo/on" data-dojo-event="Click">
handleFinalizeOrder();
</script>
</div>
<span class="right">Package Price: 20$ + 1$/pic</span><span id="results"></span>
</div>
<div id="imageList"></div>
<?php $this->beginDojoScript() ?>
<script type="text/javascript">
require([
'dojo/parser',
'dojo/dom-construct',
'dojo/dom-style',
'dojo/_base/declare',
'dojo/_base/xhr',
'dojo/_base/loader',
'dojo/_base/Deferred',
'dojo/data/ItemFileWriteStore',
'dojo/store/util/QueryResults',
'dijit/Toolbar',
'dijit/Tree',
'dijit/TooltipDialog',
'dijit/layout/StackContainer',
'dijit/layout/ContentPane',
'dijit/form/Button',
'dijit/tree/ForestStoreModel',
'dijit/form/Form',
'dijit/form/ValidationTextBox',
'dijit/form/DropDownButton',
'dijit/form/CheckBox',
'dojox/form/Uploader',
'dojox/form/uploader/plugins/IFrame',
'dgrid/OnDemandGrid',
'dgrid/Selection',
'dojo/on',
'dgrid/editor',
'dgrid/List',
'dgrid/tree',
'dgrid/Keyboard',
'dijit/form/HorizontalSlider',
'dijit/form/NumberSpinner',
'dgrid/OnDemandGrid',
'dojo/store/Memory',
'dojo/store/Observable',
'dijit/form/FilteringSelect',
'dojo/data/ObjectStore',
'dijit/Dialog',
'dojo/store/Cache',
'dojo/store/JsonRest',
'dojo/domReady!'
], function(parser, domConstruct, domStyle, declare, xhr,
loader, Deferred,ItemFileWriteStore, QueryResults, Toolbar, Tree, TooltipDialog,
StackContainer, ContentPane, Button,
ForestStoreModel, Form, ValidationTextBox, DropDownButton, CheckBox,
Uploader, UploaderIFramePlugin, OndemandGrid, Selection, on, editor,
List, tree, Keyboard, Slider, NumberSpinner, Grid, Memory,
Observable, FilteringSelect, ObjectStore, Dialog, Cache, JsonRest) {
/* Declaration */
filetypeStore = Observable(new Memory({
idProperty: "pictype",
labelProperty: "name",
data: [
{ "pictype": "1", "name": "Paperpic" },
{ "pictype": "3", "name": "DVD" }
]
}));
filesubtypeStore = Observable(new Memory({
idProperty: "picsubtype",
labelProperty: "name",
data: [
{ "picsubtype": "1", "pictype": "1", "name": "10x15" },
{ "picsubtype": "2", "pictype": "1", "name": "13x18" },
{ "picsubtype": "3", "pictype": "1", "name": "20x30" },
{ "picsubtype": "4", "pictype": "1", "name": "30x45" },
{ "picsubtype": "10", "pictype": "3", "name": "DVD" }
]
}));
var columns = [
{
label: 'Picture',
field: 'filename',
formatter: function(filename){
return '<div class="icon" style="background-image:url(<?php echo Yii::app()->baseUrl ?>/images/client/thumbnails/' + filename + ');"><a class="iconlink" href="<?php echo Yii::app()->baseUrl ?>/images/client/' + filename + '"> </a></div>';
}
},
editor({
label: 'Type of pic', autoSave: false, field: 'pictype',
widgetArgs: {
store: filetypeStore, autoComplete: true, required: true, maxHeight: 150, style: "height: 20px; width: 120px;"
},
}, FilteringSelect),
editor({
label: 'Size of pic', autoSave: true, field: 'picsubtype',
widgetArgs: {
store: filesubtypeStore, autoComplete: true, required: true, maxHeight: 150, style: "height: 20px; width: 120px;"
},
}, FilteringSelect),
{
label: 'Price/pcs',
field: 'picprice',
formatter: function(picprice){
return '<span class="pic_price">' + picprice + '</span>';
}
},
editor({
label: 'Number of pics',
autoSave: true,
field: 'piccount',
widgetArgs: {
class: 'pic_count',
style: 'width: 4em;',
constraints: {
min:1,
max:100,
places:0
}
},
}, NumberSpinner),
];
/* Model */
collectionId = <?php echo $colID; ?>;
var userMemoryStore = Memory();
var userJsonRestStore = JsonRest({idProperty: "id", target: "<?php echo $this->createUrl('/orderCollectionOrder/handleOrderedImages') ?>?id=" + collectionId + "&picid="});
var imageStore = Cache(userJsonRestStore, userMemoryStore);
window.grid = new (declare([editor, ObjectStore, OndemandGrid, Selection]))({
store: imageStore,
getBeforePut: false,
columns: columns
}, "imageList");
parser.parse();
grid.on(".dgrid-content .iconlink:click", function (evt) {
evt.preventDefault();
var data = dojo.getAttr(this, "href");
var dlg = new Dialog({
title: "Pic: " + data.substr(15),
className:"dialogclass",
content: '<img src="' + data + '">'
});
dlg.show();
});
});
</script>
<?php $this->endDojoScript() ?>
So, if I change the second filteringselect, the put fires correctly.
Contents of put in firebug:
{"id":"1","categoryId":"2","collectionId":"146","fileid":"20737","pictype":"3","picsubtype":"2","filename":"pic_143_resize.jpg","filetype":"DVD","filesubtype":"30x45","picprice":"2000","piccount":"2"}
Response:
{"id":"1","categoryId":"2","collectionId":"146","fileid":"20737","pictype":"3","picsubtype":"2","filename":"pic_143_resize.jpg","filetype":"DVD","filesubtype":"13x18","picprice":"300","piccount":"2"}
So I get the response, but the dgrid does not get updated...
Should I add an Observable store as well?
Thanks!
This actually comes down to logic in dojo/store/Observable in this case. Observable will do one of two things in response to put calls:
If the server request resolves to an object, this object will be passed to notify (which the grid will pick up)
Otherwise, the object originally passed to put will be passed through to notify
You're falling into the first case, since arrays are objects - in which case, as you suspected, you'll want just the object itself, not an array. The array doesn't make much sense anyway, since put operates on a single item.

Dojo grid nested json

I'd like to have a dojo grid which connects to a server url which outputs the following json :
{identifier : "id"
items : [ { id: "1", name: "John", university : { name: "XXX", address: "YYY" } }].
Basically I have a nested json. I would like to represent the university name and University address as separate columns in the grid.
I tried using the dojox.grid.DataGrid object and creating a gird layout, but do not know how to refer to the nested elments and university.name and university.address don't seem to work.
I am using dojo 1.6.1.
Does anybody have any pointers?
This is the js code I use :
dojo.require("dojox.grid.DataGrid");
dojo.require("dojo.data.ItemFileReadStore");
dojo.addOnLoad(function(){
// our test data store for this example:
var jsonStore = new dojo.data.ItemFileReadStore({
url: '/MainDeployer/ajax/users/get.json'
});
var layoutUsers = [
[{
field: "name",
name: "Name",
width: 10
},
{
field: "university.name",
name: "University Name",
width: 10
},
{
field: "university.address",
name: "University Address",
width: 'auto'
}]];
// create a new grid:
var grid = new dojox.grid.DataGrid({
query: {},
store: jsonStore,
clientSort: true,
rowSelector: '20px',
structure: layoutUsers
},
document.createElement('div'));
dojo.byId("usersTable").appendChild(grid.domNode);
grid.startup();
});
Thanks,
Cristian
What kind of store are you using? Have a look at the dojo.data.ItemFileReadStore documentation, there is an example with a situation like yours:
http://dojotoolkit.org/reference-guide/dojo/data/ItemFileReadStore.html#item-structure
This would help you fetching all the items with a single call to the method "fetch". If for some reasons it doesn't work due to the different json structure, you can continue using ItemFileReadStore , and create a function that loops over all the objects in your json and uses the loadItem method for adding items one by one in this way (it's not beautiful but it works):
var myData = {"items" : []};
var myStore = new dojo.data.ItemFileWriteStore({data: myData});
var myLayout = [{
field: 'name',
name: 'Name',
width: '200px'
},
{
field: 'universityName',
name: 'University Name',
width: '100px'
},
{
field: 'universityAddress',
name: 'University Address',
width: '60px'
}];
var myGrid;
dojo.addOnLoad(function(){
myGrid = new dojox.grid.DataGrid({
store: myStore,
structure: myLayout
}, document.createElement('div'));
dojo.byId("myGridContainer").appendChild(myGrid.domNode);
myGrid.startup();
dojo.xhrGet({
url: myURL,
handleAs: "json",
headers: {
"Content-Type": "application/json; charset=uft-8",
"Accept" : "application/json"
},
load: function(responseObject, ioArgs) {
myList = responseObject;
dojo.forEach(myList.items, function(element) {
myStore.newItem({"name": element.name,
"universityName": element.university.name,
"universityAddress": element.university.address});
});
})
});
}
se a formatter:
var nameFormatter = function(value, rowIdx){
return value.name;
};
var addressFormatter = function(value, rowIdx){
return value.address;
};
var layoutUsers = [
[{
field: "name",
name: "Name",
width: 10
},
{
field: "university",
name: "University Name",
width: 10,
formatter: nameFormatter
},
{
field: "university",
name: "University Address",
width: 'auto',
formatter: addressFormatter
}]];