Categories: Servoy Mastery

Take Back the UI with OOP

This Servoy tutorial uses object-oriented programming (OOP) and applies what we learned in the prior tutorial to a real-world scenario. The goal is to toggle groups of elements on a form elegantly with an object-oriented design.

Photo Credit: Roger Smith via Compfight.

Like most developers, you are probably pressed to pack more and more onto the limited screen real estate that your user interface (ui) specification permits. As applications become more complex, our user interfaces begin to look crowded, and the clean design we were striving for in the beginning, is lost in an overwhelming sea of fields, labels and tab panels.

A common strategy to keep the ui from getting crowded is to group less commonly used fields together and hide them, allowing the user to reveal them when then need to see them or input data. Often times this is done in Servoy using tab panels, but sometimes using an entire tab panel for a small number of elements is overkill, and other times, using a tab panel is just plain ugly.

Writing loops and conditional logic to show or hide elements takes a lot of work, and typically relies on elements using a naming strategy so they can be processed as a group. Sometimes things are handled worse, and a web of “if” or “switch” statements tries to control the elements based on a toggle event fired by the user.

Well, there is an alternative, and that is to use object-oriented programming to toggle the elements. Here again is the code that is going to do most of the work; it will process an array of elements and set their visible property to true or false depending on which method you call in the object. The object constructor is using the revealing module pattern which was discussed in a prior Servoy tutorial.

function ElementGroup(visible){
    var groupOn = function(key){
        var iSize = this[key].length;
        for (var i = 0; i < iSize; i++) {
            elements[this[key][i].getName()].visible = true;
        }
    };
    var groupOff = function(key){
        var iSize = this[key].length;
        for (var i = 0; i < iSize; i++) {
            elements[this[key][i].getName()].visible = false;
        }
    };
    return {
        groupOn: groupOn,
        groupOff: groupOff
    }
}

Okay, let’s go through a scenario of how to use this on a Servoy form. Assume for a moment that we have three groups of additional fields that we want to control on our form. The user should be able to toggle them so they can see them, and also hide them. It doesn’t really matter what kinds of elements we use here, they can be fields, combo boxes, radio buttons, even tab panels; they will all be handled the same way. In my example, I am going to use just labels and fields.

The first thing I am going to do is create a form variable that will hold my object. It looks like this:

var _oElements = {};

The next thing I will do is layout my panels of options that I am going to use. I do this normally, as though these fields and labels will always be showing on the form. I create two versions of the button that will be used to fire the methods that will turn the elements on and off. In this case I am using arrows to indicate the show/hide status of the optional information, but you could use any kind of visual indicator that works. Once I have my elements laid out on the form, I group my toggle button elements together, in my case the blue “Options Panel 1” shown below. I also group all the other optional fields and labels together, in this case everything else shown below, and move the group to the front in the layout so it will cover anything behind. It also makes sense to use a label with a border behind the optional fields and labels, so that it will hide anything behind it when shown. Once I have the two groups, I move them into position on my form.

The next step is to create the additional groups of control buttons and option panels. For this demo, I simply duplicated my first two groups, and created a total of three control button group,s and three option panel groups. I moved everything into position on the form as shown below in layout mode (notice the stacking of the groups is important).

Next I created an initialization method for the form’s onLoad event. In the method, I create a new object using the constructor we defined earlier, and then add all the elements for each of the panels to arrays in the object. I then assign the object to the form variable we created earlier. The last thing I do is set an object visible property for each panel to “true”, and call the toggle methods so they will be hidden when the form loads.

function initElements(){
 var oElements = new ElementGroup(true);

 oElements.panelOn_1 = [
  elements.lbl_1,
  elements.lbl_2,
  elements.lbl_3,
  elements.fld_1,
  elements.fld_2,
  elements.fld_3,
  elements.bkgnd,
  elements.btnTogglePanelOn
 ];
 oElements.panelOff_1 = [
  elements.btnTogglePanelOff
 ];
 oElements.panelOn_2 = [
  elements.lbl_1c,
  elements.lbl_2c,
  elements.lbl_3c,
  elements.fld_1c,
  elements.fld_2c,
  elements.fld_3c,
  elements.bkgndc,
  elements.btnTogglePanelOn
 ];
 oElements.panelOff_2 = [
  elements.btnTogglePanelOffc
 ];
 oElements.panelOn_3 = [
  elements.lbl_1cc,
  elements.lbl_2cc,
  elements.lbl_3cc,
  elements.fld_1cc,
  elements.fld_2cc,
  elements.fld_3cc,
  elements.bkgndcc,
  elements.btnTogglePanelOn
 ];
 oElements.panelOff_3 = [
  elements.btnTogglePanelOffcc
 ];

 _oElements = oElements;

 // Initially toggle the elements off
 _oElements.visible_1 = true;
 _oElements.visible_2 = true;
 _oElements.visible_3 = true;
 btnTogglePanel_1(null);
 btnTogglePanel_2(null);
 btnTogglePanel_3(null);
}

I then create the methods that will toggle each of the panels and hook the methods up to the button onAction events.

function btnTogglePanel_1(event) {

 // Toggle the elements
 _oElements.visible_1 = !_oElements.visible_1;
 if (_oElements.visible_1){
  _oElements.groupOn("panelOn_1");
  _oElements.groupOff("panelOff_1");
 }else{
  _oElements.groupOff("panelOn_1");
  _oElements.groupOn("panelOff_1"); 
 }
}

function btnTogglePanel_2(event) {

 // Toggle the elements
 _oElements.visible_2 = !_oElements.visible_2;
 if (_oElements.visible_2){
  _oElements.groupOn("panelOn_2");
  _oElements.groupOff("panelOff_2");
 }else{
  _oElements.groupOff("panelOn_2");
  _oElements.groupOn("panelOff_2"); 
 }
}

function btnTogglePanel_3(event) {

 // Toggle the elements
 _oElements.visible_3 = !_oElements.visible_3;
 if (_oElements.visible_3){
  _oElements.groupOn("panelOn_3");
  _oElements.groupOff("panelOff_3");
 }else{
  _oElements.groupOff("panelOn_3");
  _oElements.groupOn("panelOff_3"); 
 }
}

This is what the option panels look like when the form loads.

 This is what it looks like when the “Options Panel 1” button is toggled.

  This is what it looks like when the “Options Panel 2” button is toggled.

  This is what it looks like when the “Options Panel 3” button is toggled.

Pretty straight-forward, right? Now, we could get fancy and move control buttons below the options panel when expanded, but I tried to keep this example simple. Besides, that’s a good project for you to tackle now that you know a little more about objects and how to work with them.

Keep in mind that this was a simple example, and many times the options panel can be a large collection of elements. In that case, it often makes more sense to change the color of the button, for example make it green when a big options panel is shown to the right. In this manner, you can use the minimal amount of screen real estate, and only show one group of elements at a time to the right of the buttons. You can even toggle the next set of options automatically when the user tabs out of the last field. The possibilities are really unlimited.

I hope that this Servoy tutorial gave you some further insight on how to use object-oriented programming and that this technique will help you clean-up that user interface.

Dotzlaw Consulting

Dotzlaw Consulting brings over 20 years of experience in professional software development, serving over 100 companies across the USA and Canada. Specializing in all facets of the project lifecycle—from feasibility analysis to deployment—we deliver cutting-edge solutions such as AI-powered workflows, legacy system modernization, and scalable applications. Our expertise in Servoy development and advanced frameworks allows us to modernize fixed-positioning solutions into responsive platforms like ng Titanium with Bootstrap and core.less styling. With a passion for knowledge-sharing, our team has authored numerous tutorials on topics like object-oriented programming, AI agent development, and workflow automation, empowering businesses to achieve scalable, future-ready success.

Recent Posts

Optimizing Code Performance

This is a Servoy tutorial on how to optimize code performance. A while back, I had…

12 years ago

Servoy Tutorial: Using an Object as a Cache

This is an object-oriented Servoy tutorial on how to use an object as a cache in…

12 years ago

Function Memoization

This is an object-oriented Servoy tutorial on how to use function memoization with Servoy. Function memoization…

12 years ago

Object-Oriented Programming

This is an object-oriented Servoy tutorial on how to use object-oriented programming in Servoy. Javascript’s core…

12 years ago

Inheritance Patterns

This is an object-oriented Servoy tutorial on how to use inheritance patterns in Servoy. I use…

12 years ago

Prototypal Inheritance

This is an object-oriented Servoy tutorial on how to use prototypal inheritance in Servoy. When…

12 years ago