View RSS Feed

Development Team Blog

Migrating from 17.1 to 18.0: DataFlex Web Framework Structure Change

Rating: 2 votes, 5.00 average.
If you are migrating a web application from Visual DataFlex 17.1 to DataFlex 18.0, you might need to take an extra step to get your application to successfully compile and run in the new revision.

This is due to a change in the tWebRow structure used in DataFlex Web Framework.


To understand the two main reasons for this change it is important to understand how this worked under 17.1.

When the DataFlex web framework was developed, cWebList and cWebGrid controls were the first that needed to send complex data to the client. For this reason, we created a system for adding an array of tWebRow structs to client actions.

Later on, we identified the need of controls from other classes (like cWebTreeView and the cWebCombo) to send complex data to clients. In order to keep the same message format, we made use of the tWebRow structure for those classes as well.

In 18.0, while looking into extending the functionality of the cWebList with features like the new column types and custom row CSS, we realized that the tWebRow struct we had couldnít accommodate these features very well. We also realized that the use of tWebRow by various classes made it harder to make changes and adjust classes independently.

We understood that by extending the tWebRow struct various classes would be affected and we would be breaking backwards compatibility. We had to weigh the pros and cons of the change: this was only the second release that included tWebRow structure and if we did not improve the structure now, we would have to live with a not-so-good solution for a long time. Because of that, we decided to implement the best solution rather than adopt a mediocre solution that would keep your source code backwards compatible.

So we improved the system by doing two things:

  • First, we changed the data format from including tWebRow to including tWebValueTree as parameter for client actions.

When using ValueTreeSerializeParameter controls now can send any struct format to the client. On the client a new package (df.sys.vt) allows to deserialize these value trees into a usable format in a uniform way.

  • Second, we changed the tWebRow to a more extensible and better format.

The String[] aValues member only allowed a single string value per cell; we changed this to become a struct (tWebCell[] aCells). When we did that, having item 0 being the rowid made no sense any more so we added the separate sRowId.

We did make sure that this change would cause compiler errors for all the cases where a change was required (thatís why we renamed form aValues to aCells for example). This way, you will be able to catch all occurrences of the structure that you will need to review and adjust in your source code.


If your 17.1 web application manually fill lists or grids using tWebRow structure (aValues array), after running the automatic Migration Wizard in the Studio, you will need to inspect your code looking for tWebRow and make adjustments.

The tWebRow struct has changed from

    String[] aValues


Struct tWebCell
    String sValue
    String sTooltip
    String[] aOptions

Struct tWebRow
    String sRowID
    String sCssClassName
tWebCell[] aCells
If your application makes use of tWebRow, you will need to search for each .aValues within the application and replace with the corresponding variable from aCells. For example, all .aValues[0] should be replaced with .sRowID and all other aValues[n] should be replaced with .aCells[n-1].sValue since aValues[0] became sRowID.

In the WebOrder sample, DemoFileDialog.wo (oDemoFileDialog cWebModalDialog object) had the following piece of code:
// Populate the row....
Move sFileName to aTheRows[iRow].aValues[0]     // row id
Move sFileName to aTheRows[iRow]. aValues[1]    // File Name
Move sSize     to aTheRows[iRow]. aValues[2]    // File Size
That had to be changed to the code below to conform with the new tWebRow structure:
// Populate the row....
Move sFileName to aTheRows[iRow].sRowID              // row id
Move sFileName to aTheRows[iRow].aCells[0].sValue    // File Name
Move sSize     to aTheRows[iRow].aCells[1].sValue    // File Size
Important: If the change described above is not made, you will experience compiler errors when trying to compile/run a migrated web framework application.

Updated 24-Apr-2014 at 10:03 AM by Dennis Piccioni