User interface developers often come across situations that involve creating several web interface dashboards with similar architectures but with different UI controls and backend services serving real-time data. Examples of such Dashboards could be real-time stock quotes, or real-time performance of a factory floor.
A common approach that many follow is to create an HTML5/CSS3 web application using a standard design pattern. Every time we have to create a new Dashboard, we try to use reusable components from UI or backend services and develop new controls and Dashboards. This approach is okay, but raises a thought.
It would be so nice to have a UI Designer where we can drag & drop custom HTML5 controls, set properties at design time, and then our Dashboard is ready (with no actual code development needed).
Alright, the above statement looks quite interesting, but raises some obvious questions:
- How can we generalize custom HTML5 controls that can be used seamlessly across any Dashboard? Some new Dashboard requirements could be quite different and may not be covered with existing Designer.
- What about server-side data? How can we generalize it?
- UI layout requirements may be very different, so how can we ensure that our designer will meet all those requirements?
In this blog, I want to discuss an approach and some guidelines for developing such a web UI Designer.
Meta Data Definition
Before we start designing our Web UI framework, let’s talk about Meta Data definition.
Look at the following JSON structure:
-{
"WidgetId": "Widget",
"id": "xxx",
"WidgetFileName": "grid.locale-en.js,jquery.jqGrid.min.js,
jquery.sparkline.min.js,WebUIGridEx.js,GridWrapperEx.js",
"WidgetClassName": "ui.jqgrid.css",
"WidgetName": "WebUIGridEx",
"top": 25,
"left": 25,
"width": 20,
"height": 20,
"props": -[
-{
"id": "grid1",
"groupid": 1,
"GroupName": "Field Selection",
"parentid": -1,
"DisplayName": "Select Field:",
"FieldName": "fields",
"Value": "",
"Type": "select",
"ValidationRule": "",
"DefaultValueKey": "field_name",
"DefaultValue": null,
"DataSource": "server_name;8080;GetFields",
"Attributes": -[
-{
"FieldName": "field_name",
"DefaultValueKey": "field_id",
"Value": "",
"PrimaryKey": "1"
}
],
"callback": "change"
}
If you take a closer look into this structure, you will realize that we are defining contents and behavior of an HTML5 control.
For example: what all fields we want to render, what should be the layout of these fields, and how these fields will be populated (defined under DataSource filed in JSON file).
Build Property Tree
Next step would be to develop a JavaScript plugin that renders this JSON file and creates an in-memory property tree.
Note that this JSON file could be very complex with multiple levels of nesting, so our JS plugin has to be very generic and should consider all possible cases. This requires a lot of thought, process, and design skill.
Anyways, I am providing some plugin prototypes from my Property Tree plugin just to give an idea:
this.PropertyManager.prototype.ProcessProperty = function (callback, key) {
var subTree = this.propTree.GetSubTree(key).propTree;
};
this.PropertyTree = function (source) {
this.Source = source;
};
this.PropertyTree.prototype.BuildTree = function (saved) {
var thisobj = this;
var BuildTree = function (data) {
Array.prototype.insertChildren = function (parentid, childobj) {
found = false;
for (var i = 0; i < this.length; i++) {
}
}
return false;
};
$.each(this.Source, function () {
gPropCache.Add(this.value.WidgetId, this.value);
}
});
};
this.PropertyTree.prototype.GetProperty = function (key) {
return (prop);
};
this.PropertyTree.prototype.Save = function (callback, key) {
this.PropertyTree.prototype.FindNode = function (id, key) {
return Traverse(gPropCache.Get(key).propTree);
};
this.PropertyTree.prototype.GetSubTree = function (key) {
return gPropCache.Get(key);
}
this.PropertyTree.prototype.ProcessTree = function (callback, propTree, parentNode) {
proxy.getNamedService(
function (result) {
});
done = true;
},
inputparam, temp[2]);
delete proxy;
}
else {
done = true;
}
callback(thisprop);
};
With Meta Data definition and Property Tree plugin, we can now design our HTML5 controls and use reflection to extract all public
properties and interfaces, and present that to the user on our Web UI Designer.
The agenda for this post was just to give an introduction of the thought process and open a forum for suggestions and ideas. I haven’t provided the complete code and implementation, but plan to do that in my next blog (to be posted soon). Additional blogs will also show a real example with a step-by-step process to create a plugin and then integrate in the UI Designer. Stay tuned!
– Alok Pandey, asktheteam@keyholesoftware.com