I want to read a array value inside factory in angularjs - angularjs

I am trying to read value in array in factory but I am unable to do so. I am using ng-grid and when I click on one row I get selecteditems list which I pass in another controller where I call a factory service in which I pass that as a parameter but that parameter in the factory stays as array and when I read it using index it shows blank.
My code is as below -
myNgApp.controller('MyGrid', ['$scope', function ($scope) {
$scope.mySelections = [];
$scope.mySelItems = [];
$scope.myData = [{ Reference: 12, Customer: "fff", Title: "sd", Task: "Enter Details", Received: "Today", Due: "01/09/2014" },
{ Reference: 7899, Customer: "eee", Title: "dsd", Task: "Enter Details", Received: "Yesterday", Due: "05/09/2014" }];
$scope.gridOptions = {
data: 'myData',
checkboxHeaderTemplate: '<input class="ngSelectionHeader" type="checkbox" ng-model="allSelected" ng-change="toggleSelectAll(allSelected)"/>',
selectWithCheckboxOnly: true,
showSelectionCheckbox: true,
selectedItems: $scope.mySelections,
multiSelect: true,
columnDefs: [{ field: 'Reference', displayName: 'Reference', width: '*' }, { field: 'Customer', displayName: 'Customer', width: '**' }, { field: 'Title', displayName: 'Title', width: '***' }, { field: 'Task', displayName: 'Task', width: '***' }, { field: 'Received', displayName: 'Received', width: '**' }, { field: 'Due', displayName: 'Due', width: '**' }],
showGroupPanel: true,
enableCellSelection: false,
enableRowSelection: true,
enableCellEditOnFocus: false,
enablePinning: true,
showColumnMenu: true,
showFilter: true,
enableColumnResize: true,
enableColumnReordering: true,
maintainColumnRatios: true,
afterSelectionChange: function () {
angular.forEach($scope.mySelections, function (item) {
if ($scope.mySelItems.length == 0) {
$scope.mySelItems.push(item.Title)
}
else {
$scope.mySelItems[0] = item.Title
}
});
}
};
}]);
myNgApp.factory('myPreviewDataService', function () {
return function (x) {
var arr = [x, "Apple", "Banana", "Orange"];
return arr
};
});
myNgApp.factory('myPreviewTplService', function () {
return function () {
return '<div><div class="ngPreviewItems" ng-repeat="item in items">{{item}}</div></div>';
};
});
myNgApp.directive('showPreview', function ($compile) {
return {
scope: true,
link: function (scope, element, attrs) {
var el;
attrs.$observe('template', function (tpl) {
if (angular.isDefined(tpl)) {
// compile the provided template against the current scope
el = $compile(tpl)(scope);
// stupid way of emptying the element
element.html("");
// add the template content
element.append(el);
}
});
}
};
});
myNgApp.controller('myPreviewController', function ($scope, myPreviewDataService, myPreviewTplService) {
//$scope.showContent = function () {
$scope.items = myPreviewDataService($scope.mySelItems);
$scope.template = myPreviewTplService();
//};
});
here $scope.mySelItems is from ng grid controller that gets updated when we select a checkbox.
What I get is an array but I am unable to read its content, when I display the array as it is it gets displayed like ["test"] but when I try to read it x[0] in myPreviewDataService factory or by $scope.mySelItems[0] in myPreviewController then I get blank. I am not able to figure out why this is happening

I was able to solve it. In myPreviewDataService factory I changed the array elements from string to array
var arr = [x, "Apple", "Banana", "Orange"];
changed to
var arr = [x, ["Apple"], ["Banana"], ["Orange"]];
and in myPreviewTplService factory I changed {{item}} to {{item[0]}}
it worked.
P.S I think we can also use ng switch based on condition in myPreviewTplService factory based on the type of item, I tried to do it but I was not able to do so and worked with my earlier solution.

Related

setting a editableCellCondition in a ui-grid inside an angular 1.5 component

I am trying to set rows editable/not editable based on a flag in the data.
I can get this working outside an angular 1.5 component, but can't seem to access row.entity inside a controller in a component.
function memberDisplayCtrl ($scope, memberFactory,uiGridConstants) {
var ctrl = this;
ctrl.people = memberFactory.getMembers();
ctrl.checkStatus = function(ctrl){
// How do I do something like this:
// if (ctrl.row.entity.Status === 'Y') { return 'true'; } else {return 'false';}
};
ctrl.gridOptions = {
enableSorting: true,
enableCellEdit:false,
cellEditableCondition: ctrl.checkStatus(ctrl),
enableHorizontalScrollbar : 0,
enableVerticalScrollbar : 0,
enableColumnMenus: false,
minRowsToShow: ctrl.people.length,
columnDefs: [
{ displayName:'First Name', name: 'fname', enableCellEdit:true },
{ displayName:'Last Name', name: 'lname', enableCellEdit:true },
{ displayName:'Date of Birth', name: 'DOB', type:'date', enableCellEdit:true, cellFilter: 'date:"yyyy-MM-dd"'},
{ displayName:'Address', name: 'address', enableCellEdit:true},
{ displayName:'Status',name: 'Status', enableCellEdit: true}
],
data : ctrl.people
};
}
I'm pretty sure I have a scope problem but can't seem to figure it out. How do I access row.entity? I have an isolated scope inside my controller (since it is part of a component)
plunker here: https://plnkr.co/edit/Wz7gKs
Thanks
just pass a function to cellEditableCondition instead of executing it:
cellEditableCondition: ctrl.checkStatus
and note, that parameter received by that function is not current controller's this (aliased in your case as ctrl), but ui-grid's scope, so I renamed ctrl to scope:
function memberDisplayCtrl ($scope, memberFactory,uiGridConstants) {
var ctrl = this;
ctrl.people = memberFactory.getMembers();
ctrl.checkStatus = function(scope) {
return scope.row.entity.Status === 'Y'
};
ctrl.gridOptions = {
enableSorting: true,
enableCellEdit:false,
cellEditableCondition: ctrl.checkStatus,
enableHorizontalScrollbar : 0,
enableVerticalScrollbar : 0,
enableColumnMenus: false,
minRowsToShow: ctrl.people.length,
columnDefs: [
{ displayName:'First Name', name: 'fname', enableCellEdit:true },
{ displayName:'Last Name', name: 'lname', enableCellEdit:true },
{ displayName:'Date of Birth', name: 'DOB', type:'date', enableCellEdit:true, cellFilter: 'date:"yyyy-MM-dd"'},
{ displayName:'Address', name: 'address', enableCellEdit:true},
{ displayName:'Status',name: 'Status', enableCellEdit: true}
],
data : ctrl.people
};
}
also, I see your commented code:
if (ctrl.row.entity.Status === 'Y') {
return 'true';
}
else {
return 'false';
}
here you intend to return string variable in both cases which will always evaluated as boolean true, you should return boolean:
if (ctrl.row.entity.Status === 'Y') {
return true;
}
else {
return false;
}
which is equal to much shorter version:
return ctrl.row.entity.Status === 'Y';
plunker: https://plnkr.co/edit/KXbJ40?p=preview

ui.grid data displayed is the same on each row

I am using a cell template for each row in my data grid. If I qualify the json object with an index then the value appears correctly but of course it is the same for each row. If I remove the index, then all rows are displayed with the same value but the value is an array.
---the js file
(function() {
angular.module('xxxSurvey').controller('EditxxxSurveyController', EditxxxSurveyController);
EditxxxSurveyController.$inject = ['$scope', 'UserFacilityListService', 'xxxSurveyService'];
function EditxxxSurveyController($scope, UserFacilityListService, xxxSurveyService) {
$scope.dataLoaded = false;
$scope.currentPage = 1;
$scope.pageSize = 10;
// test ui-grid setup
$scope.dataLoaded = true;
$scope.editWorksheetOptions = {
enableSorting: true,
columnDefs: [
{
name: 'all', field: 'MasterPatientId', width: 40,
enableSorting: false, enableColumnMenu: false, pinnedLeft: true,
//cellTemplate: '<input type="checkbox" id="i{{COL_FIELD}}">'
cellTemplate: '<div class="ui-grid-cell-contents">{{grid.appScope.worksheetInfo.MasterProviderId}}</div>'
},
{name: 'residentName', field: 'residentName', minWidth: 90, pinnedLeft: true,
cellTemplate: '<div class="ui-grid-cell-contents">{{grid.appScope.editWorksheetOptions.data[0].ResidentNameLast}}</div>'
},
{name: 'residentRoom', field: 'residentRoom', width: 90, pinnedLeft: true},
{name: 'status', field: 'status', width: 90},
],
data: []
};
$scope.$on('FacilitySelected', function() {
if (UserFacilityListService.getSelectedFacility()) {
$scope.selectedFacility = UserFacilityListService.getSelectedFacility();
}
var promise = xxxSurveyService.getCurrentWorksheet($scope.selectedFacility.MasterProviderId);
promise.then(
function(payload) {
if (payload !== null) {
$scope.worksheetInfo = payload.worksheetInfo;
$scope.editWorksheetOptions.data = payload.residentData;
}
}
);
});
}
})();
--the json data
[{"AssessmentId":1,"WorksheetId":4,"MasterPatientId":1,"ResidentNameFirst":"xx","ResidentNameMiddle":"^","ResidentNameLast":"zzz","ResidentNameSuffix":"^"},
{"AssessmentId":2,"WorksheetId":2,"MasterPatientId":2,"ResidentNameFirst":null,"ResidentNameMiddle":null,"ResidentNameLast":null,"ResidentNameSuffix":null}]
--the html div id="editWorksheetGrid" ui-grid="editWorksheetOptions" class="grid" ui-grid-pinning>
i had same issue. For me it was rowIdentity problem.
Define following in your controller.
$scope.gridOptions.rowIdentity = function (row) {
return row.ID; //make sure ID is unique.
};
This fixed my problem.
Thanks

returning json object in a modal to a grid and editing it in Angularjs

I constructed a ui grid which has a column for editing, the grid information is populated by a json. Upon clicking the edit column a modal is opened. I want the user to be able to edit the row it clicked. So far I was able to return the entire json object to the modal, but I'm having trouble understanding how to turn that object into just the row I want to edit. I have a variable named ClickedRow which returns the $$hashkey id but I'm not sure how to access it. I tried a forEach utility but it's not working. I am new to angularjs can anyone help me
This is my controller:
import {safeApply} from 'ems';
import modalTemplate from './modal/modal.html';
import controller from './modal/modal.controller.js';
class AssetsController {
/* #ngInject */
constructor(AssetsService, $uibModal, $state) {
this.label = 'Assets Controller !!';
this.assetsService = AssetsService;
this.assetModal= $uibModal;
this.$state = $state;
var assetsData;
var clickedRow;
this.assetsService.resolvePromise().then((response) => {
this.gridOptions.data = response;
assetsData = this.gridOptions.data;
//console.log(response);
safeApply();
});
this.modalOptions ={
template: modalTemplate,
controller: controller,
size: 'large',
backdrop: false,
resolve: {
assetData: function(){
console.log('number 2'+clickedRow);
return [clickedRow, assetsData];
}
}
};
this.myAppScopeProvider ={
modal: this.assetModal,
modalOptions: this.modalOptions,
open:function(row){
console.log('number 1'+row);
clickedRow = row;
this.modal.open(this.modalOptions)
}
};
this.initialize();
}
initialize() {
this.gridOptions = {
paginationPageSizes: [15, 30, 45],
paginationPageSize: 9,
rowHeight: 50,
enableRowSelection: true,
enableRowHeaderSelection: false,
multiSelect: false,
enableColumnResizing: true,
enableSelectAll: false,
noUnselect: true,
columnDefs: [
{
field: 'Thumbnail',
displayName: '',
width: 100,
cellTemplate: '<span class="glyphicon glyphicon-picture" aria-hidden="true"></span>'
},
{
field: 'File Name',
displayName: 'File Name',
cellClass:'blue',
width: 100
},
{
field: 'Description_',
displayName: 'Description',
minWidth: 150
},
{
field: 'Edit_',
displayName: 'Edit',
cellTemplate: '<button class="btn btn-link pull-right" ng-click="grid.appScope.open(row)">Edit</button>',
cellClass:'blue',
width: 100
},
{ field: 'Uploaded_Date', displayName: 'Upload Date'},
{ field: 'Uploaded_By'},
{ field: 'File_Size' },
{ field: 'File_Source'},
{ field: 'In_Use'},
{
field: 'Lock_Status',
displayName: '',
cellClass:'black',
cellTemplate: '<span class="glyphicon glyphicon-lock" aria-hidden="true">'
}
],
onRegisterApi:function (gridApi) {
this.gridApi = gridApi;
},
appScopeProvider: this.myAppScopeProvider,
rowTemplate:''
};
}
}
export default AssetsController;
class ModalController {
/* #ngInject */
constructor($scope, $uibModalInstance, assetData) {
this.label = 'Modal Controller !!';
this.scope = $scope;
this.scope.assetData = assetData;
}
initialize() {
/* this.modalService.resolvePromise().then((response) => {
this.data = response.data;
});*/
}
}
export default ModalController;
Pass row.entity as parameter to your open method:
<button class="btn btn-link pull-right" ng-click="grid.appScope.open(row.entity)">Edit</button>
You'll need to declare your resolve object in your open method so you can pass entity directly:
open: function (entity) {
this.modalOptions.resolve = {
entity: entity
}
this.modal.open(this.modalOptions)
}
Inject entity into your modal controller and you're good to go
Here's a working example on Plunker: http://plnkr.co/edit/Agvcc6CZFBvQQLRpQeRk?p=preview

How to share code in angular js (concept of code resuability in angular js?

i am new to angular js and i want to share and make certain codes reusable. i have tried to do that using services and factory. But i am getting error.
'use strict';
angular.module('myApp.ctrls')
.controller('Ctrl_HubStockOnHandMode', function($http, $scope, reportService) {
$scope.HubStockOnHandModeGridOptions = {
dataSource: {
type: "jsonp",
transport: {
read: function(e) {
reportService.WebAPI('abc/BIUMo', {
EnvironmentCode:'JMVH',
OrderBy: getOrderBy(e.data.sort)
}).then(function (d) {
$scope.data = d;
e.success(d.Data);
});
}
},
serverPaging: true,
serverSorting: true
},
height:config.GridHeight,
scrollable:true,
sortable: {
mode: "single",
allowUnsort: true
},
filterable: {
extra: false,
operators: {
string: {
startswith: "Starts with",
eq: "Is equal to",
neq: "Is not equal to",
contains: "Contains"
}
}
},
pageable: false,
columns: [
{
field: "RowNumber"
,title: "No."
,width: "50px"
,sortable:false
,filterable: false
},
{
field: 'ItemCTSH'
,title:'Item'
,template: "<div kendo-tooltip title='#= ItemCT #' > #= ItemCTSH # </div>"
,filterable: {
ui: itemFilter
}
},
]
};
}
//Get Item List
$http.get('http://webapi.dashboard.hcmisonline.org/api/OID_WebApi/IssuedItemList')
.success(function (data) {
$scope.items = data.Data;
});
function itemFilter(element) {
element.kendoAutoComplete({
dataSource: $scope.items
});
}
}
});
I want to reuse the functions like the Get item. i have other pages/grids that use exactly this code, except changing the environment code
how to i solve this issue?
thanks

Kendo UI Grid foreign key column using Angular directives

I'm trying to make a Kendo Grid that has 2 foreign key columns using the Angular directives for Kendo. I am able to get one to work, but not the other (independent of each other). If I comment one out the other will work and vice versa, but either way only one will work. Abbreviated sample code is below.
invoicesController.js
app.controller('invoicesController', [
'$scope', '$rootScope', 'config', 'dataFactory', function($scope, $rootScope, config, dataFactory) {
$rootScope.title = 'Invoices';
$scope.filterCustomers = [];
$scope.filterStatuses = [];
$scope.invoiceGrid = null;
var _refreshCustomers = function () {
dataFactory.get(_.string.format('{0}customers', config.apiUrl)).success(function (result) {
$scope.filterCustomers = _.map(result, function (cust, key) {
return {
text: cust.name,
value: cust.id
}
});
});
};
var _refreshStatuses = function() {
dataFactory.get(_.string.format('{0}invoicestatuses', config.apiUrl)).success(function(result) {
$scope.filterStatuses = _.map(result.data, function(status, key) {
return {
text: status.name,
value: status.id
}
});
_initializeGrid();
});
};
var _refreshData = function () {
_refreshCustomers();
_refreshStatuses();
};
_refreshData();
var _initializeGrid = function() {
$scope.invoiceGrid = {
dataSource: {
transport: {
read: _.string.format('{0}invoices', config.apiUrl),
},
schema: {
data: 'data'
},
pageSize: 15,
sort: { field: 'invoiceDate', dir: 'asc' }
},
columns: [
{ title: 'Subject', field: 'subject', type: 'string', width: '30%'},
{ title: 'Number', field: 'number', width: '12%' },
{ title: 'Customer', field: 'customer.id', values: $scope.filterCustomers, width: '15%' },
{ title: 'Status', field: 'status.id', values: $scope.filterStatuses, width: '14%' },
{ title: 'Total', field: 'invoiceTotal', type: 'number', format: '{0:c2}', width: '10%' },
{
title: 'Updated', field: 'updatedOn', type: 'date', format: '{0:d}', width: '19%',
template: '#=lastUpdated#'
}
],
scrollable: false,
sortable: true,
filterable: true,
pageable: true
};
}
}
]);
dataFactory.js (GET method)
return $http({
url: url,
method: 'GET',
data: data,
});
list.html
<div data-kendo-grid data-k-ng-delay="invoiceGrid" data-k-options="invoiceGrid" class="top"></div>
I was able to get this to work using route resolve.
Basically, when you're defining your routes, you can set resolvers. In this case, I'm resolving customers and statuses which you will also see as arguments on the projectsController
app.js (routing config)
// Projects
$routeProvider.when('/projects', {
templateUrl: '/app/views/projects/list.html',
controller: 'projectsController',
resolve: {
customers: ['customerService', function (customerService) {
return customerService.getCustomers();
}],
statuses: ['projectService', function (projectService) {
return projectService.getStatuses();
}]
}
});
projectsController.js (abbreviated)
app.controller('projectsController', [
'$scope', '$rootScope', 'config', 'customers', 'statuses', function($scope, $rootScope, config, customers, statuses) {
// Set the options from the injected statuses (from the route resolver)
$scope.statusOptions = _.map(statuses.data.data, function(status) {
return { value: status.id, text: status.name }
});
....
// Kendo grid column definition
columns: [
{ title: 'Status', field: 'status.id', values: $scope.statusOptions, width: '15%' },
]
}]);

Resources