version: #1 (current)  |  last edited by: Mike Ho  |  on: thursday, november 3, 2005, 12:00 pm pst (about 13 years ago)


This article continues from where “QuickStart Guide: Qforms” left off.  It uses the same simple Calculator sample application, adding functionality, talking about events, attributes, styles, and combining them all together.



NOTE: This article covers Beta 1 of the framework.  If you want documentation for Beta 2, please check out the <a href=“http://examples.qcodo.com/” class=“link_body”>Examples Site</a>.


This article assumes that you have a basic understanding of Qforms from <a href=“/documentation/article.php/3” class=“link_body”>QuickStart Guide: Qforms</a>.  The tutorial will continue from where we left off with the simple Calculator sample application.

Multiple Events

In our original Calculator, we tried to simplify the form a little bit by having all the operations in a single listbox.  But what if we wanted a more elegant design, having each operation as its own button?

What we will end up with is four buttons, and each button triggering its own ServerAction:

<code_split_left>
calc_qform_2.php &nbsp; (<a href=“/sample/calculator/calc_qform_2.php” class=“link” target=“_blank”>Run</a>)

<code_split>
<include>/sample/calculator/calc_qform_2.php</include>
</code_split>
<code_split_middle>
calc_qform_2.php.inc

<code_split>
<include>/sample/calculator/calc_qform_2.php.inc</include>
</code_split>
<code_split_right>

The main thing you'll notice is that we removed the listbox, and instead, created four buttons.  And we tied each button to a ServerAction, and we've defined those four ServerActions as “btnXXX_Click” PHP methods.

Also notice that because each button is explicitly tied to a PHP method, it alleviates the need for a switch statement.

Adding Validation

As a next step, let's add some basic validation.  Basically, what we want to do is set both textboxes to be required... after all, in order to successfully perform an operation, we need to ensure that we actually have two operands.

<code_split_left>
calc_qform_3.php &nbsp; (<a href=“/sample/calculator/calc_qform_3.php” class=“link” target=“_blank”>Run</a>)

<code_split>
<include>/sample/calculator/calc_qform_3.php</include>
</code_split>
<code_split_middle>
calc_qform_3.php.inc

<code_split>
<include>/sample/calculator/calc_qform_3.php.inc</include>
</code_split>
<code_split_right>

Both files look nearly the same as before.  For the Form object, we've simply set the Name property for both TextBoxes, and set the Required property to true.  The reason we want a Name property defined is because the text of the error message will actually use the Name of a control (e.g. so that it can say “Value 1 is required”).

We also added a Form_Load event handler.  With the form now performing validations, there's a chance that the form is posted back but if one of the textboxes is blank, no ServerAction will be performed.  We want to clear out the “Results” so that it's clear that no calculation was performed.  Therefore, we null out the lblResults's Text property on Form Load.

And finally, for the HTML template include, we changed the Render() call for both textboxes to be RenderWithError().  We want to make this change so that the Form will render not just the control, but also the Error message (if any).

Adding More Complex Validation

Another requirement for the validators is that not only should both textboxes be required, but they should also be integers, as well.  After all, a simple four-function calculator cannot really do anything with “A * 15”.

What we want to basically do is override the Validate() method in the TextBox to ensure that the Text property of the TextBox is an integer.  Fortunately, there are several subclasses of the TextBox class that are at your disposal (some are included with Qcodo, others can be downloaded separately).  One of these is an IntegerTextBox class.  Along with the standard TextBox Validate() functionality of ensuring a value is specified (when Required is set to “true”), it IntegerTextBox's Validate() will also ensure that the Text value is an integer.

Let's use IntegerTextBox for our calculator:

<code_split_left>
calc_qform_4.php &nbsp; (<a href=“/sample/calculator/calc_qform_4.php” class=“link” target=“_blank”>Run</a>)

<code_split>
<include>/sample/calculator/calc_qform_4.php</include>
</code_split>
<code_split_middle>
calc_qform_4.php.inc

<code_split>
<include>/sample/calculator/calc_qform_4.php.inc</include>
</code_split>
<code_split_right>

All we did was change lines 18 and 22 to say “new IntegerTextBox” instead of “new TextBox”.  And now you can hopefully see that the Qform validation routine requires you to enter in two valid integers before executing a button's ServerAction.

Adding Custom Error Messages

Another requirement that most calculators have is that you cannot divide by zero.  What we want to do is add our own custom validation to say that only when the “Divide” button is clicked, we should check to see that Value 2 is non-zero.

Qforms supports the ability for every control to have user-defined Warning messages.  Warning messages look just like regular error messages, except they are user-defined (as opposed to the internally-controlled ValidationError messages in each control).

<code_split_left>
calc_qform_5.php &nbsp; (<a href=“/sample/calculator/calc_qform_5.php” class=“link” target=“_blank”>Run</a>)

<code_split>
<include>/sample/calculator/calc_qform_5.php</include>
</code_split>
<code_split_middle>
calc_qform_5.php.inc

<code_split>
<include>/sample/calculator/calc_qform_5.php.inc</include>
</code_split>
<code_split_right>

All we needed to do is add this type of non-zero checking validation to the btnDivide_Click method.  And if Value 2 is in fact zero, we'll set Value 2's Warning property to the error text, and simply return (and thus not performing any calculation).

Attributes, Properties and Overriders

Every control has a plethora of presentation- and logic-level properties that can be set.  A sample of the presentation-level properties are:
<ul* BackColor
* ForeColor
* CssClass
* FontBold
* FontItalic
* FontSize
* FontNames
* Width
* Height


Note that it is possible to set both a CssClass as well as other local presentation-level properties.  Setting local properties will override those attributes in the CssClass.  So for example, if you've defined a CSS style “textbox_style” that sets “font: 14px verdana”, and if you have a TextBox Qform control, where you've set CssClass=“textbox_style” and you've also set FontSize=“11px”, you will end up with a textbox that displays in 11px Verdana.

The set of logic-level properties include:
<ul* Enabled
* Required
* Visible
* ServerAction
* ClientAction



We've already covered ServerAction and ClientAction.  Hopefully, the other three should be pretty self-explanatory.

Finally, individual controls also extend the set of properties.  For example, the TextBox control also has a MaxLength property as well as a TextMode property, where TextMode can be SingleLine, MultiLine or Password (which map to an HTML Textbox, HTML Textarea, and HTML Password, respectively).

For more detailed information about the entire Qform Class Library, including all the Properties that can be set for each control, please refer to <a href=“/documentation/article.php/5” class=“link_body”>Qforms Class Library</a>, which includes a PDF download as a quick reference guide.

Let's update our calculator form with some wacky styles:

<code_split_left>
calc_qform_6.php &nbsp; (<a href=“/sample/calculator/calc_qform_6.php” class=“link” target=“_blank”>Run</a>)

<code_split>
<include>/sample/calculator/calc_qform_6.php</include>
</code_split>
<code_split_middle>
calc_qform_6.php.inc

<code_split>
<include>/sample/calculator/calc_qform_6.php.inc</include>
</code_split>
<code_split_right>

There's no rhyme or reason to the attributes that we've assigned.  It's just to demonstrate what's possible.  Note that styles can be assigned in two places, in the class definition itself (like on line 21 where we set FontSize to be 16px), or it can also be set in the HTML template include file.  Setting attributes in the include file (known as Attribute Overriding) will override anything that you set in the class definition.  Case in point: we set the “Addition” button to be Red in the class definition, but overrode it to be Blue in the HTML template include file.

The reason we allowed the capability for attribute overriding is because on many projects, it's sometimes easier for designers to be able to edit the HTML file itself.  However developers are sometimes wary of handing over files with PHP code to designers that may accidentally break the code.

Attribute overriding allows designers (or anyone for that matter) the ability to set the attributes/properties on the controls without incurring the risk of breaking something in the PHP code for the Qform class definition.

Combining Actions and Attributes

Because this is a stateful, event-driven architecture, a lot of the power of Qforms shines through when you combine actions and the changing of attributes.

In our current calculator, we simply throw a warning message when a user tries to divide by 0.  But what would be even better is if the user enters in 0 for Value 2, we could disable the “divide” button ahead of time, so that that error message wouldn't even be necessary:

<code_split_left>
calc_qform_7.php &nbsp; (<a href=“/sample/calculator/calc_qform_7.php” class=“link” target=“_blank”>Run</a>)

<code_split>
<include>/sample/calculator/calc_qform_7.php</include>
</code_split>
<code_split_middle>
calc_qform_7.php.inc

<code_split>
<include>/sample/calculator/calc_qform_7.php.inc</include>
</code_split>
<code_split_right>

As you can see, we've added a ServerAction to txtValue2, and its event handling method “txtValue2_Change” simply toggles the Enabled property of btnDivide, depending on whether or not txtValue2 is 0.

We've also taken away the error handling in btnDivide, because the Enabled property toggling now makes it not possible to ever have btnDivide called while txtValue2 is 0.  (Because btnDivide's disabling is simply a HTML attribute, a hacker could circumvent this.  So it would be a good idea to maintain the server-side validation of ensuring that the user is not dividing by 0.  We simply removed it for demonstration purposes.)

Back to Traditional PHP?

We haven't looked at how a calculator with comparable functionality would look like using traditional PHP code.  But uh, I'm not sure if we'd want to (I know that I +don't... but if someone wants to take a crack at it, send it to me and I'll post it here).  True, the +first version of our calculator showed that the traditional PHP had fewer LOC than the Qform version.  But given the validation, the event handling, styles and attributes, etc., writing a still-relatively simple calculator with all these things using traditional PHP would begin to look a little messier.

And that goes to the whole idea of Qforms.  There is definitely a slight overhead to setting up a Qform -- which is why we said earlier that it's not necessarily a good idea for every page in your application be a Qform.  But once you begin with functionality that requires a bit more in terms of display logic and even just a slightly more complex presentation layer, you'll hopefully be able to really enjoy and understand the benefits of using the Qforms architecture.



Copyright © 2005 - 2019, Quasidea Development, LLC
This open-source framework for PHP is released under the terms of The MIT License.