FlexGrid allows you to access many different options and properties of the control to customize and configure behaviors to meet project needs. But in some cases, you may want to empower your end user with control of certain features of the Grid without cluttering up your user interface with controls. In this blog, we'll dive into how to add a glyph to the FlexGrid, allowing the users to configure their own interface and keep the page looking clean. By exposing properties or behaviors to the end user and using a data binding framework such as Angular 2, you can easily make a menu so end users can customize on the fly.

Grid

The Requirements

  • We add a settings glyph to the top leftmost cell in the Wijmo FlexGrid using the cell template directive.
  • We'll set the default to "hide all settings" unless the user wants to configure them.
  • When the user clicks on the settings gear, a Wijmo popup will appear and expose settings of the FlexGrid to the end user.
  • For this blog, we'll use FlexGrid configurations in the popup, but you can place any valid HTML inside of it to accomplish any requirement.
  • In this Wijmo popup menu, I've added the ability to set the number of frozen rows or columns, put the FlexGrid into ReadOnly mode, and change the parameters for conditional formatting.

settings

Let’s take a look at what we need to do accomplish this functionality.

Project Setup

I used Angular Material Glyphs for the settings menu icon. If you want to do the same, add the following reference to your default.html page:

<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">

This provides access to the entire library. You can test it by adding the settings glyph to your HTML page.

<i class="material-icons">settings</i>

For our popup menu, we'll use the Wijmo popup control. It's included in the Wijmo.angular2.input module. Inside our directives we'll need to add a reference to *.wjPopup. We'll add a few more directives, as well, so we can access the CellTemplate directive in our companion template. For this demo we'll add wjFlexCellTemplate and wjTemplateCmp.

import * as wjNg2Grid from "wijmo/wijmo.angular2.grid";
  import * as wjNg2Input from "wijmo/wijmo.angular2.input";
  Directive: [wjNg2Grid.WjFlexGrid, wjNg2Grid.WjFlexGridColumn, wjNg2Grid.WjFlexGridCellTemplate, wjNg2Grid.WjTemplateCmp, wjNg2Input.WjPopup, wjNg2Input.WjInputNumber,  ….other directives ];

Now we'll add the cell template markup to our FlexGrid. In order to add the settings icon to the top left cell, we'll use the wjFlexGridCellTemplate. We can place any valid HTML code here, so let’s add our Settings glyph and assign it an Angular 2 click event that will call a function inside our component class.


  <wj-flex-grid [itemsSource]="data" [selectionMode]="Cell" >
    <template wjFlexGridCellTemplate [cellType]="'TopLeft'">
      <i class="material-icons" (click)="showDialog(settingsMenu)" width="*" >settings</i>
    </template>
  </wj-flex-grid>

Creating the Popup

Inside our click event, we're calling showDialog() and passing it a parameter of settingsMenu. We'll need to add our popup to our companion template and assign it a local variable of settingsMenu to pass to our showDialog().


<wj-popup #settingsMenu class="popover" [showTrigger]="'Click'" [hideTrigger]="'Click'">
 <h3 class="popover-title">Settings Menu</h3>
<div class="popover-content">
<form name="popoverForm">
</form>
</div>
</wj-popup>

Right now, the contents of the popup are empty, but in order to test to make sure the popup is working, we need to define our showDialog() function in our component class. It's inside this function that we can make popup configurations.

showDialog(dlg: wijmo.input.Popup) {
  if (dlg) {
  dlg.modal = this.modal; // Boolean 
  dlg.hideTrigger = dlg.modal ? wijmo.input.PopupTrigger.None : wijmo.input.PopupTrigger.Blur;
  dlg.show();
  }
  };

Building the contents of the Popup

Now that we have our settings menu appearing, let's add some functionality. In our class we'll define two new variables called fRows and fCols. Since we bind our frozenRows and frozenColumns properties of our FlexGrid in our markup to these variables, let’s define them as a numeric.

export class AppCmp {
  fRows: number;
  fCols: number;
  constructor() {
  this.fCols = 1;
  this.fRows = 2;
  }

This is where Angular 2 starts doing the heavy lifting for us. In our markup, we can bind properties of our FlexGrid to these variables, bind some Wijmo Input Number controls to control behavior, and Angular 2 will propagate the changes for us.

Inside our popup directive, add the following markup inside the form.

<div class="form-inline well well-lg">
 <label>Freeze Rows/Cols</label><br>
 Number of frozen Columns:
 <wj-input-number [(value)]="fCols" [format]="'n'" [step]="1"> </wj-input-number>   
 Number of frozen Rows:
 <wj-input-number [(value)]="fRows" [format]="'n'" [step]="1"> </wj-input-number>    
</div> 

We bind the value of these inputs to our fRows and fCols in our class to provide a clean user control of these parameters.

Now we need to add these properties to our FlexGrid and bind them to our variables.


  <wj-flex-grid [frozenRows]="fRows" [frozenColumns]="fCols" …. > </wj-flex-grid>

Our FlexGrid (one-way bound) and InputNumber (two-way bound) are now bound and listening to these variables so if any changes made to the inputs, the Grid will update automatically for you.

We can follow the same process for putting the FlexGrid in Readonly mode. We need to add a Boolean variable to our component class.

//Define type as boolean
  isReadOnly: boolean;
  // Initialize to true 
  this.isReadOnly = true;

Now in our settings Popup we can add a checkbox input to provide control to the end user.


<div class="form-inline well well-lg">
 <label>Editable?</label><br>
 Is read only? <input type="checkbox" [(ngModel)]="isReadOnly"/>
</div>

Finally, we add the property to our each of our FlexGrid columns and bind it to our variable in our class. You can assign unique names if you want to control the editable properties for each column.


  <wj-flex-grid-column [header]="'Date'" [binding]="'date'" [isReadOnly]="isReadOnly" ></wj-flex-grid-column>

More advanced customizations: Change formatting parameters

Giving the user access to how many frozen rows or columns they want to see, or whether they want to make changes, is a common requirement. But when it comes to doing data analysis sometimes more advanced customizations are required such as conditional formatting. The dataset may not be static data, so it can be difficult to choose a range of data to format conditionally without knowing much about the data.

So let’s give our users the ability to change the formatting parameters. To begin, we'll add some static conditional formatting to a numeric column. Inside our FlexGrid markup:


<wj-flex-grid-column [header]="'Revenue'" [binding]="'amount'" [format]="'n0'">
 <template wjFlexGridCellTemplate [cellType]="'Cell'"  let-cell="cell">
  <div [ngStyle]="{color: getAmountColor(cell.item.amount)}">
   {{cell.item.amount | number:'1.0-0'}}
  </div>
 </template>
</wj-flex-grid-column>

This code takes the amount value and calls a getAmountColor() function in our component class. Then it places that formatted value into the cell.

Let's add our getAmountColor() code.

getAmountColor(sales: number) {
  if (sales < 500) return "darkred";
  if (sales < 2500) return "black";
  return "darkgreen";
  }

In my conditionals, I manually define the high and low ends of the formatter. It may be the case that you don't know these high and low ends; perhaps you want to empower your end user to customize the high and low ends of their dataset.

Let's add some new numerics to our class and bind our getAmountColor params to it.

// Define lowEnd and highEnd as numerics 
  lowEnd: number;
  highEnd: number;
  // Initialize our variables to some number 
  this.lowEnd = 500;
  this.highEnd = 2500;
  //Update the condtional to use these values 
  getAmountColor(sales: number) {
  if (sales < this.lowEnd) return "darkred";
  if (sales < this.highEnd) return "black";
  return "darkgreen";
  }

Finally, we'll add a few Wijmo Input Number controls to our popup menu to control behavior:


<div class="form-inline well well-lg">
<label>Conditional Formatting</label><br>
       Set Low End: <wj-input-number [(value)]="lowEnd" [format]="'n'" [step]="1"> </wj-input-number>
       Set High End:  <wj-input-number [(value)]="highEnd" [format]="'n'" [step]="1"> </wj-input-number>
</div>

For the blog today, we only place some basic functionality into our popup, but you can do much more. I wanted to show you how easy it is to add glyphs to the FlexGrid control and bind it to a Wijmo popup menu using Angular 2.

Get the sample

Try Wijmo's Angular controls

Download the latest version of Wijmo

Download Now!