in my case if a column is moved or pinned same changes should reflect in sub grid also.I have written a function for this which changes the properties in subgrid as per parent but not able to find any event which occurs on pinning of columns on parent grid so that i can call my function.currently i am using this event
$scope.gridApi.core.on.rowsRendered($scope,$scope.pinSubGridColumns)
but its fired too many times and the view is getting distorted.Also if i pin columns in parent grid then sub grid columns starts after these columns but i want subgrid columns aligned as per parent so if i have id column in parent grid then subgrid id column should be below it even if it is pinned.how can i achieve this?
here is the demo on plunker : http://plnkr.co/edit/AKUFxTaJ2c3fLvl7AZin?p=preview
function :
$scope.pinSubGridColumns=function()
{
for(i=0;i<$scope.gridApi.grid.columns.length;i++)
{
for(j=0;j<$scope.subGridColumnDefs.length;j++)
{
if($scope.gridApi.grid.columns[i].name===$scope.subGridColumnDefs[j].name)
{
if($scope.gridApi.grid.columns[i].renderContainer==="left")
{
$scope.subGridColumnDefs[j].pinnedLeft=true;
$scope.subGridColumnDefs[j].pinnedRight=false;
}
else if($scope.gridApi.grid.columns[i].renderContainer==="right")
{
$scope.subGridColumnDefs[j].pinnedLeft=false;
$scope.subGridColumnDefs[j].pinnedRight=true;
}
else
{
$scope.subGridColumnDefs[j].pinnedLeft=false;
$scope.subGridColumnDefs[j].pinnedRight=false;
}
}
}
}
if( $scope.subGridApi!==undefined)
{
$scope.subGridApi.core.notifyDataChange(uiGridConstants.dataChange.COLUMN);
}
}
Related
I have created a Master-Detail app, with three columns. First view is to select a Project. Second view, to select WBS Elements. Third view, it has a Smart Chart based on the selected WBS from second view.
So far, the first time the chart is triggered it works fine. Problem is when I deselect a few WBS, and select new ones. I can't find a way to either rebind the chart nor to refresh the third view (so either the onInit or onBeforeRendering gets triggered again)
Chart currently is getting created once user hits the emphasized chart button at the top of the second view. Please do not pay attention to the layout of the second view, it is still under development.
Hope you can help me finding a way to refresh the chart after changes on the selected WBS.
Regards,
Tincho
You could use the EventBus. After loading the Chart View first time, the EventBus is "listening". Every time you're de/selecting a checkbox the event is triggered.
{ // Chart view controller
onInit: function() {
this.oEventBus = this.getOwnerComponent().getEventBus();
this.oEventBus.subscribe("Checkbox", "Selected", this.updateChart); // "Listener"
},
updateChart: function(channelId, eventId, data) {
// ...
},
}
{ // WBS view controller
onSelectWBSElement: function(oEvent) {
const oEventBus = this.getOwnerComponent().getEventBus();
oEventBus.publish("Checkbox", "Selected", {/*data*/});
},
}
For example, if I click on '+' sign on row number 1 and then I click on '+' sign on row number 2 the row number 1 have to be closed and row number 2 have to be expanded.
This the code i have used for ui-grid
<div ui-grid="gridOptions" ui-grid-pinning ui-grid-expandable class="grid" ui-
pagination>
You can define a listener for the rowExpandedBeforeStateChanged event, like this :
vm.gridApi.expandable.on.rowExpandedStateChanged(null, function (row) {
If a row has been expanded, you can iterate through all the expanded rows and collapse any that don't match the hashKey of the row that's just been expanded. In practice, because of this logic, there should only be two expanded rows in play - the previously expanded one, and the newly expanded one.
You can use logic like this in the rowExpandedStateChanged event :
if (row.isExpanded) {
collapseAnyPreviouslyExpandedRow();
}
function collapseAnyPreviouslyExpandedRow() {
var expandedRows = vm.gridApi.expandable.getExpandedRows();
if (expandedRows.length > 1) {
angular.forEach(expandedRows, function (expandedRow, key) {
if (expandedRow.$$hashKey !== row.entity.$$hashKey) {
vm.gridApi.expandable.collapseRow(expandedRow);
}
});
}
}
This assumes that you have previously assigned a gridApi object to your controller using an onRegisterApi call like this one :
vm.yourGridConfigObject.onRegisterApi = function (gridApi) {
vm.gridApi = gridApi;
I tried to apply PasswordRenderer to a specific row and column based on the value of that row.
So my custom renderer looked like this -
function firstRowRenderer(instance, td, row, col, prop, value, cellProperties) {
Handsontable.renderers.PasswordRenderer.apply(this, arguments); }
However the problem I face is, while editing the cells, the field is no longer masked. Here is an example - http://jsfiddle.net/whxbv6xh/
If you try and edit the first row of that table, the values are not masked. Any ideas?
This "unmasking" of the field is what the PasswordRenderer is essentially all about. If you want to not be able to see the original values at all you have at least two options:
1.Convert the header row's values beforehand:
function renderAsPassword(password) {
return new Array(password.length + 1).join('*');
}
alert(['', 'Kia', 'Nissan', 'Toyota', 'Honda'].map(renderAsPassword));
2.Create a custom editor, extending the built-in PasswordEditor:
var PasswordEditor = Handsontable.editors.PasswordEditor.prototype.extend();
PasswordEditor.prototype.getValue = function() {
return renderAsPassword(this.TEXTAREA.value);
};
PasswordEditor.prototype.setValue = function(newValue){
this.TEXTAREA.value = renderAsPassword(newValue);
};
I'm using the angularjs ui-grid and I have a "total" row that I want to pin to the top of the grid no matter what is the current sorting.
How can I accomplish that?
I think this is what you are looking for : Row Pinning
Essentially add another hidden column, something like this:
{
field: 'pinned',
visible: false,
sort: {direction: uiGridConstants.ASC, priority: 0}, //use uiGridConstants.DESC for pinning to the bottom
suppressRemoveSort: true,
sortDirectionCycle: [uiGridConstants.ASC] //use uiGridConstants.DESC for pinning to the bottom
}
Row entities which have pinned = true rise to the top, even when other sorting are applied.
DISCLAIMER: I know it's not exactly answers the question, but this is how I solved it for now until I'll have a better solution:
Create an other grid above the main grid :
<div style="height:30px" ui-grid="totalGridOptions"></div>
<div ui-grid="gridOptions" class="grid"></div>
with definitions:
$scope.totalGridOptions = {showHeader:false,enableHorizontalScrollbar:false};
and then bind the columns of the main grid to the total grid (for width and other adjustments):
$scope.$watch('gridOptions', function (newVal) {
$scope.totalGridOptions.columnDefs = newVal.columnDefs;
}, true);
I think you should use something like this
$scope.gridOptions.data.unshift({label:value});
unshift adds it to the top
Edit 2 / Actual Solution: The way I finally settled this issue was by using custom header cell templates. I essentially create a second header row by adding a div at the bottom of what was previously my header. Here's a simple version:
<div class="super-special-header>
<div class="header-display-name">{{col.displayName}}</div>
<div class="totals-row">{{grid.appScope.totals[col.field]}}</div>
</div>
I store my totals on the controller's $scope and can access them in that div with grid.appScope.totals[whateverThisColumnIs]. This way I can still update them dynamically, but they don't get mixed into a sort function like my previous 'solution' was aiming for.
Edit 1 / Dead-end 'solution': Just ran into a problem with my solution, if your table is long (you have to scroll to get to bottom rows), the totals row will scroll out of view. Going to leave this 'solution' here so no one else makes the same mistake!
I had this same issue but with a twist. Since I was going to need to change the default sorting algorithms for many of the columns anyway, I set my algorithm up to skip the first element in the sort. You can use the sortingAlgorithm property on any columndef that would be part of a sortable column. This is really only a solution if you have only a few sortable columns though. It becomes unmaintainable for huge tables.
I couldn't find any built-in feature for ui-grid to keep a specific row at the top of the grid when sorting is applied. But this could be done using sortingAlgorithm parameter in the columnDefs( please refer to http://ui-grid.info/docs/#!/tutorial/Tutorial:%20102%20Sorting).
I have written an algorithm which keeps the row('total' is the particular cell value in the row) at the top of the grid without applying a sorting.
var sortingAlgorithm = function (a, b, rowA, rowB, direction) {
if (direction == 'total') {
if (a == 'total') {
return 0;
}
return (a < b) ? -1 : 1;
} else {
if (a == 'total') {
return 0;
}
if (b == 'total') {
return 1;
}
}
}
I have a splitter. In this splitter, I am implementing drag and drop functionality for the list view. Each list view is loaded in "table" format.
I want to drag my list view from left to right.
For the 1st list view, I have this code :
var listViewOptions = {
template: kendo.template(
$("#Firsttemplate").html()
),
dataSource: listdatSource,
};
var sourceListView = $("#First").kendoListView(listViewOptions).data("kendoListView");
var draggableOptions = {
filter: "table",
hint: function (e) {
return $('<div class="new">' + e.html() + '</div>');
}
}
sourceListView.element.kendoDraggable(draggableOptions);
In the filter, if I give "table" / "tbody" the whole content of list view is dragging in a row format and after dropping it is in the right side of splitter and is displaying in a single row. I want to display in the same format as in the leftside.
Can you tell me how to do this?
Thanks
somejQueryElement.html() gives you the inner HTML code of your element. Thus, if you filter on table elements, your argument e of the hint function is the table and e.html() is the content of the table.
If you want to have your table, you have to add reencapsulate the element in table tags :
var draggableOptions = {
filter: "table",
hint: function (e) {
return $('<div class="new"><table>' + e.html() + '</table></div>');
}
}