Johan Broddfelt
/* Comments on code */

Work with external js libraries in DataFlex

I have been assigned a project where I need to show some graphs inside of a DataFlex application. So I needed to integrate a graph library into the DataFlex project. In this post and the video above I highlight the key points in order to get a complete integration to work.

Include the library

External librarys come with some premade source files that you need to load in your html header section of Index.html. Then you have another part where you use the functionallity of the library in order to show something on the screen. This code I have put in a separate file called graph.js. But you can place it in the Index.html as well if you prefere that.

<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script src="js/graph.js"></script>

Sending the data

We can use any data we manage in the system as long as we compos it into a string that matches the data the library expects. And in order to add a placeholder for the graph I created an WebHtmlBox called oGraph_box and with a separate procedure filled it with html containing the data and the elements I needed to render the graph.

Move "[['Mushrooms', 15],['Onions', 1],['Olives', 7],['Zucchini', 1],['Pepperoni', 2]]" to sData

Move (sHtml + '<div id="chart_div"></div>') to sHtml
Move (sHtml + '<input type="hidden" id="graph_data" value="' + sData + '">') to sHtml
            
Send UpdateHTML to oGraph_box sHtml

In order to recieve the data in the javascript I need to read the value of graph_data and turn that string into an object. This is how I managed that:

// Get the string from the element graph_data
var dataObj = document.getElementById('graph_data');

// Change all the single quotes (') to double quotes (") in order for it to be valid JSON
dataObj.value = dataObj.value.replace(/'/g, '"');

// Add additional structure to the string in order to make it a valid JSON string and then use JSON.pars to turn it into a js object
var graphData = JSON.parse('{"data": ' + dataObj.value + "}");

// Now I can feed the graph enging with the data like this
data.addRows(graphData.data);

But before any of this occurs I need to execute it from the serverside. And I do that by containing all of the javascript code in a function I call "runGraph"

var runGraph = function() {
	// your js code
};

And then I call that from the server by activating the pbServerOnShow property and telling it to call runGraph with the psClientOnShow property.

Set pbServerOnShow to True
Set psClientOnShow to "runGraph"

Now the code will generate a graph on the page.

Handle events

Now I would like to be able to send data back to the server when I interract with the js library. And in order to do that we need to start to add a procedure that can recieve the call from the view. Inside of the oGraph_box I added the following:

// On order for the object to allow events from the client we need to activate the pbServerOnClick for this object
Set pbServerOnClick to True

Procedure OnClick String sId String sParam
	If (Trim(sId) <> "") Begin
		// Here you can do what ever you like with the data you get back
		Showln ("You pressed " + sId)
	End
End_Procedure

In order to call this procedure placed in oWebApp -> oGraph -> oWebMainPanel -> oGraph_box you need to use the following call:

// call fire on the element and then say what procedure to call and include an array with elements
oWebApp.oGraph.oWebMainPanel.oGraph_box.fire('OnClick', [data.getValue(selectedItem.row, 0)]);

// You may also do a set, in order to change a property of an element
oWebApp.oGraph.oWebMainPanel.oGraph_box.set("pbRender", false);

If you enjoy this video then don't forget to go into the channel on youtube and subscribe or add your mail to my newsletter. You may also want to see all episodes of Discovering DataFlex available on youtube.

UPDATE...

There are some issues with this implementation and I will try to explain them here:

There is a race condition between the rendering of the data and the execution of the graph rendering javascript. I had to use a function like the one below to delay the execution of the graph rendering javasript in order to avoid the race condition.

var execPortal = function() {
    //runPortal();
    var jsonElem = document.getElementById('json_data');
    //console.log(jsonElem);
    if (jsonElem !== null) {
        //console.log('activate');
        runPortal();
    } else {
        setTimeout(execPortal, 10);
    }
};

Then when you re-enter the page you will have another problem with jsonElem not being null so you need to remove it after you have read the data like below.

var jsonElem = document.getElementById('json_data');
var jsonData = JSON.parse(jsonElem.innerHTML);
jsonElem.remove();

Hope this solves your issue

- DataFlex javascript library integration

Follow using RSS

<< Build a Conference App part 3 Chilkat RSS reader using ActiveX >>

Comment

Name
Mail (Not public)
Send mail uppdates on new comments
5 comments
The system will prompt an error call "Unhandled Program Error on the client", description state that the "event handler function 'runGraph' set as 'psClientOnShow' not found.​" with an error code of 999 and the object. Sorry for the double post.​
2018-08-30 03:12:55 - sgprogrammer
This sounds like the race condition I just added a comment about at the end of the blog post.​
2018-08-29 13:01:46 - Johan
After i input (Set pbServerOnShow to True, Set psClientOnShow to "runGraph") and start the project, the system will prompt handler error and the google chart will not appear. Any idea what is the issue regarding the chart not appearing?​
2018-08-29 10:25:32 - sgprogrammer
I have added an update to the post. I'm not sure if this solves your problem. It was a long time I looked at this so I need to do some digging to figure out what might be up with your code.​
2018-08-29 10:02:23 - Johan
After i input (Set pbServerOnShow to True, Set psClientOnShow to "runGraph") and start the project, the system will prompt handler error and the google chart will not appear. Any idea what is the issue regarding the chart not appearing?​
2018-08-29 09:36:40 - sgprogrammer