Thursday, June 9, 2011

Wizard's Work

Manage 2000 7.4 development now includes a wizard that is capable of generating a maintenance web function with single valued fields and scrolled sets somewhat akin to PWS.
And there were a LOT of bytes in that elephant!
But the payback is a reduction in cost of writing web clients for Manage 2000 maintenance and posting functions, which we will leverage during the remainder of the standard system development cycle. And it will produce further payback as a tool for custom development projects.
The Manage 2000 tooling for the faux scrolled sets leverages the ajax validation, last keys, and prompt stack features of the roiTextbox and provides smooth keyboard navigation.
It takes just a few moments to select fields from a business transaction object and generate a working web function, which can be further enhanced and polished in Visual Studio.

Tuesday, March 8, 2011

ITouch'd Manage 2000

Well the Manage 2000 7.4 web repository is finally branched and 7.4 only development can now be checked in. But one last web tools development project did make it into the 7.3 sp3 code base before the branch; MT/M2000Mobile/M2000Mobile.aspx provides navigation based on MENU.MASTER trees and DEMO/MobileStockStatusByLoc/MobileStockStatusByLoc.aspx which provides an example application to copy.
The idea is to build HTML, javascript, and CSS styles that mimic mobile applications, rather than building applications in proprietary environments one end-user device at a time. Using micro-frameworks like WebApp.Net one can build a web page that looks and feels like a mobile app although it runs in the browser.
Sp2 just went out the door so we won't be launching sp3 for awhile but it should be available in plenty of time for stocking stuffers.

Sunday, January 30, 2011

iManage2000

This last month I've been testing and researching issues related to accessing Manage 2000 web functions from IPhone and Android based mobile devices. Since these internet enabled devices include web browsers the basic ability to run Manage 2000 web functions is built right in.
However there are stumbling blocks to their usability. The most obvious problem is the small screen and the large complex pages of standard Manage 2000 web function pages. A little further examination reveals navigation problems in the drop down menus. These are rendered by Infragistics UltraWebMenu controls which do not work properly with WebKit based browsers. Another issue to consider is performance when accessing the net through slower connections. (How many G's are there in T1?)
So, though you can go the discount route and setup phone desktop buttons to target specific standard Manage 2000 web functions, a little more work can lead to a much better user experience.
The road map to a better user experience includes replacing the standard heading banner with a navigation app based on IUI, WebApp.Net, or Sencha Touch. The menus should still be administerable in MENU.BUILD, but the whole mobile menu tree would get loaded to the mobile browser as a multi-layer page with anchor navigation between layers. This would provide the user with rapid menu navigation including familiar slide transitions and header navigation buttons.
Functions would work off of standard hyperlinks and load and postback in their usual fashion. Though any specific mobile web function development should consider leveraging the layer tools in these micro-frameworks. Other mobile web function best practices would include avoiding the IG Grid in lieu of lighter weight options, minimizing the information displayed in any given layer to 5-7 items and providing multiple choice data entry in place of fill in the blank wherever possible.
Sizing the formatting table to 480 x 320 can help give a design time feel for mobile screen territory at standard magnification. HTML meta tags like <meta name="viewport" content="width=device-width; initial-scale=1.0;" /> can be used to control the magnification level of the web function when initially displayed. Since these micro frameworks tend to use CSS hiding techniques they interfere with the design time WSYIWYG in Visual Studio. You can temporarily comment out the stylesheet link in the aspx file to get a better designer experience.

Friday, December 17, 2010

2 bits 4 bits 64 bits a dollar

The good news: "Mr Newby your new 64 bit Windows-7 8 gig package is ready for you."
The bad news: "Program Files or Program Files (x86)" and "How about that WOW6432Node Eh!"
Sooooooo, I've been installing and uninstalling and tweaking vbproj files and futsing with Visual Build scripts and messing about with InstallShield 2010 scripts and repeating, ad naseum.
But if you are a developer loading up Manage 2000 7.3 sp2 web tools on 64 bit Windows 7 box and you should run into issues, be thankful, it could be much much worse. The sp2 installs are now much more solid.
The most likely annoyance will be dataset references pointing into "Program Files" that can't be resolved because the dataset libraries are now in "Program Files (x86)". You can, of course, simply delete them and then re-add them from the correct location on your box.
Or you can copy the typed library en-masse from Program Files (x86) to Program Files. You just need to remember to copy over dlls anytime you regenerate them through the dataset utility.
Another option is to use the Path Conversion Utility to do a mass change on all the vbproj files in a Manage 2000 web site. This makes sense if all of your production and development web servers are 64bit.
I have also added a PreBuild.cmd script at the Manage2000.vbproj level that you can add under advanced compile options "..\..\..\PreBuild.cmd" for a more surgical approach. As you build projects it will convert the references from hardcoded to "$(ProgramFiles)" which will load and build in either 64 or 32 bit environment. This will prompt you to reload the project during the build if it finds references that must be changed. Otherwise it will let the build continue normally.

Saturday, November 6, 2010

Manage 2000 7.4 Web - The Beginnings

Manage 2000 7.3 field release is well underway and I have finally got some of the bug reports I have been begging for since Beta. Yes, be careful what you wish for. But each one is a treasure that will make 7.3 sp2 a better more solid product when it launches in Q1 of 2011.

Perspectives 2010 is done and now I can turn my attentions to some serious development work for Manage 2000 7.4. My first major task is to build a foundation for web update functions that will be as nice for the keyboard oriented users as PWS functions and that will be as quick to build for the developer.

There have been 4 or 5 update web functions in Manage 2000 since release 7.1 and the BTO framework has always supported update business object processes. But is is not an easy task to build an update web function and the user experience falters particularly for keyboard oriented folks in scrolled set scenarios.

It is remarkable how effective one level of de-normalization in the user interface can be. When you look around at the thousands of Manage 2000 PWS functions almost all of the screens are a collection of single valued prompts with a few scrolled sets. The application developer can express the modeling of complex business processes quite efficiently with this one level de-normalization, taking the user through multiple screens/pages traversing deeper business processing levels. And I wonder if this does not reflect a characteristic of human perception to be interested in a set of data and its immediate context, but no further.

Using grids to implement scrolled sets is like converting an all-terrain vehicle into a riding lawn mower; sure it can be done, but is it the most practical approach? The programming model is too complex and the performance too poor. A much leaner model that only does what is required for scrolled set entry and does not try to be a generalized do everything-2-dimensional container is needed.

So here I am re-casting the SCROLL.MAINT logic Doug wrote 20 years ago into an HTML/JavaScript mold. Am I going backwards, or am I bringing those things that worked and added value into the Dot World?

Tuesday, September 21, 2010

REST Web Services from UniBasic

In the midst of working up some labs for Perspectives I started thinking about REST web service access from UniBasic. The lab I happened to be working-up is on SOAP based RPC web service usage, for which we have a number of working examples and implemented projects.

But in creating services for Manage 2000 internal consumption I have all but abandoned SOAP RPC in favor of the far more elegant JSON REST model. I am usually working in ASP.NET and IE DOM client land, thankfully with the prototype.js library. So the question of the day was what would REST JSON access look like from UniBasic and what are the central issues in using it?

Well in addition to all the SOAPRequest support added with the UniBasic Extensions are a couple of simple little commands for retrieving the content from a URL. Now URLs often return HTML intended for human consumption and are not very easy to parse. The JSON REST model however returns very nice orderly string serializations.

With something as simple as:

CREATE.REQUEST.RTN.CODE = createRequest(URL:"?":QS,HTTP.METHOD,HTTP.REQUEST.HANDLE)
SUBMIT.REQUEST.RTN.CODE = submitRequest(HTTP.REQUEST.HANDLE,'','',HTTP.RESPONSE.HEADERS,HTTP.RESPONSE.DATA,HTTP.RESPONSE.STATUS)

you can get orderly responses like:

HTTP.RESPONSE.DATA = {'oValItem':{'FileName':'CM', 'TableNbr':'', 'ItemId':'1024
', 'NewItemId':'1024', 'Valid':'True', 'Display':'Sears Systems, Incorporated',
'ErrorFlag':'False', 'ErrorMsg':''}}

UniData does not yet include a JSON DOM to match the XML DOM of the UniBasic Extensions, but the parsing difficulties of JSON serializations are relatively minor. And if you need to directly access JSON REST services in the middle of UniBasic code this seems like nice direct approach.

The real stumbling blocks aren't coding difficulties, but security of your application server if you open up the HTTP or HTTPS ports for UniBasic to "see" services on the Internet. One answer to this is to go through a proxy server. This also points out one of the benefits of the architecture of Manage 2000 with its ASP.NET arm which may be used in a similar manner to delegate interaction with the messy world away from your closely guarded business database into a DMZ area.

Thursday, September 2, 2010

Dynamic Dropdowns and TM JSON arrays

Whether you call it RIA or Web 2.0 or AJAX enabled, there is an evolutionary process taking place on the web these days with UIs morphing from BLOCK-TERM like full page postbacks to much more granular dynamic changes in the page as the user interacts with it. And you can certainly see the effects of this progression in Manage 2000 release 7.3.

A developer friend asked if I preferred coding in VB in the code-behind ("code-beside" in the new parlance) or on the client using javascript and such. This is one of those questions that makes my brain churn for awhile.

The central conclusion I finally came to was that if it makes the UI more convenient for the user, that I dynamically change control configurations (like reloading drop down options based on previous answers they've selected) as they progress through a page then I prefer taking manual control on the client using javascript. I still use code-behind and aspx templates to push the HTML out in the first place, but then shift to javascript-AJAX-JSON-DHTML to make the user interface reactive and dynamic so that it responds more intelligently to the conversation that the user is having with it without having to pause and reprocess major Page construction code.

So how does one go about dynamically loading an HTML SELECT with options from a Manage 2000 TM table?

I have added a new service called GetTMTable in /mt/JSONServices for just this purpose, using much of the same code as my last post:

Private Function GetTMTableAsJSONArray(ByVal context As HttpContext) As System.Text.StringBuilder
Dim TableNbr As String = context.Request.QueryString("TableNbr")
Dim result As New System.Text.StringBuilder
Dim arTableEntries As New System.Collections.Generic.List(Of Array)
Dim ds As New ROISystems.Components.roiDataSet
Dim TableMaster As New ROISystems.WebControls.roiTableMaster
ds = TableMaster.GetTable(TableNbr)
For Each entry As DataRow In ds.Tables("VALIDATION_Validation_Info").Rows
Dim row() As String = {entry.Item("Code"), entry.Item("Desc")}
arTableEntries.Add(row)
Next
Dim JSONSerializer As New System.Web.Script.Serialization.JavaScriptSerializer
result.Append(JSONSerializer.Serialize(arTableEntries))
Return result
End Function

Here is the js portion of my testcode.
function LoadTable() {
var Site = document.location.pathname.Field('/', 2, 1);
var svcUrl = document.location.protocol
+ '//' + document.location.host
+ '/' + Site + '/MT/JSONServices/GetTMTable.ashx';
var TableNbr = $F('TableNbr');
var qs = 'TableNbr=' + TableNbr + '&Cid=' + $F('hedtcid');
new Ajax.Request(svcUrl + '?' + qs, {
method: 'get', asynchronous: false,
onSuccess: function(transport) {
var arTableEntries = transport.responseJSON;
// clear and reload the dropdown with the new table
$('ddlTMTable').options.length = 0
$A(arTableEntries.each(function(item) {
var opt = document.createElement('option');
opt.text = item[1];
opt.value = item[0];
$('ddlTMTable').options.add(opt);
}))
}
});
}


The result is blindingly fast reloads of the dropdown list from various tables.

When you do finally postback you will run into some MS security checking unless you disable event checking in the page declaration in the aspx file, or in a web config setting:
@ Page EnableEventValidation="false"
or
pages enableEventValidation="false"

You may also run into occasional confusion during postback on the part of webcontrols code trying to figure out why what is coming back doesn't match what was sent out. To avoid this confusion you can either just use plain ol HTML controls or check the Request.Form("lbID") array directly if it gets to be a problem.

Unfortunately I had to change the roiTableMaster control to remove a dependency on roiPage so that it would work out of JSONServices. This makes it difficult to patch, but it is all better for 7.3 sp2.

In the mean time you could, of course, implement a version of /mt/JSONServices that descends from roiPage rather than IhttpHandler, it just would have all the application overhead that roiPage carries around.