I'm wondering if there's a way to select the "Grouping" row in ag-grid.
For example, in the example shown on the website:
http://www.ag-grid.com/angular-grid-grouping/index.php
You can set the "rowSelection" parameter to "single" in order to highlight an entire row at the lowest node. However, that does not allow you to highlight the "Country" row.
In the example, the only way to do this is to "select all" the elements below that row.
Thanks!
According to the documentation, setting the grid option groupSelectsChildren to false will make the grouping row selectable, independently from its children.
groupSelectsChildren: When true, selecting a group will have the
impact of selecting all it's children. The group will then display
'selected' when all children are selected, 'unselected' when none are
selected and 'intermediate' when children have a mix of selected and
unselected. When the node is selecting children, it will never appear
in the selected set when calling api.getSelectedNodes(). When false,
then the group is selectable independently of the child nodes. When
selecting the group node independently of the children, it will appear
in the set when calling api.getSelectedNodes().
I had the same problem so I worked around it by emulating the look-and-feel of selecting rows.
In your columnDefs object, add the cellClassRules attribute to EVERY column definition (so every cell will be highlighted, making it appear that the row itself is highlighted when you click on it):
var columnDefs = [
{ headerName: "#1", cellClassRules: { rowSelected: CustomRowStyle }, field: "Col1" },
{ headerName: "#2", cellClassRules: { rowSelected: CustomRowStyle }, field: "Col2" },
{ headerName: "#3", cellClassRules: { rowSelected: CustomRowStyle }, field: "Col3" }
]
Then add an event listener for onCellClicked in your gridOptions object:
onCellClicked: function(cell) {
SelectedRowIndex = cell.rowIndex;
$scope.gridOptions.api.refreshView();
}
In your controller, define a variable called SelectedRowIndex:
var SelectedRowIndex; // this will contain the currently selected row number
Now create a function called CustomRowStyle which is called by ag-grid each time it is about to render a cell on-screen. This function will check if the cell is in the same row as the SelectedRowIndex (based on which row the user last clicked on) to determine if the cell should appear with the rowSelected class.
function CustomRowStyle(params) {
return params.rowIndex === SelectedRowIndex
}
Finally, define a rowSelected class with your selected row CSS:
.rowSelected {
background-color: silver !important;
}
Whichever row you click on (whether it's a group item or a child item) will appear with the rowSelected CSS. Your controller can always know which row is currently selected by checking the SelectedRowIndex variable.
This probably won't work for all cases but I found that as of version 20.2.0 RowNode's have a 'parent' property (Note: I'm not saying that feature was added in 20.2.0, just that I haven't gone and checked previous versions). So I do this:
api.getRowNode('child-row-id').parent.setSelected(true)
Obviously depending on how many levels of grouping you have and how dynamic that is (i.e. can the user change the grouping configuration, can you have n levels of grouping, etc.) you'll need to detect and adjust, but this works well for my particular use case of remembering what was selected and reselecting it on page refresh because my grid always starts out in the same grouping state on page load.
set groupSelectsChildren={false} and use this code onRowClicked={this.onRowClicked}
use any unique data identifier for selecting the node.
onRowClicked = (row) =>{
let that = this;
this.gridApi.forEachNode(node =>{
if(node.data.id === row.data.id) { that.gridApi.selectNode(node,true);}
});
}
Related
I want to show the Row no in my grid.
I use cell template and there i use {{rowRenderIndex+1}}
It works fine when records are less then 14,but after record count get increased then when we scroll down the grid the Row No get initialize with one again and again.
You can add a property in the data and add column for display:
//Add property
$scope.yourData.forEach( function(row, index){
row.idx= index;
});
//Adding column
columnDefs: [
{
field: 'idx',
displayName: '',
width: 30
}
In the ui-grid FAQ there is a section "How can I show a sequence number/id in a column in my grid?"
I believe you are looking for the second answer in that section:
cellTemplate: '<div class="ui-grid-cell-contents">{{grid.renderContainers.body.visibleRowCache.indexOf(row)}}</div>'
The rowRenderIndex is used to index rows that are rendered at that moment.
Scenario is quite simple. I have edit view which comprises of select element with multiple selection. Select element looks as follows
<select class="selectpicker" multiple
ng-model="UserBeingEdited.UberTypes"
ng-options="uberType.Id as uberType.Name for uberType in UberTypes"></select>
</div>
If I press edit for specific user then showEditModal function is called and edit pop up shows up. User has his own UberTypes objects selected so I pick theirs Ids and assign to UserBeingEdited.UberTypes.
$scope.UserBeingEdited = { UberTypes: []};
$scope.showEditModal = function (user) {
for (var i = 0; i < user.UberTypes.length; i++) {
$scope.UserBeingEdited.UberTypes.push(user.UberTypes[i].Id);
}
$("#editUserModal").modal("show");
};
Unfortunately they are not selected, no matter what. Suprisingly, if I set values to property UserBeingEdited by the time of declaring then it works, items are selected.
$scope.UserBeingEdited = { UberTypes: [1,2]}; //this works
It seems like angular does not refresh selected items within UI.
EDIT:
I have two items: Uber1 and Uber2. Both items are selected but view does not reflect it. If I open drop down menu and select Uber2 it shows Uber1 selected, apparently Uber2 was selected and another click was treated as unselection. The same happens when I click Uber1 first, Uber2 shows as selected.
As above picture depicts, Uber2 is highlighted since I have just clicked it but it shows Uber1 as selected. Both were selected in User's UberTypes but view just simply does not mark them as selected.
http://jsfiddle.net/upusq8ah/7/
I use bootstrap-select.js for select element and presumably this library causes such an error since without including it, it works fine.
Solution
After a while of struggle, I accidentally ran into below workaround. You need to call refresh on selectPicker and this has to be delayed otherwise it will bring no effect.
setTimeout(function () {
$('.selectpicker').selectpicker('refresh');
}, 100);
$("#editUserModal").modal("show");
I have three dropdown boxes. I need to filter the data and need to be displayed in the table based on my checkbox selection(either with single checkbox or two checkboxes or three checkboxes).
I have done the following, but if we observe it clearly, I am not able to filter the data properly using AngularJS.
Like:
a. It should work for individual checkbox selection: means if I select any single checkbox either from Name or Description or Field4, then respective matched filtered data should be displayed in the table, otherwise it shouldn't be displayed any data(i.e if it doesn't match our checkbox selection means it won't display any data)
b. It should work for multiple(two) checkbox selection: means if I select any multiple checkboxes like either one from Name and one from Description or one from Description and one from Field4 or one from Field4 and one from Name, then respective matched filtered data should be displayed in the table, otherwise it shouldn't be displayed any data(i.e if it doesn't match our checkbox selection means it won't display any data)
c. It should work for multiple(three) checkbox selection: means if I select the three checkboxes like one from Name and one from Description and one from Field4, then respective matched filtered data should be displayed in the table, otherwise it shouldn't be displayed any data(i.e if it doesn't match our checkbox selection means it won't display any data)
It is working fine for the first time checkbox selection only, means: after loading the above code/app, if we check either any one of the above selections(like whether single checkbox selection or two checkbox selection or three checkbox selection) then it's working fine, later it is not working(means if we uncheck the above any criteria and then if we select any checkbox again then it's not working, for that again we need to refresh the app/code then only it's working).
Example: if I select one from Name, then respective matched data will be displayed. Then again if I uncheck the same and check the some other checkbox like from Description then it's not working. Similarly for all the above criteria. You can observe it clearly.
Please let me know that what I have done wrong here and let me know how to filter it properly. Created Fiddle. Thanks in advance !
The problem is the convoluted filtering logic. Anytime you find yourself nesting lots of if statements, think about reorganizing the branching logic. By breaking it into smaller components, you can make it easier to manage, and if you can avoid using if altogether, then you only have to test one path, instead of several.
Every time a user checks a box, we need to make sure that we only display items that match however many boxes are checked. So we need to know 1) how many boxes are checked, n, and 2) how many items can be found with n matching fields.
We can take advantage of the fact that Boolean variables can be cast to integers (0 = false, true = 1) and use that to count the number of checked boxes, as well as the number of matches found.
We can also put the field names into an array, so that we don't have a lot of repetition in our functions.
Fiddle example here.
var fields = ["name", "description", "field4"];
//for each field, count how many fields the item matches
function getMatches(item, matchesNeeded) {
var foundMatches = 0;
fields.forEach(field => {
foundMatches += item[field] === $scope.pagedItems[field]
});
//make sure found at least one match and found desired minimum
return foundMatches && foundMatches >= matchesNeeded;
}
//count how many boxes are checked
//this will tell us how many different fields we are matching on
function numChecked() {
var count = 0;
fields.forEach(field => {
//this will auto convert falsy to 0.
//truthy values will be 1
count += Boolean($scope.pagedItems[field]);
});
return count;
}
$scope.filterItems = function(item) {
return getMatches(item, numChecked());
};
As #Larry pointed it was more based on logic. I have modified Apress book 'Pro AngularJS' Source Code from GIT for this.
Basic logic will in filter function as below -
$scope.categoryFilterFn = function (product) {
var canHave = false;//dont load by default
var atLeastOneTrue = false;//Check if previously checked any condition
angular.forEach(filterValues, function(selectedValue, key) {
var selectVals = Object.values(selectedValue);
if(selectVals.indexOf(product[key]) !== -1) {//if values exits in product.
canHave = !atLeastOneTrue ? true : canHave;
}else{
canHave = false;
}
atLeastOneTrue = true;
});
return canHave;
}
For working Fiddle.
I'm using the following code in order to set the selected value:
this.myCombo.setBind('{rec.my_value}');
All my data is in "rec".
Options for choose are being filled in the combo as expected but no value is set to the selected value.
Why is this happening and how to solve?
Tried already put the above bind after data is being loaded and after page is already rendered, but without success.
You can use code something like this:
{
xtype:'combo',
store:'mystore',
valueField:'id', // you will get this value by default after selection
displayField:'name', // it will responsible to show display as option on combo
listeners: {
change : function(cmp){
var value = cmp.getValue();
}
}
}
Where id and name are the record data of store. Now, whenever you select any option, then it will display.
Suppose I know which row index to target (with this.rowToBeDeleted having a value of 2, say), how can I hide this row only from the grid but not the store (I have a flag in the store, which signifies what rows should be deleted from the db later in my PHP webservice code).
You can either use one of the store.filter() methods or you can hide the row element.
grid.getView().getRow(rowIndex).style.display = 'none';
I think it's much better though to just remove the record from the store and let the store update the view since you are deleting the record and not just hiding it. With the store in batch mode (the default: batch: true, restful: false), it will remember which rows you've removed and won't fire a request to the server until you call store.save().
I suggest using store.FilterBy() and pass a function to test the value of the value in rowToBedeleted:
store.filterBy(function(record) {
return record.get("rowToBeDeleted") != 2;
});
I wrote a basic blogpost about gridfiltering a while ago, you can read it here: http://aboutfrontend.com/extjs/extjs-grid-filter/
In ExtJS 4.1, there is no view.getRow(..). Instead you can use:
this.view.addRowCls(index, 'hidden');
to hide the row at the specified index, and
this.view.removeRowCls(index, 'hidden');
to show it (where 'this' is the grid).
CSS class hidden is defined as
.hidden,
{
display: none;
}
This is useful for peculiar scenarious where store.filterBy() is not appropriate.
In the grid js file write following code to apply a CSS to those rows which you want to hide.
<pre><code>
Ext.define('MyGrid',{
extend : 'Ext.grid.Panel',
xtype : ''mygrid',
viewConfig : {
getRowClass : function(record,id){
if(record.get('rowToBeDeleted') == 2){
return 'hide-row';
}
}
},
.................
.................
});
</code></pre>
Now define a custom CSS in custom.css file:
.hide-row{display:none}
This will hide rows in grid without removing or filtering from store.
You can use the store.filter() or store.filterBy() methods for that.
Set a "hidden" property on your records and the filter all records that have hidden set to true for example. This way they'll still be present in the store but not visible in the grid.