Get selected row of angularjs ui-grid - angularjs

I've looked at multiple articles on this ui-grid and its giving me fits. I'm trying to get the selected row object. I'm either getting an undefined or can not read property of 'getSelectedRows'. Any help is greatly appreciated.
I started with this article here and the documentation doesnt seem to be all that great either.
Here is my code:
vm.gridOptions = {
enableRowSelection: false,
enableSelectAll: false,
showGridFooter:true
};
vm.gridOptions.columnDefs = [
{ name: 'productName' },
{ name: 'unitPrice' }
];
vm.gridOptions.multiSelect = false;
vm.getSelectedRows = function () {
vm.mySelectedRows = vm.gridApi.selection.getSelectedRows();
}
productDataService.getProductList()
.then(function (result) {
vm.gridOptions.data = result.data;
vm.mySelectedRows = vm.gridApi.selection.getSelectedRows();<--Property undefined error here
$timeout(function() {
if (vm.gridApi.selection.selectedRow) {
vm.gridApi.selection.selectRow(vm.gridOptions.data[0]);
}
});
});
vm.gridOptions.onRegisterApi = function(gridApi) {
vm.gridApi = gridApi;
}

Hope this helps:
angular.module('app', ['ui.grid', 'ui.grid.selection'])
.controller('MainCtrl', ['$scope', '$timeout', function($scope, $timeout) {
var vm = this;
vm.gridOptions = {
enableRowSelection: false,
enableSelectAll: false,
showGridFooter:true,
data: [{productName: "Moroni", unitPrice: 50},
{productName: "Tiancum", unitPrice: 43},
{productName: "Jacob", unitPrice: 27},
{productName: "Nephi", unitPrice: 29},
{productName: "Enos", unitPrice: 34}]
};
vm.gridOptions.columnDefs = [
{ name: 'productName' },
{ name: 'unitPrice' }
];
vm.gridOptions.multiSelect = false;
vm.getSelectedRows = function () {
vm.mySelectedRows = vm.gridApi.selection.getSelectedRows();
}
vm.getProductList = function() {
vm.gridOptions.data = vm.resultSimulatedData;
vm.mySelectedRows = vm.gridApi.selection.getSelectedRows(); //<--Property undefined error here
if (vm.mySelectedRows[0]) {
alert('Selected Row: ' + vm.mySelectedRows[0].productName + ', ' + vm.mySelectedRows[0].unitPrice + '.');
} else {
alert('Select a row first');
}
$timeout(function() {
if (vm.gridApi.selection.selectedRow) {
vm.gridApi.selection.selectRow(vm.gridOptions.data[0]);
}
});
};
vm.gridOptions.onRegisterApi = function(gridApi) {
vm.gridApi = gridApi;
};
vm.resultSimulatedData = [{productName: "Moroni1", unitPrice: 50},
{productName: "Tiancum1", unitPrice: 43},
{productName: "Jacob1", unitPrice: 27},
{productName: "Nephi1", unitPrice: 29},
{productName: "Enos1", unitPrice: 34}];
return vm;
}]);
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-grid/4.0.2/ui-grid.min.js"></script>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/angular-ui-grid/4.0.2/ui-grid.min.css" />
<div ng-app="app" ng-controller="MainCtrl as vm">
<button ng-click="vm.getProductList()">Get Product List</button>
<div ui-grid="vm.gridOptions" ui-grid-selection class="gridStyle">
</div>
</div>
If you can share more of your code that might help me to further help you.

If you want to filter out and select a column from the selected row(s), you can run a small loop and filter the value which you require as follows:
$scope.Grid.onRegisterApi = function (gridApi) { $scope.Grid= gridApi; };
Then to a button outside the grid you can add the following method to it's ng-click event.
$scope.DoSomthing= function () {
var rows = $scope.Grid.selection.getSelectedRows();
angular.forEach(rows, function (row, key) {
angular.forEach(row, function (column, colKey) {
if (colKey == "Your Column binding string")
{
console.log(column);
}
});
});
Then probably you can create an array of the column values and use where ever you need it.
I hope this helps to anyone looking for a similar functionality !

The most easy way to get current "clicked, changed" and whatever event want is to add a cell template like this in gridOptions:
vm.gridOptions = {
enableColumnMenus: false,
enableHorizontalScrollbar: 0,
enableVerticalScrollbar: 0,
enableRowSelection: false,
enableRowHeaderSelection: false,
rowHeight: 30,
multiSelect: false,
appScopeProvider: vm,
onRegisterApi: function(gridApi) {
vm.gridApi = gridApi;
},
columnDefs: [{
{
displayName: "",
field: "delete",
enableSorting: false,
width: "80",
cellTemplate: '<div class="ui-grid-cell-contents"><span class="grid-cell-icon fa fa-trash" ng-click="grid.appScope.vm.deleteRowModal(row.entity)"></span></div>'
}
...
]
}
So row.entity is pass data from row in controller!
If you want to show grid data value from JSON and not delete icon like it is in this case put {{COL_FIELD}}
Hope now everybody can take values from cliked row from ui-grid.

Related

Keep selection after ui-grid data refresh

I am using ui-grid in my web application.
Everything is working fine, the issue is when I refresh the grid data the selection gets removed.
In the Fiddle when I select a row and then hit the refresh the button the ui-grid selection gets removed.
JSFiddle: http://jsfiddle.net/mdawood1991/xyuotpe8/6/
HTML:
<div ng-controller="MyCtrl as controller">
<button ng-click="controller.refreshData()" type="button">
Refresh
</button>
<div ui-grid="controller.assetListGrid" ui-grid-selection></div>
</div>
Controller:
var myApp = angular.module('myApp', ["ui.grid", "ui.grid.selection"]);
//myApp.directive('myDirective', function() {});
//myApp.factory('myService', function() {});
myApp.controller("MyCtrl", function($scope) {
var self = this;
$scope.name = 'Superhero';
self.assetListGrid = {};
self.gridOptions = {
enableFiltering: true,
enableGridMenu: true,ang
enableColumnMenus: false,
enableRowSelection: true,
enableSelectAll: false,
multiSelect: false,
enableHorizontalScrollbar: 1,
columnDefs: [{
name: 'assetId'
}, {
name: 'reference',
enableHiding: false,
width: 250,
resizeable: true
}],
onRegisterApi: function(gridApi) {
self.assetGridObject = gridApi;
// register the onRowSelect Function here
//this.assetGridObject.selection.on.rowSelectionChanged(null, function(row) {
// if (row.isSelected)
// });
},
appScopeProvider: self
}
self.initGrid = function() {
self.assetListGrid = self.gridOptions;
self.assetListGrid.data = "controller.gridAssets"
}
self.loadInitData = function() {
self.gridAssets = [{
assetId: 1,
reference: "Dawood"
}, {
assetId: 2,
reference: "Dawood 2"
}, {
assetId: 3,
reference: "Dawood 3"
}, {
assetId: 4,
reference: "Dawood 4"
}, ]
}
self.refreshData = function() {
console.log("Data refresh")
self.gridAssets = [{
assetId: 1,
reference: "Refresh"
}, {
assetId: 2,
reference: "Refresh 2"
}, {
assetId: 3,
reference: "Refresh 3"
}, {
assetId: 4,
reference: "Refresh 4"
}, ]
}
self.initGrid();
self.loadInitData();
});
How do I keep the selection?
Seems like I have found a solution:
What I did was first I put the selected row inside a temporary object, when the row is selected
onRegisterApi: function(gridApi) {
self.assetGridObject = gridApi;
// register the onRowSelect Function here
self.assetGridObject.selection.on.rowSelectionChanged(null, function(row) {
if (row.isSelected) {
self.assetGridObject.grid.appScope.selectedRow = row.entity;
}
});
},
FIDDLE: http://jsfiddle.net/mdawood1991/02dpggyo/2/
Then when the data is refreshed I am checking if a row is selected or not, if it a row is selected I am getting the latest value of that row from the Array of new data, this what the refresh data method looks like now:
self.refreshData = function() {
console.log("Data refresh")
self.gridAssets =
[
{assetId: 1,reference: "Refresh 1"},
{assetId: 2,reference: "Refresh 2"},
{assetId: 3,reference: "Refresh 3"},
{assetId: 4,reference: "Refresh 4"}];
if (self.selectedRow)
{
console.log("Row is selected");
//THIS LINE HERE I THINK IS THE KEY -
self.assetGridObject.grid.modifyRows(self.gridAssets);
// GET THE ROW FROM NEWLY LOADED DATA
var selectedRoww = null;
for (var i = 0; i < self.gridAssets.length; i++)
{
//COMPARING BASED ON MY asseId AS THIS IS THE VALUE THAT WILL NOT CHANGE IN MY GRID - OTHER COLUMS CAN CHANGE
if (self.gridAssets[i].assetId == self.selectedRow.assetId)
{
selectedRoww = self.gridAssets[i];
}
}
// THIS LINE HERE IS SELECTING THE ROW FROM THE GRID
self.assetGridObject.selection.selectRow(selectedRoww);
}
}

how to get a particular location on google maps with markers from a angular dropdown list

I am trying to do some location search on google maps,its like i am having a angular multi-select drop-down where i am having several locations, if i select a single location or more ,i have to show them on maps using markers,and how to get our current location any suggestions on how to do it please.
Dropdown code
<div class="m-r"
ng-dropdown-multiselect=""
options="locations"
selected-model="search.locations"
extra-settings="multiSelectSettingsFunction"
translation-texts ="locationsTexts"
settings="selectSettings">
</div>
Google maps code
<ui-gmap-google-map center="map.center" refresh="true" zoom="map.zoom" draggable="true" data-tap-disabled="true">
<ui-gmap-window show="map.window.show" coords="map.window.model" options="map.window.options" closeClick="map.window.closeClick()">
<div style="color: black" background-color="#337ab7">
{{map.window.title}}
{{map.window.venue}}
</div>
</ui-gmap-window>
<ui-gmap-markers idkey="marker.id" models="map.markers" coords="'self'" doCluster="false" fit="'true'" icon="'icon'" events="map.markersEvents " options="'options'"></ui-gmap-markers>
</ui-gmap-google-map>
controller.js
app.controller("MainController", [ '$anchorScroll', '$scope', '$http', '$modal', '$log', '$timeout', '$location', '$rootScope', '$window','$mdSidenav' , function ($anchorScroll, $scope, $http, $modal, $log, $timeout, $location, $rootScope, $window,$mdSidenav) {
$scope.searchBack = window.sessionStorage.searchBack;
$scope.search = {
pax: '',
data: '',
locations : [],
distance : []
}
$scope.$watch('search.locations', function(newVal, oldVal){
//console.log(newVal);
//$scope.setSearch();
}, true);
$scope.locationsTexts = {
buttonDefaultText: 'Locations',
dynamicButtonTextSuffix: 'Locations',
}
$scope.multiSelectSettings = {
displayProp: 'locations',
idProp: 'locations',
scrollableHeight: '256px',
scrollable: true,
enableSearch: true,
buttonDefaultText: 'asd',
dynamicButtonTextSuffix: 'Locations',
//showCheckAll: false,
};
$scope.locations = [
{id: 1, label: "kothapet"},
{id: 2, label: "Dsnr"},
{id: 3, label: "Malakpet"},
{id: 4, label: "Chadarghat"},
{id: 5, label: "Koti"},
{id: 6, label: "abids"}
];
Maps Controller
app.controller('MapController2', function($scope, $rootScope, $http) {
var data = {};
data.map = {
zoom: 16,
center: {
latitude: 17.399,
longitude: 78.52
},
markers: [
{
id: 1,
latitude: 17.3762,
longitude: 78.5461,
title: 'Location:Nagole',
venue:'Venue: Ng builders'
},
{
id: 2,
latitude: 17.3710,
longitude: 78.5410,
title: 'Location:Kothapet',
venue:'Venue: A Builders'
},
{
id: 3,
latitude: 17.3688,
longitude: 78.5247,
title: 'Location:Dilsukhnagar',
venue:'Venue: B Builders'
},
{
id: 4,
latitude: 17.3667,
longitude: 78.500,
title: 'Location:Malakpet',
venue:'Venue: C Builders'
}],
markersEvents: {
click: function(marker, eventName, model, arguments) {
console.log('Marker was clicked (' + marker + ', ' + eventName);//+', '+mydump(model, 0)+', '+mydump(arguments)+')');
$scope.map.window.model = model;
$scope.map.window.model = model;
$scope.map.window.title = model.title;
$scope.map.window.venue = model.venue;
$scope.map.window.show = true;
}
},
window: {
marker: {},
show: false,
closeClick: function() {
this.show = false;
},
options: {}, // define when map is ready
title: ''
}
};
//$scope.window = false;
$scope.onMarkerClicked = function (m) {
//this.windowOptions = !this.windowOptions;
console.log('Marker was clicked');
console.log(m);
};
$scope.closeClick = function () {
this.window = false;
};
$scope.map = data.map;
});
1) To resolve location by address name utilize Google Maps Geocoding API, for example:
var resolveAddress = function(address) {
var deffered = $q.defer();
$http({
url: 'http://maps.googleapis.com/maps/api/geocode/json?address=' + address + '&sensor=false',
method: 'GET'
}).
success(function(data) {
deffered.resolve(data);
}).
error(function(error) {
deffered.reject();
});
return deffered.promise;
};
2) For angularjs-dropdown-multiselect component you could utilize events to add events what the directive fires, for example onItemSelect which triggers once the item is selected:
<div class="m-r"
ng-dropdown-multiselect=""
options="locations"
selected-model="search.locations"
translation-texts="locationsTexts"
settings="selectSettings"
events="{ onItemSelect: showItemOnMap }">
</div>
$scope.showItemOnMap = function(item) {
//...
};
The following demo demonstrates how to display markers on map from items selected in angularjs-dropdown-multiselect control
Demo

How to evaluate a filter string programmatically in an Angular expression

I'm trying to evaluate filters programmatically within an Angular expression in a template.
HTML:
<div ng-app="myApp">
<div ng-controller = "MyCtrl">
<div ng-grid="gridOptions" class="gridStyle"></div>
</div>
</div>
JS:
var app = angular.module('myApp', ['ngGrid']);
app.controller('MyCtrl', function ($scope) {
$scope.myData = [{name: "Moroni", age: 50},
{name: "Tiancum", age: 43},
{name: "Jacob", age: 43},
{name: "Nephi", age: 29},
{name: "Enos", age: 34}];
$scope.gridOptions = {
data: 'myData',
columnDefs: [{ field: "name", },
{ field: "age", cellTemplate: '<div><div>{{row.getProperty(col.field) | col.colDef.filter}}</div></div>', cellFilter: 'test' }],
};
});
app.filter('test', function () {
return function (input) {
return input + '!';
};
});
CSS:
.gridStyle {
border: 1px solid rgb(212, 212, 212);
width: 100%;
height: 500px;
}
As you can see, in the cellTemplate for the 'age' column, I'm trying to pass through the cell data through a filter that is in a string in my column definitions (col.colDef.filter).
Is this possible?
I want to do this because I want to use just one template but define a variety of filters on each of the columns.
http://jsfiddle.net/GWha8/2/
How about simply adding test as the filter instead of getting the col's:
{{row.getProperty(col.field) | test}}
Updated jsfiddle.
The gridOption id you should be using is cellFilter (not filter). If you are not doing any other formatting that would require a cellTemplate all you need to do it set $scope.gridOptions.columnDefs[1].cellFilter = 'test' like this:
$scope.gridOptions = {
data: 'myData',
columnDefs: [
{
field: "name"
},
{
field: "age",
cellFilter: 'test'
}
]
};
However, if you are do need to do other changes that will require a cellTemplate then you can just reference your filter by name right in the template (no need to define $scope.gridOptions.columnDefs[1].cellFilter) like this:
$scope.gridOptions = {
data: 'myData',
columnDefs: [
{
field: "name"
},
{
field: "age",
cellTemplate: '<div class="ngCellText" ng-class="col.colIndex()">{{COL_FIELD | test}}</div>''
}
]
};
1) you can fix this in ng grid sources inside ngColumn, and use column cellFilter
if (colDef.cellTemplate && !TEMPLATE_REGEXP.test(colDef.cellTemplate)) {
self.cellTemplate = $.ajax({
type: "GET",
url: colDef.cellTemplate,
async: false
}).responseText;
}
self.cellTemplate = self.cellTemplate.replace(CUSTOM_FILTERS, self.cellFilter ? "|" + self.cellFilter : "");
2) you can create custom function which accept filter and return string
function getTemplateFilter(test){
return '<div><div>{{row.getProperty(col.field) | '+ test +'}}</div></div>'
}

How can I get my ng-grid to re-sort itself?

I have some data displayed in an ng-grid.
Some of this data is displayed nearly immediately after the page loads; other data is slower and we stitch it in once it's received.
In doing this, sorting can break if the grid is set to sort data that isn't there when the first half of the data is rendered in the grid.
Is there a nice way to tell the grid to re-sort itself and preserve multiple columns as well as sort directions once all of the data has been received?
JS
var app = angular.module('myApp', ['ngGrid']);
app.controller('MyCtrl', function ($scope) {
$scope.myData = [{name: "Moroni", age: 50},
{name: "Tiancum", age: 43},
{name: "Jacob", age: 43},
{name: "Nephi", age: 29},
{name: "Enos", age: 34}];
$scope.gridOptions = {
data: 'myData',
columnDefs: [{ field: "name", },
{ field: "age" },
{ field: "state" }],
sortInfo: {
fields: [ 'age', 'state' ],
directions: [ 'asc', 'desc' ]
}
};
var lateData = [
{ name: 'Moroni', state: 'NY' },
{ name: 'Tiancum', state: 'CA' },
{ name: 'Jacob', state: 'PA' },
{ name: 'Nephi', state: 'AK' },
{ name: 'Enos', state: 'MO' }
];
setTimeout(function () {
$scope.myData = _.merge($scope.myData, lateData);
$scope.$digest();
}, 3000);
});
HTML
<div ng-app="myApp">
<div ng-controller = "MyCtrl">
<div ng-grid="gridOptions" class="gridStyle"></div>
</div>
</div>
CSS
.gridStyle {
border: 1px solid rgb(212, 212, 212);
width: 100%;
height: 500px;
}
http://jsfiddle.net/akukucka/4vrQq/
Not sure if this is what you wanted:
$scope.resort= function(){
$scope.gridOptions.sortBy('age');
};
Plunker is here
Since I don't have any of your code you have to find a place where/when to do the sorting for yourself.

How to do client-side pagination with ngGrid?

If you set the enablePaging options of an ng-grid to true, you enable server-side pagination.
What about client-side one? I could not find any hint on this in the documentation, but I can not imagine that ng-grid does not support client-side paging as well.
Any hint?
I think the example given on the angular page (http://angular-ui.github.io/ng-grid/) actually shows an example of client-side paging. If you look at the data load that is being called by the sample script (http://angular-ui.github.io/ng-grid/jsonFiles/largeLoad.json), you'll see that its not actually doing any server-side paging... it's coming down as one big file.
It might help you!!
The AngularJs code-sample
var app = angular.module('myApp', ['ngGrid']);
app.controller('MyCtrl', function($scope, $http) {
$scope.filterOptions = {
filterText: ""
};
$scope.pagingOptions = {
pageSizes: [25, 50, 100],
pageSize: 25,
totalServerItems: 0,
currentPage: 1
};
$scope.setPagingData = function(data, page, pageSize) {
var pagedData = data.slice((page - 1) * pageSize, page * pageSize);
$scope.myData = pagedData;
$scope.pagingOptions.totalServerItems = data.length;
if (!$scope.$$phase) {
$scope.$apply();
}
};
$scope.getPagedDataAsync = function(pageSize, page) {
setTimeout(function() {
$http.get('json').success(function(largeLoad) {
$scope.setPagingData(largeLoad, page, pageSize);
});
}, 100);
};
$scope.$watch('pagingOptions', function() {
$scope.getPagedDataAsync($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage, $scope.filterOptions.filterText);
}, true);
$scope.gridOptions = {
data: 'myData',
enablePaging: true,
pagingOptions: $scope.pagingOptions,
showFooter: true
};
$scope.gridOptions.columnDefs = 'gridColumnDefs';
// city loc pop state
$scope.gridColumnDefs = [{
field: "city"
},
{
field: "state"
}, {
field: "pop"
}, {
field: "loc"
}
];
});
The HTML code-sample
<div ng-app="myApp" ng-controller="MyCtrl">
<div class="gridStyle" ng-grid="gridOptions"></div>
</div>

Resources