ui-grid expandable one at a time - angular-ui-grid

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;

Related

Highlight row in ag grid on button click

I have a button outside the grid, on clicking of this button i am iterating the row nodes and doing a check whether the data is empty or not. If it is empty i want to highlight that row. Did not found anything which can give me any option to highlight the row in ag grid on button click.
Kindly help
I found the answer for above:
In Component: may be in constructor
this.rowClassRules = {
'invalid-row': (params) => {
if (this.inValidRowNode && this.inValidRowNode.data.name === params.data.name) {
return true;
}
}
};
On button click (in validation method), while iterating the node we need to set the data. I am setting in this way.
node.setDataValue('name', ' ');
In Html:
<ag-grid-angular #agGrid rowSelection="multiple" [gridOptions]="gridOptions" [columnDefs]="gridColumnDefs" (gridReady)="onGridReady($event)"
[rowClassRules]="rowClassRules">

How to post process with a dynamically created Google Chart?

I have a chart that looks like this:
Data comes from a web service and I want all the data to remain intact as it comes through to my model. The bars on the chart represent timespans (just a number column that displays the timespan.TotalHours).
Occasionally, as shown in the image, a time span will be negative - meaning it was ahead of schedule. When this is the case, I do not want to display that segment at all and in fact would like to subtract that time from the green segment. From what I've looked up, something that could help me with the actual subtraction of the negative number could be post processing. But how would I be able to modify my chart creation after that's done?
In case it's relavent, the code for the chart's creation is below:
<script type="text/javascript">
google.charts.load('current', { 'packages': ['corechart'] });
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = new google.visualization.DataTable();
// Since every row will alwyas have this as the first column, we do not need to iterate. The first column will always be this title.
data.addColumn("string", "Category");
// This iterates through each stage (timespan) and creates a column for it.
// And display only the relavent time spans on the chart.
#foreach (var stage in Model.selectedForm.rows[0].stages)
{
#Html.Raw("data.addColumn('number', '" + Regex.Replace(stage.label, "(\\B[A-Z])", " $1") + "');") // Adding a numeric column for each timespan (stage) in that row. Using Regex to make the labels more friendly to the user.
}
#foreach (var row in Model.selectedForm.rows)
{
#Html.Raw("data.addRow(['" + row.label + "'") //The first part of our row is the label - each subsequent stage will be filled in at each iteration below
foreach (var stage in row.stages) //For each stage in the row being created ...
{
if (stage.timespan.TotalHours <= 0)
{
#Html.Raw(", " + "null") // replace the column with a null value
}
else
{
#Html.Raw(", " + stage.timespan.TotalHours) //...Continue the HTML builder adding additional timespans to eventually...
}
}
#Html.Raw("]);\n\n") //...close it here
}
var options = {
titlePosition: 'none',
width: 1200,
height: 400,
legend: { position: 'top', maxLines: 3 },
bar: { groupWidth: '75%' },
isStacked: true
}
var chart = new google.visualization.BarChart(document.getElementById('SOPChart'));
chart.draw(data, options);
}
</script>
Edit: I've added a check in my code that generates the table to account for the negative value and not drawing the purple segment. However there is still the matter of subtracting that time from the previous segment which I am unclear on how to accomplish.
Edit: Added the updated code with comments. Also added an updated image of what this produces. Now that the actual chart is being handled, I still need a way to subtract the value off of the previous (green) segment. After this edit, here is what the chart looks like now:
if you want to try javascript on the client to correct the issue...
remove the last edit and allow the negative value to come thru
then use following snippet to correct, add just above --> var options = {
for (var i = 0; i < data.getNumberOfColumns(); i++) {
if (data.getValue(i, data.getNumberOfColumns() - 1) < 0) {
// subtract from next to last column
data.setValue(i, data.getNumberOfColumns() - 2, data.getValue(i, data.getNumberOfColumns() - 2) + data.getValue(i, data.getNumberOfColumns() - 1));
// remove negative from last column
data.setValue(i, data.getNumberOfColumns() - 1, null);
}
}

AngularJS : UI-Grid changing sub grid as per parent grid

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);
}
}

Handsontable Password Renderer

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);
};

filter in kendoUI drag and drop

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>');
}
}

Resources