|
Comments
Did you read today's front page stories & breaking news?
SYS-CON.TV
|
Features Advanced WebDW HTML Generation
Advanced WebDW HTML Generation
By: John Olson
Aug. 1, 2011 12:00 AM
Okay, so I've been promoting the inclusion of PB client/server articles, yet here I am writing about the Web DataWindow. Don't stop reading! This article applies to all PB developers, whether n-tier or client/server. That said, I now have to prove that this article is important to client/server developers....
Here's my angle: HTML has become a standard beyond Web development. People doing work unrelated to the Web, even nonprogrammers, need to learn the basics of HTML. Here's an example: I'm a consultant and I invoice my customers using QuickBooks. When I generate my invoices I deliver them as HTML files. Sure, I could deliver them as documents or PDFs, but that assumes the recipients have programs to support my document format (Word 2000) or a PDF viewer. What formats do I know they can read regardless of their software? I can think of only two that support graphics: RTF and HTML. In with the new and out with the old! RTF is dead. It's been replaced by HTML, so that's my format of choice. Yes, that was a trivial example, but what it shows is that my bookkeeper, who isn't a programmer, has to know something about HTML, even if it's only that HTML is a broadly supported format. For PBDJ I've had to save documents as HTML, as well as for for my Web site. When I need to tweak something after generating the HTML, I simply pop the file open in a text editor and tweak. As software developers you need to know at least the basics of HTML regardless of the type of development you're doing. My next argument is that it's becoming more common for PB apps, even client/server ones, to use the HTML generation features of the DW. For years we shipped DataWindows around via e-mail or used other methods to make them available to non-PB clients. Our format options are limited, and frankly, WMF doesn't cut it. We could create a PDF and get the exact representation we saw on the monitor, but unfortunately that requires a PDF generation license, which could be costly if we have a large number of workstations or servers that need that capability. The free way is to use the HTML generated by PB. Once generated, we can ship it off via e-mail, store it in the database, or send it into space. We don't have to care if the reader has proprietary software (PBDK) that can read a proprietary format (PSR). It's HTML; any browser can read it. Of course, my argument breaks down in several places, especially the cross-browser support, but let's just skip past those trivial issues. My point is that you, as an n-tier developer or a client/server developer, need to know HTML, especially how PB generates HTML for DataWindows. This isn't an introductory article; we've had them before. If you would like to see an article that describes how to generate HTML for DWs in PB and/or how to get that HTML to the Web, send me an e-mail and I'll consider publishing one in an upcoming issue. This article is an advanced lesson on one Web DataWindow property of significant interest: tabIndex. Hopefully, you'll be a tabIndex guru by the time you finish reading this article. First, a quick look at how to generate HTML for a DW. Remember, I won't go into the details but will only give a brief example of how to obtain the HTML string for a DW. Step 1 is to tell the DW that it will be used for HTML generation. Step 2 is to get the HTML and put it into a string variable. // Get the HTML from the DatastoreThe equivalent, using more traditional syntax: // Get the HTML from the DatastoreAfter that you're on your own. Either e-mail the string or send it to a browser. Each column on the DataWindow will have some HTML rendered for it. The HTML is nontrivial and could be described in a short article of, say, 100 pages. The properties of the column and of the DW itself determine how the column is rendered. If the DW is ReadOnly, then everything is rendered in HTML as spans. The HTML, when viewed, will look like the DW but you won't be able to edit anything or change column properties via JavaScript. If the DW is not ReadOnly, PB looks at the column properties to determine how to render the column. I'm focusing on TabSequence so I'll skip right past all the questions already popping up in your mind. If a column is Protected, disabled, DisplayOnly, or any combination of those, PB generates HTML to match...or at least tries to. Of course, DW columns don't have an "enable" property, so when I say disabled for a DW column I mean the TabSequence is 0. Protected refers to the "Protect" property, and DisplayOnly to the "DisplayOnly" property of the text edit styles. If a column is not visible, it doesn't get rendered in HTML at all, though PB does generate some under-the-covers JavaScript so you can still refer to the column using JavaScript and Web DW functions like set item. An HTML "column", using PB lingo, is called an INPUT. There are several INPUT types but they don't exactly match the column edit styles in PB (e.g., DDLB, DDDW, Edit, etc.). Each INPUT has a number of predefined properties, but they also don't exactly match the DW column properties. Therefore, the Sybase engineers who determined how to generate HTML for the DW had a difficult job to do. They did a good one, but it's still evolving as change requests come in from PB developers. "tabIndex" is a property of the HTML INPUT. It's like TabSequence in the DW in that it defines the order of tabbing among enabled INPUTs on the HTML page. Table 1 provides a brief description of tabbing behavior for potential values of the tabIndex property. As with a PowerBuilder client, it's important to be able to control the tab order of the Web DataWindow. Therefore, it's important to know how PB generates the tabIndex property in relation to property settings on the DW itself. First, let's look at the three main properties I mentioned and how they are rendered in HTML.
TabSequence
An important detail about TabSequence is that PB numbers them in multiples of 10, regardless of the numbers you give them. If you define your TabSequences as 1, 2, 3, 7, 11, 25, as soon as you leave the Tab Order view of the DW painter, PB will reorder them to 10, 20, 30, 40, 50, 60. I like this feature as it allows me to easily move columns in the tab order via code without making room. If the TabSequences were 1, 2, 3, 4, 5 and you wanted to move 5 before 3, you'd have to change 5 to 3, then change 3 to 4 and 4 to 5. PB's renumbering scheme eliminates the need to make room. More on this later.
Protect
DisplayOnly
Generating tabIndex
Earlier I described how the DW painter orders the TabSequence values in multiples of 10, thereby leaving room to easily move columns around in the tab order or even add new ones. Unfortunately, the HTML rendered for the DW does not follow that precedent. Instead, the tabIndex values run in series. If you have TabSequence values of 10, 20, 30, 40, 50, 60, you'll get tabIndex values of 1, 2, 3, 4, 5, 6.
TabIndexBase
To address this problem, a new property has been added to the DW: TabIndexBase. This property defaults to 0 but you can set it to any integer value. It acts as an offset so you can specify that the lowest tabIndex value on DW2 should be higher than the highest tabIndex value on DW1. PB doesn't calculate the offset for you; you have to do that yourself. For the earlier example, you'd set the TabIndexBase for DW2 to 5 or higher so that all tabIndex values for DW2 end up being higher than all those in DW1. If you set it to exactly 5, you'd end up with 6, 7, 8, 9, 10. The syntax for setting the TabIndexBase is: ds1.Modify("DataWindow.HTMLGen.TabIndexBase='70'") Beginning with PB8, the TabIndexBase property is listed in the HTML Generation tab of the properties view of the DW painter. If your offset is static, you can set it permanently there rather than changing it via code. For more information on TabIndexBase see the following technical document on Sybase's Web site: http://my.sybase.com/detail?id=1012430.
tabIndex Equation
tabIndex = (TabSequence/10) + tabindexbase For pages that have only one DW, the TabIndexBase is irrelevant, though it may be needed in order for the Web DW to fit into the tab order of non-WebDW elements on the page. For those with more than one DW it's a savior.
Rules of tabIndex Generation
Implications
For these reasons it's important to analyze your columns up front and determine if you need PB to render them a certain way in HTML. If a column is disabled by default yet you may need to reenable it dynamically, you better make sure PB defines the INPUT with all the properties you'll need when it is reenabled. As this article is already too long, I'll have to end by offering a few recommendations.
Recommendations
This will make your HTML larger, but will allow you to do a lot of things dynamically using JavaScript that you're accustomed to doing dynamically in your PB clients. 2. Set your DW properties so that PB always defines a tabIndex on your INPUTs. This will help you avoid the headaches involved in hard coding tabIndex values into JavaScript in your pages. 3. Use JavaScript to change your INPUT properties dynamically rather than reloading a page to make a change. Reloads are time-consuming and unnecessarily interrupt users. JavaScript can be a powerful tool for dynamically changing the look and behavior of a DW on an HTML page. Use it as you would use PowerScript to dynamically change the look and behavior of a DW on a PB client.
Wrap Up
In an upcoming article I'll delve deeply into the recommendations I briefly stated, and show you techniques for creating powerful HTML DataWindows.
Note that the only scenario that consistently produces an INPUT that can be referenced and changed via JavaScript is when the control is created with a positive TabSequence, DisplayOnly (if applicable) is not selected, and the control is not Protected. Reader Feedback: Page 1 of 1
SOA World Latest Stories
Subscribe to the World's Most Powerful Newsletters
Subscribe to Our Rss Feeds & Get Your SYS-CON News Live!
|
SYS-CON Featured Whitepapers
Most Read This Week |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||