Cannot detect row selection in ui.grid - angularjs

I have an angular ui grid working with selection, I want to populate a form with the contents of the selected record. I see no way to either reference the selected record or detect that row selection has occurred. Any ideas?

With ui-grid the api is a little different than the ng-grid example Aidan posted.
Normally you'd listen to the rowSelectionChanged event, refer: http://ui-grid.info/docs/#/api/ui.grid.selection.api:PublicApi
This would look something like the following:
$scope.selectionChanged = function( rowChanged ) {
if( rowChanged.isSelected ){
$scope.targetRow = rowChanged;
}
};
gridOptions = {
// other stuff
onRegisterApi: function(gridApi) {
$scope.gridApi = gridApi;
$scope.gridApi.selection.on.rowSelectionChanged($scope, $scope.selectionChanged);
}
};
You should then be able to use $scope.targetRow as the target for your form. You'll probably need to turn off multiselect (check the selection gridOptions, or the selection tutorial), and deal with what happens when no row is selected.
In my application I tend to do the form as a popup (a modal or a separate page). When I do that it's much simpler, I just do a click event on the row itself, or (more commonly) a button on the row. Refer perhaps to http://ui-grid.info/docs/#/tutorial/305_appScope for an example. You can pass the row that was clicked upon into that click handler:
cellTemplate:'<button ng-click="grid.appScope.openModal( row.entity )">Edit</button>' }
You can then pass the entity (which would be an ngResource) into that modal, and once it edits it then it can just call save on the resource when it's done.
I did something similar to this in my (ng-grid based) tutorial series: https://technpol.wordpress.com/2013/11/09/angularjs-and-rails-4-crud-application-using-ng-boilerplate-and-twitter-bootstrap-3-tutorial-index/

It is customary to post what you have tried, please consider this in future. Here is a short sample that utilises the afterSelectionChange event for the ng-grid:
A grid with two divs to hold the selected data:
<div class='gridStyle' ng-grid='testGridOptions'></div>
<div>{{current.name}}</div>
<div>{{current.age}}</div>
some test data:
$scope.testData = [{name:'John', age:25},
{name:'Mary', age:30},
{name:'Fred', age:10},
{name:'Joan', age:20}];
configuration for the grid:
$scope.testGridOptions = {
data: 'testData',
multiSelect: false,
afterSelectionChange: function(data){
$scope.current = data.entity;
}
};
Hope this gets you started.
Aidan

Related

How to prevent Kendo MultiSelect from losing values after editing in a grid template?

I have a grid that displays a comma-separated list of values, and it has an array that gets used in a template editor for the grid. (On the server, I transform the comma-separated list to an array for the Kendo multiselect AngularJS directive). I have almost everything working: display, edit, and adding values in the multiselect.
There's just one weird thing happening: after I add a value in the multiselect, click Save in the editor, and reopen the editor, the multiselect then only displays one of the most-recently entered values. I know that the values are there and going through the pipeline, because the values make it into the database. I can refresh the page, open the editor, and all the values display in the multiselect correctly, including the one I just added.
It's as if kendo "forgets" most of the values when I reopen the editor. How can this be prevented? Does the MultiSelect need to be rebound to the values? If so, how?
I have tried adding this onChange event, but it had no effect. I've added valuePrimitive to no effect. I tried specifying k-rebind, but it caused an error.
Here's the directive being used in the text/x-kendo-template:
<select kendo-multi-select
id="zipCode"
k-placeholder="'Enter zip codes...'"
style="width: 225px"
k-on-change="dataItem.dirty=true"
k-auto-bind="false"
k-min-length="3"
k-enforce-min-length="true"
k-data-source="options.zipCodeDataSource"
k-data-text-field="'text'"
k-filter="'startsWith'"
k-filtering="options.zipCodeFiltering"
k-no-data-template="'...'"
k-ng-model="dataItem.zipArray"
k-highlight-first="true" />
And this is the DataSource:
options.zipCodeDataSource = new kendo.data.DataSource({
severFiltering: true,
transport: {
read: {
url: serviceUrl + "ZipCode/Get",
type: "GET",
dataType: "json",
contentType: jsonType,
data: function (e) {
// get your widget.
let widget = $('#zipCode').data('kendoMultiSelect');
// get the text input
let filter = widget.input.val();
// what you return here will be in the query string
return {
filter: filter
};
}
},
},
schema: {
data: "data",
total: "Count",
model:
{
id: "text",
fields: {
text: { editable: false, defaultValue: 0 },
}
},
parse: function (response) {
return response;
}
},
error: function (e) {
}
});
If I display {{dataItem.zipArray}} in a <pre> all of the expected values are there.
I wonder if something needs to be added to the edit event handler in the kendo grid definition, but I'm not sure what it would be. I've had to do binding like that for the dropdownlist directive.
edit: function (e) {
if (e.model.marketId === 0) {
e.container.kendoWindow("title", "Add");
} else {
e.container.kendoWindow("title", "Edit");
}
// re-bind multi-select here??
// These two lines actually cause the multiselect to lose pre-existing items in dataItem.zipArray
// var multiselect = kendo.widgetInstance(angular.element('#zipCode'));
// multiselect.trigger('change');
}
...
Update:
This dojo demonstrates the issue.
Run the dojo
Edit the first record in the Contracts grid
Add a zip code such as 22250
Click Save
Then click Edit on the first row again
Only zip code 22250 is displayed in the editor
Also, I notice that if I change k-min-length="3" to k-min-length="1", then the issue goes away. But in the scenario I'm working on, it needs to be 3.
This seems to be an issue with kendo itself. Back then this issue was reported here.
Ok based on the reply from telerik, this issue has been fixed in 2017 R3 SP1 release (2017.3.1018). You can verify it by using this updated dojo example:
http://dojo.telerik.com/IREVAXar/3

Programmatically selecting grid row does not fire itemclick event in ExtJS4

I am building an ExtJS4 Web Application and I have a "page" where I have a Grid whose records come from a database. After loading the store of the grid, I want the first item to be selected.
This is what I've tried so far:
store.load({
callback: function() {
if(store.count() > 0){
grid.getSelectionModel().select(0);
//grid.getView().select(0);
}
}
});
The store loads the database records properly as they're shown in my grid. The first row is also highlighted as if it was clicked. However, my listener/controller for the itemclick event isn't firing as opposed to when I manually click the row.
I've also tried grid.getView().select(0); as well as grid.getSelectionModel().selectFirstRow(); but apparently, both those aren't functions.
My grid row appears to be selected by the itemclick function isn't being called at all.
You should use 'selectionchange' listener in 'Ext.selection.Model' instead of 'itemclick' in grid class. This listener will be fired in both cases when rows are clicked in grid and rows are selected programmatically.
Probably the code will be like this:
Ext.create('Ext.grid.Panel', {
selModel: Ext.create('Ext.selection.Model', {
...
listeners: {
selectionchange: function( this, selected, eOpts ) {
// Write your listener here or fire another event in view controller
}
}
}
store: ...
});

Angular UI-Grid: How to Clear All (general Angular and built-in UI-Grid) Column Filters On Button Click

How do I clear AND refresh ALL of my (general Angular and built-in UI-Grid) filters on a button click?
Background: I have built an application that uses the UI-Grid and takes advantage of the built-in filtering functionality. It also has a cross-column search written in angular.
Current Battle I want to be able to clear and refresh my filters on a single button click. So far I have been able to implement this for the cross-column search but have not been successful implementing it for the built-in column filters (which ironically I thought would be the easy part!).
Research Done On Problem:
1) Searched through the UI-Grid tutorials ... fail
2) Looked at the provided UI-Grid API ...partial success! Seems like I think I found what I'm looking for in the "clearAllFilters" function (here is the source code) but I cannot figure out how to implement it so onto step 3...
3) Googled like mad for implementation demos/examples/help/hints/anything!? ...fail
4) Asked for help on Stack Overflow :)
Thanks in advance.
Sorry, I didn't see the clearAllFilters() function of ui grid. So it becomes simpler. You can do this:
$scope.clearFilters = function() {
$scope.myGridApi.grid.clearAllFilters();
};
you can do this:
//get the grid api
$scope.myGridOptions.onRegisterApi = function(gridApi) {
$scope.myGridApi=gridApi;
}
You have to bind this function to your clear button :
$scope.clearFilters = function() {
var columns = $scope.myGridApi.grid.columns;
for (var i = 0; i < columns.length; i++) {
if (columns[i].enableFiltering) {
columns[i].filters[0].term='';
}
}
};
Please try this:
$scope.gridApi.core.clearAllFilters();
The $scope.gridApi was from the initial setting of my ui-grid element
$scope.gridOptions = {
flatEntityAccess: true,
paginationPageSizes: [10, 25, 50, 75, 100],
paginationPageSize: 25,
enableFiltering: true,
enableColumnResizing: true,
enableGridMenu: true,
onRegisterApi: function (gridApi) {
$scope.gridApi = gridApi;
},
columnDefs: [{
I think this is the simple way(just replacing the grid data with original/actual json data), you can simply create and call below clearFilters function on click of a button.
$scope.clearFilters = function() {
$scope.yourGridOptions.data = $scope.originalData;
}

Single Selection not working in Extjs Grid

This is how I set up my selection model for my grid :
var selM = Ext.create('Ext.selection.Model', {
mode: 'SINGLE',
toggleOnClick: true,
allowDeselect:true
});
And then in my table I add this as a configuration paramater :
var packageGrid = Ext.create('js.grid.MyGrid', {
selModel: selM
});
The MULTI selection is disabled, which is great. However now nothing remains selected. If I click on a row the highlighting disappears as soon as I move the mouse away.
This could be an extjs bug. I have tried the other parameter 'SIMPLE' as well.
Here is a fiddle which shows my problem :
http://jsfiddle.net/fgkb8yw5/1/
RowModel is the default so you can simply use:
selModel: {
mode: 'SINGLE'
}
Example: http://jsfiddle.net/8mra2het/1/
It's not a bug, Ext.selection.Model is the abstract class - which shouldn't be instantiated directly. Normally - when you specify the selModel declaratively, the grid component will implement one of the grid-context appropriate sub-classes:
Ext.selection.CellModel
Ext.selection.RowModel
I updated your fiddle using RowModel to demonstrate.

Persist selected rows the correct way

I'm trying to make use of ngGrid.
The list represents a bunch of items which the users then can select (or not). This selection should be persisted so when the user comes back the grid shows the same selected items as last time. I made a plunker
However I've run into a bit of a problem using ngGrid.
I'm using afterSelectionChange to save selection changes to the grid.
$scope.gridOptions = {
data: 'myData',
showSelectionCheckbox: true,
afterSelectionChange: function(rowItem, event) {
// $http... save selection state
}
};
Which is fine. However when I want to select rows programmatically when the page loads all hell breaks loose. The below code is supposed to select the row with the name Enos, and it does. But it triggers afterSelectionChange 4 times.
$scope.$on('ngGridEventData', function() {
angular.forEach($scope.myData, function(data, index) {
if (data.name == 'Enos') {
$scope.gridOptions.selectItem(index, true);
}
});
});
That can't be intended. I made a plunker.
How to persist selected rows using ngGrid?
Don't know why this is firing 4 Times, but it does not happen when you use selectedItems:
$scope.gridOptions = {
data: 'myData',
showSelectionCheckbox: true,
selectedItems:$scope.output
};
Not really an answer, but maybe it helps you.
Forked Plunker
Update
Found out some more:
The event ngGridEventData is fired 2 times:
On Initialization AND after selectItem by a watcher.
Also afterSelectionChange is fired 2 time. The rowItem from first call is a clone (from cache?) the second one is noClone.
This sums up to 4!
So by taking init out of ngGridEventdata and replacing it with a timeout as well as only pushing rowitems when they are a clone (why?) resolves this issue.
$scope.gridOptions = {
data: 'myData',
showSelectionCheckbox: true,
afterSelectionChange: function(rowItem, event) {
if (rowItem.isClone) {
$scope.output.push({
name: rowItem.entity.name,
selected: rowItem.selected
});
$scope.num++;
}
}
};
setTimeout(function() {
angular.forEach($scope.myData, function(data, index) {
if (data.name == 'Enos') {
$scope.gridOptions.selectItem(index, true);
}
});
})
I know this is still not an answer and smells like a bug to me, but here is another forked Plunker anyhow.
Of course you now have to find a way how to splice items out of the array when they are unselected. Good Luck!
I figured it out - or sort of.
Using beforeSelectionChange instead of afterSelectionChange I get the expected behavior.
The documentation is lagging some information.

Resources