The Grid the Brad and the Ugly: Using Grids to Improve Your Applications

Preview:

Citation preview

[1207] The Grid, the Brad, and The Ugly: Using Grids to Improve Your ApplicationsBrad BalassaitisPaul Calhoun

Paul Calhoun• Vice President – QDilligence• CTO – NetNotes Solutions Unlimited• IBM – Champion 2013-2016• Been teaching, administering and coding with Notes/Domino

since release 2. • Been working with XPages since the beta release.• Spends all spare time showing people cute pictures of his

grandkids !!! (You have been warned !!)

Brad Balassaitis• Senior Consultant for PSC Group• Certified Notes developer since R4• IBM Champion 2014 - 2016• Blog: xcellerant.net

Outline• Client-Side Grids• Dojo• Gridx• Sencha Ext JS• Kendo UI Grid• jQuery

Client-Side Grids

Why Grids?• UI• Features• Performance

Grid UI• Modern UI + Themes

Grid Features• Infinite scrolling or paging• Columns – change width, rearrange, show/hide• Sorting• Filtering• Expandable detail section• Inline editing with UI widgets

Grid Performance• Less server-side processing• Less data sent to browser

Data only – no HTML

• Client-side sorting/filtering• Asynchronous server interaction• Virtual Rendering

# of DOM Elements

# Rows View Grid50 5k 3k

500 37k 29k5000 353k 290k

# Rows View Grid50 844 944

500 7,594 944

5000 75,078 944

Considerations• Cost• Complexity

Not drag-and-drop Experience of developers

• Overhead Loading additional library

• Scaling Pre-filter

Getting Started• Add library to WebContent• Include JS/CSS resources (page/theme level)• REST service to provide data• Define columns and create grid• Add features

Dojo

The Grid• Built into Domino / XPages via the Extension Library

So it’s “Free” (relatively speaking) Doesn’t require loading of any additional libraries (Code or styling)

• Doesn’t require extensive knowledge of Client Side Java Script CSS JSON or XML

• Easy to prototype and get into production

The Brad• Brad has already done all the work for you !!

http://xcellerant.net/dojo-grids-in-xpages/ Blog series on using / implementing dojo grids in XPages from

soup to nuts (beginning to end)

The Ugly• Why exactly am I doing this section again?• It’s not <insert other grid technology> !!

This is mostly subjective and developer preference• “I already know grid technology “X”, so I won’t use grid technology “Y””

• “X” looks better than “Y”

The Parts• Domino View• XPage• Extension Library

Rest Service Dojo Grid Control Grid Columns

The View • A Domino View that contains the primary columns to be

displayed in the grid

The XPage and Extension Library • The XPage does NOT have to be in the same .nsf as the data

(view)• Must have

Extension Library from OPENNTF

or Domino 8.5.3 Upgrade Pack 1 or above

The REST Service• Add the REST Service control from the Data Access drawer to

the XPage.• Provide a value for the ‘pathinfo’

attribute This allows you to test the json

returned from the service from aa url: xpagename.xsp/pathinfo

• Add a View JSON Service Click the plus button and choose

xe:viewJsonService

The REST Service (cont)• Set contentType attribute to

application/json

• Set defaultColumns attribute to true

• Set var attribute value to variable name that will be used to access the row data

• Set viewName attribute to the name of the View that containsthe data for the grid

The Dojo Data Grid Control• Add the Dojo Data Grid control from the Dojo Layout drawer• Accept or provide an id• Choose the REST Service

on the same page as the grid control

Add Columns to the Grid Control• Sample the JSON output from the REST Service• Use the pathInfo variable from the REST Service definition to

get a sample of the JSON output• Notice the variables that

are used for the columnnames

Add Columns to the Grid Control (cont)• User the variable names from the JSON output as the values

for the field attribute of the Dojo Data Grid Column• Set a value for the label attribute which will be come the

column header• Set a width appropriate

to the data being displayed• Add a Data Grid Column

for every view column tobe displayed in the grid

• Save and Test !!!

The Rendered Grid

Demo

Gridx

The Grid: Gridx• Next-generation Dojo grid

http://oria.github.io/gridx/news/metrics.html (gridx vs dgrid and dojo grid)

• Handle one million+ rows• Many feature modules

The Brad• Blog series on implementing and using gridx in XPages

http://xcellerant.net/gridx-in-xpages/

The Ugly• Relative to other current grids, UI isn’t as modern

Installation• Download gridx library (free)• Drag into WebContent folder• Dojo Module Path• Include Gridx Resources

Dojo Module Path1. XPage or CC Properties

> Resources2. Add… > Dojo Module

Path Resource3. Prefix: gridx4. url: /gridx

Gridx Resources <xp:this.resources>

<!-- Claro Theme -->

<xp:styleSheet href="/.ibmxspres/dojoroot/dijit/themes/claro/claro.css"></xp:styleSheet>

<xp:styleSheet href="/.ibmxspres/dojoroot/dijit/themes/claro/document.css"></xp:styleSheet>

<!-- Module Path to locate Gridx Library -->

<xp:dojoModulePath url="/gridx" prefix="gridx"></xp:dojoModulePath>

<!-- -Main GridX Stylesheet -->

<xp:styleSheet href="gridx/resources/claro/Gridx.css"></xp:styleSheet>

</xp:this.resources>

Gridx - Sample Grid<xc:ccGridxResources></xc:ccGridxResources>

 <div id="gridX_Here" style="height:300px; width:300px;"></div> 

<script>  require(["gridx/Grid", "dojo/store/JsonRest“, "gridx/core/model/cache/Async", "dojo/domReady!” ],

function(Grid,JsonRest, Cache) {     var store = new JsonRest({      idProperty: '@noteid',      target: "X_REST.xsp/gridData"    });     var columns = [      {id: 'first', field: 'firstname', name: 'First', width:   '70px'},      {id: 'last', field: 'lastname', name: 'Last'},      {id: 'state',field: 'state', name: 'State', width: '40px'}    ];   

Gridx - Sample Grid (con’t)    grid = new Grid({      id: "my_gridX",      cacheClass: Cache,      store: store,      structure: columns    });     //Put it into the DOM tree.    grid.placeAt('gridX_Here');    grid.startup();   });</script>

Opening a Document• Connect an event handler to a row event• Read the unid from the row data and build a URL

grid.connect(grid, "onRowDblClick", function(eventInfo) {

  var unid = grid.row(eventInfo.rowId).item()['@unid'];

  location.href = "MyPageName.xsp?action=openDocument&documentId=" + unid;

});

Gridx - Adding Feature Modules• Require a module (AMD or page-level)• Add it to the grid's modules attribute

<script> require(["gridx/Grid“, "gridx/modules/ColumnResizer“, "dojo/store/JsonRest“,

"gridx/core/model/cache/Async“, "dojo/domReady!” ], function(Grid, Resizer, JsonRest, Cache) {....grid = new Grid({ id:   "my_gridX", cacheClass: Cache, store: store, structure: columns, modules: [ Resizer ]});

Gridx Features• Sorting - initial, custom, programmatic, nested• Resizing, rearranging, showing/hiding columns• Row selection• Column/Row locking• Exporting• Virtual Scrolling• Persistence

Gridx Features• Column Header Menus

Gridx Features• Toolbars• Selection

Gridx Features• Quick Filter

Full Text Search

Gridx Features• Filter Bar

Field-specific Data type-specific Multiple rules Client-side No coding required!

Gridx Features – Filter Bar

Gridx Features• Details on Demand

Expandable detail section No loaded unless requested (then cached) Asynchronous call to retrieve data

Gridx Features

Server-Side Updates• Use client-side code to asynchronously trigger server-side code

and wait for a response• Two Key Uses:

1. Inline Editing

2. Document Processing

Inline Editing• Require Edit module• Add Edit module to grid• Define editable column(s)

editable: true

• Optionally use a UI widget• Save Changes

Inline Editing – UI Widgets• Add CellWidget module to grid• Include Dojo widget on page

<xp:this.resources>  <xp:dojoModule name="dijit.form.NumberSpinner"></xp:dojoModule></xp:this.resources>

• Specify widget in column definition{ id: 'rating', field: 'Rating', name: 'Rating', dataType: 'number', width: '75px',   editable: true,   editor: 'dijit.form.NumberSpinner',  editorArgs:{    props: 'smallDelta: 1, constraints: {min:1, max:5, places:0}'  } }

Inline Editing – UI Widgets

Inline Editing – Saving Changes

Inline Editing – Options for Saving Changes1. Enable Domino Data Service, POST/PATCH updates via XHR2. RPC Method

Provides opportunity to process as needed (take other action aside from just direct field update)

Does not require enabling DDS

3. POST to Custom REST service (Same benefits)

Inline Editing – Grid Events• Edit Events

onBegin - before cell goes into edit mode• Use to track original value and see whether it changed in onApply

onApply - after cell is edited

• Attaching Event Handlers Module definition

{  moduleClass: Edit,  onBegin: beforeEdit, onApply: saveChange}

Inline Editing: Saving Changes• Requirements

1. SSJS function process the change

2. RPC method to accept UNID, field, value and call the SSJS method

3. Client-side Javascript function to call RPC method

4. Grid event handler

Inline Editing: Saving Changes• 1. SSJS function process the change

function rpcUpdateField (unid, fieldName, fieldValue) { var doc:NotesDocument = database.getDocumentByUNID(unid); if (doc != null) { doc.replaceItemValue(fieldName, fieldValue); doc.save(true); return true; } else { return false; }}

Inline Editing: Saving Changes• 2. RPC method to accept UNID, field, value and call the SSJS method

One line to call SSJS function<xe:jsonRpcService id="jsonRpcService1" serviceName="rpcGrid"> <xe:this.methods> <xe:remoteMethod name="updateField” script="rpcUpdateField (unid, fieldName, fieldValue);"> <xe:this.arguments> <xe:remoteMethodArg name="unid"></xe:remoteMethodArg> <xe:remoteMethodArg name="fieldName"></xe:remoteMethodArg> <xe:remoteMethodArg name="fieldValue"></xe:remoteMethodArg> </xe:this.arguments> </xe:remoteMethod> </xe:this.methods></xe:jsonRpcService>

Inline Editing: Saving Changes• 3. Client-side Javascript function to call RPC method

• Wait for response and set cell color to green or red

function saveChange() {... rpcGrid.updateField(rowUNID, fieldName, newValue).addCallback(function(updateSuccessful) { if (updateSuccessful) { node.style.backgroundColor = 'green'; } else { node.style.backgroundColor = 'red'; } });...

Inline Editing: Saving Changes• 4. Grid event handler

• Call the client-side JS function

modules: [... { moduleClass:Edit, onBegin:beforeEdit, onApply:saveChange }, CellWidget]

Processing Multiple Documents

Processing Multiple Documents• Inline icon, toolbar button, or header menu action• Requirements

1. SSJS function process the changes

2. RPC method to accept array of UNIDs and call the SSJS method

3. Client-side Javascript event handler• Call RPC method and wait for response

• Display growl message

4. Grid event handler

Sencha Ext JS

The Grid• One of the most mature / established JS libraries available• Extensive documentation and support• Over a dozen grid types

http://examples.sencha.com/extjs/6.0.1/examples/kitchensink/#grids

• Support for “Spreadsheet” style grids including locking columns and rows

• Built in ability to export to EXCEL• In-Line Editing, filtering and much, much, much more !!

The Brad• I don’t know ?• What do you think Brad ?

<pause here for witty comeback from Brad>

The Ugly• It’s not Free

Although there is a Free Trial Different “levels” from standard to premium

• Standard currently starts at $895 (5 license minimum = $4,475)

• Ext JS is a VERY robust framework (not a bad thing) BUT… this can make it difficult to pull just the pieces you want

• Not specifically designed to run on Domino/XPages You have to code everything from scratch

The Parts• Domino View• Ext JS Libraries and Style Sheets• XPage

One to render the grid One XAgent to return the JSON

• Java Code to produce the JSON

The View and Libraries• A Domino View that contains the data to be rendered in the grid• From the download of Ext JS copy all of the following to the

WebContent folder of the application that will implement the grids

The Java Code• First we need Java code to produce the JSON• To produce the JSON we need a JSON API

It just so happens there is one that is included in the Extension Library !!!!

• com.ibm.commons.util.io.json.* Used to create JSON Objects and Arrays

The Java Code (cont)

The Java Code (cont)

The Java Code (cont)

The XAgent • An XAgent is and XPage that does not render any UI but only

contains code. It is in essence a Java Servlet

• In the XPages afterRenderResponse event add the following code

The XPage• The Xpage only has two controls

Script Output Control• This is where all of the JavaScript will be written

Panel• This is where the grid will be rendered

The XPage Source• Using the Ext JS API

Define the data model Set Configuration attributes and required components

The XPage Source (cont)• Using the Ext JS API

Create the data store and point it to the XAgent

The XPage Source (cont)• Using the Ext JS API

Define the grid and it’s attributes

The XPage Source (cont)• The Panel contains a <div> that is used as the target for

rendering the grid REMINDER- This is all happening CLIENT SIDE !!!

Ext JS Grid

Kendo UI Grid

The Grid: Kendo UI Grid• jQuery-based• Part of Kendo UI (layout, forms, grids, charts/maps, etc)• Much more modern look and feel (Bootstrap)• Templates for toolbar, rows, details• Instantiation: Programmatic, HTML Table, MVVM, Angular• Bind to local data, remote data, web sockets• Mobile Components• Offline

The Grid: Kendo UI Grid

The Brad• Blog series coming...

The Ugly• Licensing: $999 per developer• 100 MB library

30+ MB of examples Custom builder available with license 2.4 MB js file is actually loaded in browser (+90 k jQuery)

Kendo UI Grid - Features• Sorting• Filtering• Grouping• Reordering, Column Locking• Paging• Export to Excel or PDF• Virtualization• Persistence• Hierarchy (Expandable Details)

Kendo UI Grid - Features• Persistence

Programmatically save and restore grid state Column order Column widths Sorting Filters Grouping

Kendo UI Grid - Features• Grouping / Categorization

Grid-level property -- groupable: true Drag column header to top to group Aggregation

• Define aggregates for a column (count, average, sum, min, max)

Group header templates per column to display aggregate info

Kendo UI Grid - Features• Filtering

Type-specific filtering on one or more columns Enabled with a single property Option 1: Popups in column header

• Optional Checkbox selection of one or more column values

Option 2: Filter Row

Kendo UI Grid - Features• Filter Popups

Optional checkbox selection for multiple values

Kendo UI Grid - Features• Filter Row

Kendo UI Grid - Features• Editing

Features• Built-in add/edit/delete buttons

• Validation

• Control over editable fields

Styles• Inline

• Popup

• Batch

Kendo UI Grid

Kendo UI Grid• Installation

Drag library into WebContent Add 2 JS libraries and 2 stylesheets<xp:this.resources> <xp:styleSheet href="KendoUI/styles/kendo.common.min.css"></xp:styleSheet> <xp:styleSheet href="KendoUI/styles/kendo.default.min.css"></xp:styleSheet> <xp:script src="KendoUI/js/jquery.min.js" clientSide="true"></xp:script> <xp:script src="KendoUI/js/kendo.all.min.js" clientSide="true"></xp:script></xp:this.resources>

Kendo UI Grid• AMD Issue

As with many jQuery plugins, newer versions of dojo break them because of amd loading conflicts

• http://xomino.com/select2-v4-needs-amd-fixing-in-domino-r9-xpages/

• Edit the js file before importing into the NSF

typeof define=="function"&&define.amd?define:function(_,f){f()});

typeof define=="function"&&define.amd&&false?define:function(_,f){f()});

Kendo UI Grid – Simple Grid<div id=“grid”></div><script>$(document).ready(function(){ $("#grid").kendoGrid({ columns: [ {field: "FirstName", title: "First Name"}, {field: "LastName", title: "Last Name"} ], dataSource: { transport: {read: "xRest.xsp/People"} } });}</script>

Kendo UI Grid – Adding Featuressortable: true,resizable: true,reorderable: true,

jQuery

The Grid• Hold on I’m thinking….

• Yea, no, I can’t think of any. Disclaimer: This is MY experience with jQuery and jQuery grids

in general. Your milage may vary

• In the early days jQuery was the goto library because it was the most “moder” (it had rounded corners)

• Of course check out xomino.com for all things jQuery and XPages

The Brad• DataTables - Very popular, lots of features, good docs, Bootstrap• SlickGrid - Fast and pretty simple, not supported recently• Flexigrid – simple, basic grid features• jsGrid – nice looking, editing, inflexible search• jqGrid – Bootstrap UI, feature-rich, simple• jqxGrid – feature-rich, decent-looking• jQuery Bootgrid or Ingrid – add basic grid features to a table

The Ugly• There is no single source for jQuery beyond the core• Most anything you want to do beyond basics requires a plug in• You don’t always know where those plug ins

Came From Will be supported Will even be maintained

• There are a LOT of grid plug-ins to choose from. No real clear picture of best one to implement for XPages.

Thank you

Acknowledgements and DisclaimersAvailability. References in this presentation to IBM products, programs, or services do not imply that they will be available in all countries in which IBM operates.

The workshops, sessions and materials have been prepared by IBM or the session speakers and reflect their own views. They are provided for informational purposes only, and are neither intended to, nor shall have the effect of being, legal or other guidance or advice to any participant. While efforts were made to verify the completeness and accuracy of the information contained in this presentation, it is provided AS-IS without warranty of any kind, express or implied. IBM shall not be responsible for any damages arising out of the use of, or otherwise related to, this presentation or any other materials. Nothing contained in this presentation is intended to, nor shall have the effect of, creating any warranties or representations from IBM or its suppliers or licensors, or altering the terms and conditions of the applicable license agreement governing the use of IBM software.

All customer examples described are presented as illustrations of how those customers have used IBM products and the results they may have achieved. Actual environmental costs and performance characteristics may vary by customer. Nothing contained in these materials is intended to, nor shall have the effect of, stating or implying that any activities undertaken by you will result in any specific sales, revenue growth or other results.

Acknowledgements and Disclaimers cont.© Copyright IBM Corporation 2015. All rights reserved.

• U.S. Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.

• Please update paragraph below for the particular product or family brand trademarks you mention such as WebSphere, DB2, Maximo, Clearcase, Lotus, etc.

• IBM, the IBM logo, ibm.com, [IBM Brand, if trademarked], and [IBM Product, if trademarked] are trademarks or registered trademarks of International Business Machines Corporation in the United States, other countries, or both. If these and other IBM trademarked terms are marked on their first occurrence in this information with a trademark symbol (® or ™), these symbols indicate U.S. registered or common law trademarks owned by IBM at the time this information was published. Such trademarks may also be registered or common law trademarks in other countries. A current list of IBM trademarks is available on the Web at “Copyright and trademark information” at www.ibm.com/legal/copytrade.shtml

If you have mentioned trademarks that are not from IBM, please update and add the following lines:

[Insert any special 3rd party trademark names/attributions here]

Other company, product, or service names may be trademarks or service marks of others.

Recommended