Images in Web 5250 - Part 2

In Part 1 almost a year ago we described basic image support inside our web terminal. As we added more new features and improvements in the last 12 months, it's time to write about image support again to introduce you with new screen data to image linking engine.

We added a new Tn5250.Image class  to our Web API engine which purpose is to register image URL service  to specific screen, screen position and user action. The rendering engine will show an image on a terminal screen based on provided data.

All what is needed is to register image retrieval URL.

 var o = {
        "name": "img_avatar_1",
        "url": "/lite/img/${val}",
        "opt": {
            "type":"click",
            "target": {"r1": 10, "c1":50, "r2": 24, "c2":79 }
        }
    }
 Tn5250.Image.registerImageService(o);

JSON configuration object contains instructions where to show the image, which action (click, hover or fixed) will trigger it, and finally which screen data to use for image retrieval. This is a very simple example of much powerful options available which we will present later in this text.

To get a feeling what is possible, please watch this short video first before reading the rest of the blog post.

Example

In this example we will show a basic image popup when the user clicks at any position on any terminal screen.  Engine will pick up text between left and right color attributes (view them with ALT+A). The retrieved value will be injected into the image element instead of ${val} and then showed on the screen as an image popup.

var url = '/lite/img/${val}';

var opt = {
    type:'click',
    target: {r1: 10, c1:50, r2: 24, c2:79 }
};

Tn5250.Image.registerImageService('img1', url, opt);

For a test, execute sample code above and go to the terminal screen with command line. In command line enter logo.png. The Image panel should pop up in the bottom right corner. By moving the mouse over / out of the image, the image will disappear.

If we replace type:'click' to type:'fix', the image will be automatically rendered on specific area defined by target parameter each time new screen arrives. By using type:'float', the image will pop up just by moving the mouse over any text area.

If option window is set to true,  engine will create new named popup window with generated image URL.

Screen Matcher

To improve performance and avoid showing image popups every time user clicks or move mouse, or to prevent showing popup for uninterested screen area, we need to define screens for which we want imaging engine to work.

To do that we will use a screen matching engine. The same one used by Modernization engine.

In this example we will map only screens shown on image above... "Work with All Spooled Files".

Creating matching criteria is a simple process... select row, start col and length of data from which we will create matching hash code...


// area on top of the screen, to extract sccreen title
var row = 0;
var col = 26;
var len = 27

var def = Tn5250.ETL.createHash(row, col , len) ;
console.log(def);

From resulting value we will create simple screen matching criteria (def option).

var url = '/lite/img/${val}';

// screen matching criteria
var def  =  {
    "row": 0,
    "col": 26,
    "len": 27,
    "hash" : 347536357
};

var opt = {
    type:'click',
    match : def,
    target: {r1: 10, c1:50, r2: 24, c2:79 }
};

Tn5250.Image.registerImageService('img1', url, opt);

We can also create more complex matching criteria to match multiple locations on the screen. This can come in handy when there is a lot of similar screens which has very small differences. Here is an example of more complex matching criteria.

{
    "query" : {
        "list" : "txt1 && txt2 && txt3 && txt4"
    },
    "segments" : {
        "txt1" : {"row":3, "col":71, "len": 6, "hash": 1200467185},
        "txt2" : {"row":5, "col":29, "len": 7, "hash": 46586408},
        "txt3" : {"row":16, "col":73, "len":6, "hash": 1405477245},
        "txt4" : {"row":17, "col":13, "len":7, "hash": 628307496}
    },
    "detect" : "list"
}


Auto value

Except leaving the user to use mouse to select potential image data, we can add automatic data extraction with source option. In the example below, an image box will be rendered with image data extracted from defined row, col1, col2 position defined in source option every time when the screen "Work With All Spooled Files " is detected.

var url = '/lite/img/${val}';

var def  =  {
    "row": 0,
    "col": 26,
    "len": 27,
    "hash" : 347536357
};

var opt = {
    type:'fix',
    match : def,
    source: {row: 20, col:6, len:20 },
    target: {r1: 10, c1:50, r2: 24, c2:79 }
};

Tn5250.Image.registerImageService({url:url, name:'img1', opt:opt});

New window target

The Image engine will create a new popup window with generated image URL as a source if the flag window is set to true.



var url = '/lite/img/${val}';

var def  =  {
    "row": 0,
    "col": 26,
    "len": 27,
    "hash" : 347536357
};

var opt = {
    type:'click',
    window: true,
    match : def,
    source: {row: 20, col:6, len:20 },
    target: {
         width:200, 
         height:200, 
         top : 50, 
         left:50 
    }
};

Tn5250.Image.registerImageService({url:url, name:'img1', opt:opt});

Dynamic target

Sometimes screen source is not enough. For more complicated URL generation we can use JavaScript function instead of screen location definition. The Function is responsible to return the correct URL address.


function myFunc(cfg, el) {
  return cfg.url.replace('${val}','test.png');
}

var url = '/lite/img/${val}';

var def  =  {
    "row": 0,
    "col": 26,
    "len": 27,
    "hash" : 347536357
};

var opt = {
    type:'click',
    window: true,
    match : def,
    func: myFunc,
    target: {
         width:200, 
         height:200, 
         top : 50, 
         left:50 
    }
};

Tn5250.Image.registerImageService({url:url, name:'img1', opt:opt});

Rest Service as a Source

Sometimes it is needed to load a JSON definition which contains a path to an image instead of retrieving an image directly. Image engine supports that option as shown in example definition below. Be sure to set rest=true and path='...' as a JSON path to response property containing image URL.

NOTE: Image engine will  cache URL image responses and no further request will be made to the REST service which improves performance and reduce network traffic.

    {
        "name": "img_avatar_1",
        "url": "https://randomuser.me/api/?seed=${val}",
        "opt": {
            "rest": true,
            "path": "results[0].picture.large",
            "type": "float",
            "match": { "row": 0, "col": 24, "len": 32, "hash": 251702275},
            "source": { "row": 6, "col": 7, "len": 5, "grid": 15 },
            "target": { "r1": 1, "c1": 56, "r2": 4, "c2": 62 }
        }
    }

Multiple parameters

It is not always enough to use a single value for URL service. For example, to create PDF417 2D barcode we might need multiple values from the screen. Here is an example showing how to formulate parameterized URL for our new Barcode rendering service.

Notice args property and mapping between URL arguments.

{
  "name": "img_barcode_1a",
  "url": "/barcode/generator?zoom=2&type=PDF417&format=png&text=${arg1}%0a${arg2}",
    "opt": {
      "type": "float",
      "args": {
         "arg1": {"row":6, "col":15, "len":15, "grid":15},
         "arg2": {"row":6, "col":31, "len":12, "grid":15}
      },
      "match": { "row": 0, "col": 24, "len": 32, "hash": 251702275},
      "source": { "row": 6, "col": 15, "len": 15, "grid": 15 },
      "target": { "r1": 2, "c1": 38}
    }
}

Registering Definitions

Image definitions can be saved to io.greenscreens\etl\data as a JSON Array and later loaded with following command.

io.greenscreens.ETLController.getDefinition('/data/images.json', function(json, val, sts) {
    if (!sts) {
        console.log(json);
        return;
    }
    Tn5250.Image.registerImageService(json.data);
});

Conclusion

As video from the beginning of this post shows, it is a very powerful, simple but effective solution which gives 5250 terminals new power.

Possibilities do not end here. Imagine we need to generate product barcode for example. URL can point us to online service which will render barcode image.  

For example http://localhost/barcode_service?id=${val}

Now, we can use a mobile device application to scan barcode to simply pickup screen information and transfer it into mobile without need for typing. This reduces not only human error during data entry, but also enables terminal integration with new technologies and user  interaction  much easier than ever.

We hope you will enjoy this new feature.