Difficulting initializing a Kendo grid in an AngularJS controller - angularjs

I'm trying to bind some data to a Angular-Kendo UI grid, but as soon as I click on the tab which contains my grid widget I get this error below :
Error: error:unpr
Unknown Provider
Unknown provider: $modalInstanceProvider <- $modalInstance
Description
This error results from the $injector being unable to resolve a required dependency.
I'm not really sure why it's crashing on $modalInstance since I'm trying to wire up my Kendo grid with some data. This is strange.
Here's my HTML :
<div data-ng-controller="GridSettingsCtrl" class="col-md-4">
<div class="col-lg-12">
<h3>Choose a Dimension grouping</h3>
<span id="userDimenGrid" kendo-grid="userDimenGrid"
k-data-source="userDimenGridDS"
k-options="userDimenGridOptions"
k-rebind="userDimenGridOptions" />
</div>
</div>
and here's my Angular controller code :
FYI: the HTML attrib k-data-source="userDimenGridDS" is wired to Kendo DataSource $scope.userDimenGridDS in my js code - which in turn calls read: getUserDimensionsList for the data.
(function () {
'use strict';
angular.module('rage')
.controller('GridSettingsCtrl', ['$scope', '$modalInstance', 'datacontext', 'widget', gridSettings]);
function gridSettings($scope, $modalInstance, datacontext, widget) {
var settings = this;
// add widget to scope
$scope.widget = widget;
// set up result object
$scope.result = jQuery.extend(true, {}, widget);
$scope.ok = function () {
$modalInstance.close($scope.result);
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
$scope.userDimenGridOptions = {
selectable: true,
sortable: true,
pageable: true,
columns: [
{ field: "id", width: "10px", hidden: true },
{ field: "dimension", width: "80px", editor: dimenDropDown, template: "#=dimension#" }, // DropDown editor defined !!
{ field: "hierarchy", width: "60px" },
{ command: [{ name: "edit", text: '' }, { name: "destroy", text: '' }], width: 120 }
],
editable: "inline",
toolbar: ["create"],
};
// SERVER-SIDE DIMENSIONS DATA SOURCE - see dimenDropDown()
$scope.dimensionsDataSource = new kendo.data.DataSource({
transport: {
read: getDimensionsFromServer
}
});
// USER DIMENSIONS DATA SOURCE !!
$scope.userDimenData = [];
$scope.userDimenGridDS = new kendo.data.DataSource({
transport: {
read: getUserDimensionsList,
create: function (options) {
options.success(options.data);
}
},
schema: {
model: {
id: "id",
fields: {
dimension: { type: "string" },
hierarchy: { type: "boolean" }
}
}
},
pageSize: 5
});
// SERVER-SIDE DIMENSIONS DATA SOURCE - see dimenDropDown()
$scope.dimensionsDataSource = new kendo.data.DataSource({
transport: {
read: getDimensionsFromServer
}
});
}; // end of gridSettings()
function getUserDimensionsList(options) {
// Retrieve user dimensions list from server or local cache, and return to Kendo Grid DataSource.
// Called by: read option of $scope.dimenUserGridDS
var userDimenFromStorage;
if ($scope.readUserDimensionsFromCache) { // pull from cache
userDimenFromStorage = reportsContext.getUserDimenFromLocalStorage();
}
if ($scope.readUserDimensionsFromCache && userDimenFromStorage != null && userDimenFromStorage.length != 0) {
options.success(userDimenFromStorage);
}
else { // pull from server
datacontext.getDimenUserList().then(function (data) {
if (data.status == 'FAIL') {
if (data.messages.length > 0) {
logErr("Error retrieving user Dimensions list: " + data.messages[0]);
return;
}
}
else {
// RETURN DUMMY REC FOR TESTING...
$scope.userDimenData = data;
options.success($scope.userDimenData);
}
});
}
}
function getDimensionsFromServer(options) {
datacontext.getDimensionsFromServer().then(function (data) {
if (data.status == 'FAIL') {
if (data.messages.length > 0) {
logErr("Error retrieving KRI list: " + data.messages[0]);
return;
}
}
else {
options.success(data.data);
}
});
}
// USER DIMENSION DROPDOWN FOR GRID
function dimenDropDown(container, options) {
$('<input id="dimenDropDown" data-text-field="name" data-value-field="name" data-bind="value:' + options.field + '"/>')
.appendTo(container)
.kendoComboBox({
dataTextField: "name",
dataValueField: "name",
dataSource: $scope.dimensionsDataSource
});
}
})();
and here's a screen shot to show the tab I click on to get my "Dimension Grouping" grid, which of course does not render yet due to the error:
As I mentioned, the error occurs as soon as I click on that "Dimensions" tab - which is when it should try and bind the data to the Kendo grid.
Here's a screen shot of that :
If anyone can see a problem with my code, your advice would be appreciated...
regards,
Bob

I found my problem. I'm using Malhar dashboard widget framework, which specifies the controller in it's settings.
Reference to Malhar dashboard on github: https://github.com/DataTorrent/malhar-angular-dashboard
So my HTML ended up looking like this, without the data-controller attrib:
<div class="col-md-4">
<div class="col-lg-12">
<h3>Choose a Dimension grouping</h3>
<span id="userDimenGrid" kendo-grid="userDimenGrid"
k-data-source="userDimenGridDS"
k-options="userDimenGridOptions"
k-rebind="userDimenGridOptions" />
</div>
</div>

Related

ExtJS 6.2 - controller keeps looking stores in my cotroller path

I'm new in extJS and i've been working in an app for some time.
My problem is that I have an app with an MVC architecture and as I instatiate the controller I declare de stores. But when I run this app in the browser, for some reason the controller is trying to get the store from my controller folder.
I have other controllers runing in my app and all of them looks for the store in the stores folder.
Does anyone have a clue about this issue?
Thanks
Ext.define('SGE.controller.staticData.AbstractController', {
extend: 'Ext.app.Controller',
requires: [
'SGE.util.Util'
],
stores: [
'Actors',
'staticData.Categories',
'staticData.Cities',
'staticData.Countries',
'staticData.Languages'
],
views: [
'staticData.AbstractGrid',
'staticData.Actors',
'staticData.Categories',
'staticData.Cities',
'staticData.Countries',
'staticData.Languages'
],
init: function(application) {
this.control({
"staticdatagrid": {
render: this.render,
edit: this.onEdit
},
"staticdatagrid button[itemId=add]": {
click: this.onButtonClickAdd
},
"staticdatagrid button[itemId=save]": {
click: this.onButtonClickSave
},
"staticdatagrid button[itemId=cancel]": {
click: this.onButtonClickCancel
},
"staticdatagrid button[itemId=clearFilter]": {
click: this.onButtonClickClearFilter
},
"staticdatagrid actioncolumn": {
itemclick: this.handleActionColumn
},
"citiesgrid button[itemId=clearGrouping]": {
toggle: this.onButtonToggleClearGrouping
}
});
this.listen({
store: {
'#staticDataAbstract': {
write: this.onStoreSync
}
}
});
if (!Ext.getStore('countries')) {
Ext.create('SGE.store.staticData.Countries');
}
if (!Ext.getStore('languages')) {
Ext.create('SGE.store.staticData.Languages').load();
}
if (!Ext.getStore('actors')) {
Ext.create('SGE.store.staticData.Actors');
}
if (!Ext.getStore('categories')) {
Ext.create('SGE.store.staticData.Categories');
}
},
onStoreSync: function(store, operation, options){
Packt.util.Alert.msg('Success!', 'Your changes have been saved.');
console.log(store);
console.log(operation);
console.log(options);
},
render: function(component, options) {
component.getStore().load();
if (component.xtype === 'citiesgrid' && component.features.length > 0){
if (component.features[0].ftype === 'grouping'){
component.down('toolbar#topToolbar').add([
{
xtype: 'tbseparator'
},
{
xtype: 'button',
itemId: 'clearGrouping',
text: 'Group by Country: ON',
iconCls: 'grouping',
enableToggle: true,
pressed: true
}
]);
}
}
},
onEdit: function(editor, context, options) {
context.record.set('last_update', new Date());
},
onButtonClickAdd: function (button, e, options) {
var grid = button.up('staticdatagrid'),
store = grid.getStore(),
modelName = store.getProxy().getModel().modelName,
cellEditing = grid.getPlugin('cellplugin');
store.insert(0, Ext.create(modelName, {
last_update: new Date()
}));
cellEditing.startEditByPosition({row: 0, column: 1});
},
onButtonClickSave: function (button, e, options) {
button.up('staticdatagrid').getStore().sync();
},
onButtonClickCancel: function (button, e, options) {
button.up('staticdatagrid').getStore().reload();
},
onButtonClickClearFilter: function (button, e, options) {
button.up('staticdatagrid').filters.clearFilters();
},
handleActionColumn: function(column, action, view, rowIndex, colIndex, item, e) {
var store = view.up('staticdatagrid').getStore(),
rec = store.getAt(rowIndex);
if (action == 'delete'){
store.remove(rec);
Ext.Msg.alert('Delete', 'Save the changes to persist the removed record.');
}
},
onButtonToggleClearGrouping: function (button, pressed, options) {
var store = button.up('citiesgrid').getStore();
if (pressed){
button.setText('Group by Country: ON');
store.group('country_id');
} else {
button.setText('Group by Country: OFF');
store.clearGrouping();
}
}
});
Browser response
enter image description here
An ExtJs Controller pulls in the specified store files before rendering its UI. Assuming that you have not created any store files (assumption form your init function where you created the store if they do not exist), it first searches the store files to load them into the memory.
Another possible problem may be the store has a different namespace than that of the application, you will need to specify the full class name as well as define a path in the Loader's paths config or setPath method.
Refer doc ExtJs Controller's Stores.

Automatically trigger change event in kendo detail grid

I have a angular kendo grid similar to the telerik demo.
Main Grid:
$scope.mainGridOptions = {
dataSource: {
transport: {
read: queryurl
},
pageSize: 5,
},
sortable: true,
pageable: true,
detailTemplate: kendo.template($("#template").html()),
dataBound: function () {
this.expandRow(this.tbody.find("tr.k-master-row").first());
}
}
Detail Grid:
$scope.detailGridOptions = function (item) {
return {
dataSource: {
transport: {
read: detailsUrl
},
},
change: $scope.showDocument,
selectable: "row",
dataBound: function (e) {
var row = e.sender.tbody.find("tr:first");
row.addClass("k-state-selected");
row.trigger("change") //doesnt work!
}
}
}
When the user clicks a row in the detail grid a document is rendered in a jquery dialog. This all works as expected.
When the grid loads, the first master-row is expanded. Now I need the change event of the first row in the detailsgrid to fire automatically, so that the first document of the first entry gets displayed automatically, when the app loads.
As I was able to highlight the first detailrow I thought that i could trigger the change event like this: row.trigger("change") but this doesn't seem to work.
Any ideas are much appreciated!
Try using the select method of the grid to select the row instead of manually adding the "k-state-selected" class. It will automatically trigger the change event for you. JsBin example.
(function() {
'use strict';
var grid = $('#grid').kendoGrid({
dataSource: [
{ name: 'Brett', age: 37 },
{ name: 'Susan', age: 38 }
],
selectable: 'row',
change: function (e) {
console.log('change triggered');
},
dataBound: function (e) {
var row = this.tbody.find('tr:first');
this.select(row);
}
}).data('kendoGrid');
})();

Kendo UI Angular JS and AutoComplete with a service

I'm making an Angular App and I'm starting to use some of the Kendo UI controls. I'm having some issues wiring up the AutoComplete control. I would like to use a factory that will return the list of "auto complete" values from my database.
I have iincluded the auto complete control and I'm trying to use the k-options attribute:
<input kendo-auto-complete ng-model="myFruit" k-options="FruitAutoComplete" />
In my controller the following hard coded list of fruits work:
$scope.FruitAutoComplete = {
dataTextField: 'Name',
dataSource:[
{ id: 1, Name: "Apples" },
{ id: 2, Name: "Oranges" }
]
}
When I move this over to use my factory I see it calling and returning the data from the factory but it never get bound to the screen.
$scope.FruitAutoComplete = {
dataTextField: 'Name',
dataSource: new kendo.data.DataSource({
transport: {
read: function () {
return FruitFactory.getYummyFruit($scope.myFruit);
}
}
})
}
I end up with the request never being fulfilled to the auto complete.
My factory is just returning an array of fruit [
my Fruit Factory Code:
getYummyFruit: function (val) {
return $http.get('api/getFruitList/' + val)
.then(function (res) {
var fruits= [];
angular.forEach(res.data, function (item) {
fruits.push(item);
});
return fruits;
});
}
Here is your solution
http://plnkr.co/edit/iOq2ikabdSgiTM3sqLxu?p=preview
For the sake of plnker I did not add $http (UPDATE - here is http://plnkr.co/edit/unfgG5?p=preview with $http)
UPDATE 2 - http://plnkr.co/edit/01Udw0sEWADY5Qz3BnPp?p=preview fixed problem as per #SpencerReport
The controller
$scope.FruitAutoCompleteFromFactory = {
dataTextField: 'Name',
dataSource: new kendo.data.DataSource({
transport: {
read: function (options) {
return FruitFactory.getYummyFruit(options)
}
}
})
}
The factory -
factory('FruitFactory', ['$http',
function($http) {
return {
getYummyFruit: function(options) {
return $http.get('myFruits.json').success(
function(results) {
options.success(results);
});
}
}
}

create/update user story using rally app sdk

Until now, I have been querying the data stores using Rally App SDK, however, this time I have to update a story using the js sdk. I tried looking up for examples for some sample code that demonstrates how the App SDK can be used to update/add values in Rally. I have been doing CRUD operations using Ruby Rally API but never really did it with the app sdk.
Can anyone provide some sample code or any link to where I could check it out?
Thanks
See this help document on updating and creating reocrds. Below are examples - one updates a story, the other creates a story. There is not much going on in terms of UI: please enable DevTools console to see console.log output.
Here is an example of updating a Defect Collection on a User Story:
Ext.define('CustomApp', {
extend: 'Rally.app.App',
componentCls: 'app',
launch: function() {
console.log("launch");
Rally.data.ModelFactory.getModel({
type: 'User Story',
success: this._onModelRetrieved,
scope: this
});
},
_onModelRetrieved: function(model) {
console.log("_onModelRetrieved");
this.model = model;
this._readRecord(model);
},
_readRecord: function(model) {
var id = 13888228557;
console.log("_readRecord");
this.model.load(id, {
fetch: ['Name', 'Defects'],
callback: this._onRecordRead,
scope: this
});
},
_onRecordRead: function(record, operation) {
console.log('name...', record.get('Name'));
console.log('defects...', record.get('Defects'));
if(operation.wasSuccessful()) {
//load store first by passing additional config to getCollection method
var defectStore = record.getCollection('Defects', {
autoLoad: true,
listeners: { load: function() {
//once loaded now do the add and sync
defectStore.add({'_ref':'/defect/13303315495'});
defectStore.sync({
callback: function() {
console.log('success');
}
});
}}
});
}
},
});
Here is an example of creating a user story, setting a project and scheduling for an iteration:
Ext.define('CustomApp', {
extend: 'Rally.app.TimeboxScopedApp',
componentCls: 'app',
scopeType: 'iteration',
comboboxConfig: {
fieldLabel: 'Select an Iteration:',
labelWidth: 100,
width: 300
},
addContent: function() {
this._getIteration();
},
onScopeChange: function() {
this._getIteration();
},
_getIteration: function() {
var iteration = this.getContext().getTimeboxScope().record.get('_ref');
console.log('iteration',iteration);
if (!this.down('#b2')) {
var that = this;
var cb = Ext.create('Ext.Container', {
items: [
{
xtype : 'rallybutton',
text : 'create',
id: 'b2',
handler: function() {
that._getModel(iteration);
}
}
]
});
this.add(cb);
}
},
_getModel: function(iteration){
var that = this;
Rally.data.ModelFactory.getModel({
type: 'UserStory',
context: {
workspace: '/workspace/12352608129'
},
success: function(model) { //success on model retrieved
that._model = model;
var story = Ext.create(model, {
Name: 'story 777',
Description: 'created via appsdk2'
});
story.save({
callback: function(result, operation) {
if(operation.wasSuccessful()) {
console.log("_ref",result.get('_ref'), ' ', result.get('Name'));
that._record = result;
that._readAndUpdate(iteration);
}
else{
console.log("?");
}
}
});
}
});
},
_readAndUpdate:function(iteration){
var id = this._record.get('ObjectID');
console.log('OID', id);
this._model.load(id,{
fetch: ['Name', 'FormattedID', 'ScheduleState', 'Iteration'],
callback: function(record, operation){
console.log('ScheduleState prior to update:', record.get('ScheduleState'));
console.log('Iteration prior to update:', record.get('Iteration'));
record.set('ScheduleState','In-Progress');
record.set('Iteration', iteration);
record.set('Project', '/project/12352608219')
record.save({
callback: function(record, operation) {
if(operation.wasSuccessful()) {
console.log('ScheduleState after update..', record.get('ScheduleState'));
console.log('Iteration after update..', record.get('Iteration'));
}
else{
console.log("?");
}
}
});
}
})
}
});

AngularJS UI ng-grid not painting content text & blank when used inside directive

I am developing one SearchAndSelect control (AngularJS directive) which contains it's own ng-grid, slider page. Everything is working, data is being fetched, number of rows are coming to the grid, but grid is not showing text.
SearchAndSelectDirective.js
App.directive('searchAndSelect',
function () {
return {
restrict: 'E',
templateUrl: "/app/directives/searchAndSelect.html",
controller: "searchAndSelectController",
transclude: false,
scope: {
currentNode: '='
},
compile: function() {
// return true;
}
};
}
);
SearchAndSelect.html
<button class="btn" ng-click="openSliderPage()">Add/Remove {{EntityName}}</button>
<div id="divSlide" class="sliderDiv">
<div class="sliderHeader" ng-model="partialPageHeading">
<span class="sliderHeaderLabelOriginal">{{partialPageHeading}}</span>
</div>
<div>
<div class="gridStyle" ng-grid="gridOptions"></div>
<div class="modal-footer">
<input ng-model="filterOptions.filterText" />
<button class="btn btn-info" ng-click="getPagedDataAsync()">Filter</button>
<button class="btn btn-primary" ng-click="add()">Update</button>
<button class="btn btn-warning" ng-click="cancnel()">Cancel</button>
</div>
</div>
<!--<ng-include src="svcSliderView"></ng-include>-->
</div>
It has got it's own controller, which fetches the data in async manner. Number of rows are being generated within the grid, grid is visible. I have code inside controller to mark some rows selected, and it is happening. But only the content is not being displayed. If I see browser's element exploration, I can see the data is there.
SearchAndSelectController.js
$scope.filterOptions = {
filterText: "",
useExternalFilter: false
};
$scope.pagingOptions = {
pageSizes: [50, 100, 200],
pageSize: 50,
currentPage: 1
};
$scope.getVehListParams = function () {
var params = { PageNo: $scope.pagingOptions.currentPage, PageSize: $scope.pagingOptions.pageSize };
params.CalculateTotal = false;
if (!$scope.totalCount) {
params.CalculateTotal = true;
}
params.FilterText = '';
if ($scope.filterOptions.filterText) {
params.FilterText = $scope.filterOptions.filterText;
}
return params;
};
$scope.getPagedDataAsync = function () {
var vehListGetParams = $scope.getVehListParams();
seVehicleResource.get(vehListGetParams,
function (result) {
$scope.dataList = result.DataList;
if (result.TotalCount || result.TotalCount == 0) {
$scope.totalCount = result.TotalCount;
}
//mark already added rows in left as selected.
$timeout(function () {
if ($scope.planSelected) {
_.each($scope.planSelected.Vehicles, function (vehicle) {
var vIdx = $.map(result.DataList, function (obj, index) {
if (obj.VehicleId == vehicle.VehicleId) {
return index;
}
return null;
});
if (vIdx && vIdx.length > 0) {
$scope.vehicleExisted.push(result.DataList[vIdx[0]]);
$scope.gridOptions.selectItem(vIdx[0], true);
}
});
}
});
}, function (error) {
console.log(error);
});
};
$scope.$watch('pagingOptions', function (newVal, oldVal) {
if (newVal !== oldVal && (newVal.currentPage !== oldVal.currentPage || newVal.pageSize !== oldVal.pageSize)) {
$scope.getPagedDataAsync();
}
}, true);
$scope.allSelected = false;
$scope.gridOptions = {
data: 'dataList',
enablePaging: true,
showFooter: true,
showFilter: true,
columnDefs: [{ field: 'Make', displayName: 'Make', width: '35%' }, { field: 'Model', displayName: 'Model', width: '35%' }, { field: 'BeginYear', displayName: 'Begin Year', width: '15%' }, { field: 'EndYear', displayName: 'End Year', width: '15%' }],
totalServerItems: 'totalCount',
pagingOptions: $scope.pagingOptions,
filterOptions: $scope.filterOptions.filterText,
showSelectionCheckbox: true,
afterSelectionChange: $scope.afterSelectionChange,
};
I used this directive inside following div, which made its fontsize to 0, removing this container grid, fixed my issue.
Thanks All
<div class="btn-group">

Resources