PowerBuilder Authors: Chris Pollach, Yeshim Deniz, Jayaram Krishnaswamy, Kevin Benedict, Avi Rosenthal

Related Topics: PowerBuilder

PowerBuilder: Article

Using the Tag Property – Part 3

The use of the tag property of DataWindow columns

This is the third and final part of a series presenting a proposal for the use of the tag property of DataWindow columns. My original thought was to provide a means to automatically set a microhelp for each column. Of course, if you are using an MDI application you have a function to set the microhelp, but that function is only available in MDI. If you are using any other application type, then this is not available to you.

Even if you do have an MDI, I have found that the microhelp is not as useful as I would like. The microhelp is always on the frame, nowhere near the column. The user might miss it entirely.

In order to implement something that might be a bit more useful, we created several objects in our tool library that, when used together, will give us the functionality that we seek. You will need those objects to reproduce what we are doing here. If you don't have them from previous articles you will still be able to find them in the downloadable source code for this article.

First we have to consider what we want to do. One of the most common things that I like to do is associate a "pre" and "post" event to a DataWindow column. We can set it up so that we have an event that we use before the column gets focus, sort of like the preOpen and the postOpen events of a window in the PFC. To do that we need to be able to have two different values in the tag attribute. One is good for naming the pre-event and the other the post.

Of course the very first thing is to decide upon the metaphor. How do we want to distinguish the pre-event from the post? We have a tag, which is a string. How do we separate the values?

On the one hand we could use the ini file metaphor, key=value. We would still be left with the problem of multiple values. We could do something like this:


I prefer another style that I picked up somewhere:


We will need to expand our DataWindow object to load all of the key/value pairs into our key_value pair object when the column is getting focus.

Start with a DataWindow
The first thing that we need is a DataWindow that will give us something reasonable to use. Let's do an employee editor DataWindow.

Create a new DataWindow with a freeform presentation style. It will need a SQL Select data source. Select all the columns and then sort them by last name and first name.

Of course the DataWindow will need to be formatted. It doesn't look good at all. The emp_id should be read-only so let's make that a computed field.

We need to create a drop down for both the department and the manager fields. They are IDs but if we make a drop down DataWindow, they can display the names. So we'll need two new DataWindows. I like to name these dddw_department and dddw_employee because I may want to reuse them elsewhere. It's a good idea to put them in their own pbl so you can always find them quickly. I'm putting them in my tools pbl.

Both of the drop downs will be read-only so let's remove all the columns and add a computed field. The computed field for the employee drop down has this expression:

‘(‘ +  emp_id + ‘) ‘ +  emp_lname + ‘, ‘ +  emp_fname

The drop down DataWindow for the department is a little more complex but not too bad. You need to select the department name from the department table. In the department table you'll find a column named dept_head_id. Use that to join to the employee table and get the name of the department head (see Figure 1).

Figure 1

Note that if you first choose the department table, then the employee, your join will be on the dept_id. You will need to change that. If you open the employee table first, then the join will be what you want.

Finally order this by department name. Then you delete all the objects off the DataWindow painter and add a computed field. Here's my expression:

department_dept_name + ‘ (‘ +  employee_emp_lname + ‘, ‘ +  employee_emp_fname + ‘)'

After we format the DataWindow, we put it into a window and retrieve it. Of course that window needs to be opened from our application open event.

Let's add a static text under the DataWindow. We'll use that for our test. Your window should look something like Figure 2.

Figure 2

Finally We Get to the Point of the Articles
What we really need is an event that will act like the rowFocusChanging event but for columns. Let's create that. We need to pass that event the column that we are leaving and the one to which we are going. We do this in u_dw and start by adding an instance variable to hold the last column that we were in. When we have done that these will be our instance variables:

U_dw instance variables
private string is_selection_mode = "n"
private n_cst_dw_row_helper idw_row_helper
private u_dw_microhelp io_microhelp
private boolean ib_microhelp_registered = FALSE
private string is_last_column = ""
n_cst_key_value_collection io_key_values

Note: the last variable will be used later in this article. Bear with me.

We will use the is_last_column to store the last column we were in. As you can see, it's initialized to an empty string. The next thing we need to do is create an itemFocusChanging event like the rowFocusChanging. It doesn't need any code. It just needs to be there and accept two string variables. Here's the code for it:

U_dw. itemFocusChanging
// string as_old_column
// string as_new_column
// As_old_column is the column we are coming
// from. as_new_column is the column we are going to

Now we need to call this column from the ItemFocusChanged event. Here is the code:

// ARGUMENTS Long row, dwo the column
// If there is a tag property set for the dwo and if the microhelp is instantiated
// I display that tag
// Then we need to call the new itemFocusChanging events passing
// the old column and the new one.
// 3/26/2011 Rik Brooks
// 5/20/2011 Rik Brooks - added the call to the itemFocusChanging

IF ib_microhelp_registered then io_microhelp.text = dwo.tag
trigger event itemFocuschanging( is_last_column, dwo.name)
is_last_column = dwo.name

So now we have an event that will allow us to handle both leaving a column and entering into it. This is just what we need.

Automating Our Events
The next thing is to add code to our new event that checks for a tag in both columns. If we have a "post" event tag in the old, then we do that first. Then we check to see if there is a pre-event tag in the new column and do that one.

There is a little twist to this event. We don't know how many commands we might have on the tag. We could have just one, or both, or at some time in the future we may have many. Here is where we need the key / value object. Look in the tools pbl and you will find n_cst_key_value_collection. Once again, if you don't have the tools.pbl then you can download it or email me and I'll send it to you.

There are only two functions in this object that concern us. We will need of_add and of_value. We call of_add from the itemFocusChanging event.

As I considered what I was going to do I realized that I missed an essential function in the key value object when we created it. I forgot to add a function that lets me clear the object so it can be reused. Let's open that object and add the of_clear function:

// resets the object so that it holds no values

ids_key_value.reset( )

Here is where we use that mysterious instance variable that I spoke of before, the lo_key_values. It will hold the values on the tag for the current object. First we have to create it. We do that in the constructor of u_dw:

Constructor of u_dw
// DESCRIPTION - initialize variables

io_key_values = create n_cst_key_value_collection

Now in itemFocusChanging we add the code that makes all this work.

U_dw. itemFocusChanging
// string as_old_column
// string as_new_column
// As_old_column is the column we are coming
// from. as_new_column is the column we are going to.
// It also handles pre and post events for the column

if io_key_values.of_count() > 0 then
// We have values on the tag of the old column
string ls_event, ls_tag

ls_event = io_key_values.of_value( "post_event")
if len(ls_event) > 0 then triggerevent(ls_event)
end if

// Post event is done. Now we clear out the key values
// and load it with the new column.

ls_tag = this.describe(as_new_column + ".Tag")
if len(ls_tag) > 0 then
// We have a tag, load it into our key value object
// Format is [key]value
int li_left, li_right, li_next_left
string ls_key, ls_value
li_left = pos(ls_tag, "[") // the first left bracket
do while li_left > 0
li_right = pos(ls_tag, "]", li_left)
if li_right > 0 then
ls_key = mid(ls_tag, li_left + 1, li_right - li_left - 1)
li_next_left = pos(ls_tag, "[", li_right)// Now find the next key
if li_next_left > 0 then
ls_value = mid(ls_tag, li_right + 1, li_next_left - li_right - 1)
ls_value = right(ls_tag, len(ls_tag) - li_right)
end if
// Finally we can add to our key values
io_key_values.of_add(ls_key, ls_value)
li_left = li_next_left
// If there is no right bracket then we are done, something
// somehow got corrupted. Just forget the whole
// thing
li_left = -1
end if
end if

// Done. Now let's see if there is a pre event for the new one
ls_event = io_key_values.of_value( "pre_event")
if len(ls_event) > 0 then triggerevent(ls_event)

Almost Done
Basically we are in fact done, but we need a test. Go back to your d_employee DataWindow. Go to the emp_fname column and put this in the tag:


Finally open w_main. Add two new events to dw_1. Call one ue_pre and the other ue_post. Put a messagebox in each. Now run your application. When you enter the first name field the ue_pre event will fire. When you leave the column the ue_post event will fire.

Obviously you could have as many events as you like. You can have a ue_pre_name, ue_prev_city, etc. You can go farther too. You can add other types of tag commands. All the commands will automatically be in the key value object. You can just add functionality for them in your itemFocusChanging event.

Oh yeah, that brings up one other thing - I bet you'll find a lot of uses for the itemFocusChanging event other than the tag values.

Source Code

More Stories By Richard (Rik) Brooks

Rik Brooks has been programming in PowerBuilder since the final beta release before version 1. He has authored or co-authored five books on PowerBuilder including “The Definitive DataWindow”. Currently he lives in Mississippi and works in Memphis, Tennessee.

Comments (0)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.