the grid the brad and the ugly: using grids to improve your applications
TRANSCRIPT
[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.