Building a Simple Currency Converter
This tutorial introduces the Prado web application framework and teaches
you how to build a simple web application in a few simple steps. This
tutorial assumes that you are familiar with PHP and you have access
to a web server that is able to serve PHP5 scripts.
In this tutorial you will build a simple web application that converts
a dollar amount to an other currency, given the rate of that currency
relative to the dollar. The completed application is shown bellow.
You can try the application locally or at the
Prado website.
Notice that the application still functions exactly the same if javascript
is not available on the user's browser.
Downloading and Installing Prado
The best way to install PRADO is through composer
If you don't use composer yet, first install it:
curl -s http://getcomposer.org/installer | php
php composer.phar install
Creating a new Prado web Application
Then, create the application structure using composer:
composer create-project pradosoft/prado-app currency-converter
The command creates a new directory named
currency-converter in your current working directory.
You may need to change to the appropriate directory
first.
The above command creates the necessary directory structure and minimal
files (including "index.php" and "Home.page") to run a Prado web application.
Now you can point your browser's url to the web server to serve up
the index.php script in the currency-converter directory.
You should see the message "Welcome to Prado!"
Creating the Currency Converter User Interface
We start by editing the Home.page file found in the
currency-converter/protected/pages/ directory. Files ending
with ".page" are page templates that contains HTML and Prado controls.
We simply add two textboxes, three labels and one button as follows.
<com:TForm>
<fieldset>
<legend>Currency Converter</legend>
<div class="rate-field">
<com:TLabel ForControl="currencyRate" Text="Exchange Rate per $1:" />
<com:TTextBox ID="currencyRate" />
</div>
<div class="dollar-field">
<com:TLabel ForControl="dollars" Text="Dollars to Convert:" />
<com:TTextBox ID="dollars" />
</div>
<div class="total-field">
<span class="total-label">Amount in Other Currency:</span>
<com:TLabel ID="total" CssClass="result" />
</div>
<div class="convert-button">
<com:TButton Text="Convert" />
</div>
</fieldset>
</com:TForm>
If you refresh the page, you should see something similar to the following figure.
It may not look very pretty or orderly, but we shall change that later using CSS.
The first component we add is a
TForm
that basically corresponds to the HTML <form> element.
In Prado, only one TForm element is allowed per page.
The next two pair of component we add is the
TLabel
and
TTextBox
that basically defines a label and a textbox for the user of the application
to enter the currency exchange rate.
The ForControl property value determines which component
that the label is for. This allows the user of the application to click
on the label to focus on the field (a good thing). You could have used
a plain HTML <label> element to do the same thing, but
you would have to find the correct ID of the textbox (or
<input> in HTML) as Prado components may/will render the
ID value differently in the HTML output.
The next pair of components are similar and defines the textbox
to hold the dollar value to be converted.
The TLabel with ID value "total" defines a simple label.
Notice that the ForControl property is absent. This means that this
label is simply a simple label which we are going to use to display the
converted total amount.
The final component is a
TButton
that the user will click to calculate the results. The Text
property sets the button label.
Implementing Currency Conversion
If you tried clicking on the "Convert" button then the page will refresh
and does not do anything else. For the button to do some work, we need
to add a "Home.php" to where "Home.page" is. The Home class
should extends the
TPage, the default base
class for all Prado pages.
<?php
class Home extends TPage
{
}
Prado uses PHP's __autoload method to load classes. The convention
is to use the class name with ".php" extension as filename.
So far there is nothing interesting about Prado, we just declared some
"web components" in some template file named Home.page and created
a "Home.php" file with a Home class. The more interesting
bits are in Prado's event-driven architecture as we shall see next.
We want that when the user click on the "Convert" button, we take the
values in the textbox, do some calculation and present the user with
the converted total. To handle the user clicking of the "Convert" button
we simply add an OnClick property to the "Convert" button in
the "Home.page" template and add a corresponding event handler method
in the "Home.php".
<com:TButton Text="Convert" OnClick="convert_clicked" />
The value of the OnClick, "convert_clicked", will be the method
name in the "Home.php" that will called when the user clicks on the
"Convert" button.
class Home extends TPage
{
public function convert_clicked($sender, $param)
{
$rate = floatval($this->currencyRate->Text);
$dollars = floatval($this->dollars->Text);
$this->total->Text = $rate * $dollars;
}
}
If you run the application in your web browser, enter some values and click
the "Convert" button then you should see that calculated value displayed next
to the "Amount in Other Currency" label.
In the "convert_clicked" method the first parameter, $sender,
corresponds to the object that raised the event, in this case,
the "Convert" button. The second parameter, $param contains
any additional data that the $sender object may wish to have added.
We shall now examine, the three lines that implements the simply currency
conversion in the "convert_clicked" method.
$rate = floatval($this->currencyRate->Text);
The statement $this->currencyRate corresponds to the
TTextBox component with ID value "currencyRate" in the
"Home.page" template. The Text property of the TTextBox
contains the value that the user entered. So, we obtain this
value by $this->currencyRate->Text which we convert the
value to a float value.
$dollars = floatval($this->dollars->Text);
The next line does a similar things, it takes the user value from
the TTextBox with ID value "dollars and converts it to
a float value.
The third line calculates the new amount and set this value in the
Text property of the TLabel with ID="total".
Thus, we display the new amount to the user in the label.
$this->total->Text = $rate * $dollars;
Adding Validation
The way we convert the user entered value to float ensures that the
total amount is always a number. So the user is free to enter what
ever they like, they could even enter letters. The user's experience
in using the application can be improved by adding validators
to inform the user of the allowed values in the currency rate and the
amount to be calcuated.
For the currency rate, we should ensure that
- the user enters a value,
- the currency rate is a valid number,
- the currency rate is positive.
To ensure 1 we add one
TRequiredFieldValidator. To ensure 2 and 3, we add one
TCompareValidator. We may add these validators any where within
the "Home.page" template. Further details regarding these validator and other
validators can be found in the
Validation Controls page.
<com:TRequiredFieldValidator
ControlToValidate="currencyRate"
ErrorMessage="Please enter a currency rate." />
<com:TCompareValidator
ControlToValidate="currencyRate"
DataType="Float"
ValueToCompare="0"
Operator="GreaterThan"
ErrorMessage="Please enter a positive currency rate." />
For the amount to be calculated, we should ensure that
- the user enters a value,
- the value is a valid number (not including any currency or dollar signs).
To ensure 1 we just add another TRequiredFieldValidator, for 2
we could use a
TDataTypeValidator. For simplicity we only allow the user to enter
a number for the amount they wish to convert.
<com:TRequiredFieldValidator
ControlToValidate="dollars"
ErrorMessage="Please enter the amount you wish to calculate." />
<com:TDataTypeValidator
ControlToValidate="dollars"
DataType="Float"
ErrorMessage="Please enter a number." />
Now if you try to enter some invalid data in the application or left out
any of the fields the validators will be activated and present the user
with error messages. Notice that the error messages are presented
without reloading the page. Prado's validators by default validates
using both javascript and server side. The server side validation
is always performed. For the server side, we
should skip the calculation if the validators are not satisfied. This can
done as follows.
public function convert_clicked($sender, $param)
{
if($this->Page->IsValid)
{
$rate = floatval($this->currencyRate->Text);
$dollars = floatval($this->dollars->Text);
$this->total->Text = $rate * $dollars;
}
}
Improve User Experience With Active Controls
Requires Prado versions 3.1a or later.
In this simple application we may further improve the user experience
by increasing the responsiveness of the application. One way to achieve
a faster response is calculate and present the results without reloading
the whole page.
We can replace the TButton with the Active Control counter part,
TActiveButton,
that can trigger a server side click event without reloading the page.
In addition, we can change the "totals" TLabel with the
Active Control counter part,
TActiveLabel, such that the server side can update the browser without
reloading the page.
<div class="total-field">
<span class="total-label">Amount in Other Currency:</span>
<com:TActiveLabel ID="total" CssClass="result" />
</div>
<div class="convert-button">
<com:TActiveButton Text="Convert" OnClick="convert_clicked" />
</div>
The server side logic remains the same, we just need to import the
Active Controls name space as they are not included by default. We
add the following line to the begin of "Home.php".
Prado::using('System.Web.UI.ActiveControls.*');
If you try the application now, you may notice that the page no longer
needs to reload to calculate and display the converted total amount.
However, since there is not page reload, there is no indication or not obvious
that by clicking on the "Convert" button any has happened.
We can further refine the user experience by change the text of "total" label
to "calculating..." when the user clicks on the "Convert" button. The text of
the "total" label will still be updated with the new calculate amount as before.
To indicate that the calculation is in progress, we can change the text
of the "total" label as follows. We add a ClientSide.OnLoading property
to the "Convert" button (since this button is responsible for requesting
the calculation).
<com:TActiveButton Text="Convert" OnClick="convert_clicked" >
<prop:ClientSide.OnLoading>
$('<%= $this->total->ClientID %>').innerHTML = "calculating..."
</prop:ClientSide.OnLoading>
</com:TActiveButton>
The ClientSide.OnLoading and various
other properties accept a javascript block as their content or value.
The javascript code $('...') is a javascript function that is
equivalent to document.getElementById('...') that takes a string
with the ID of an HTML element. Since Prado renders its components's IDs, we need
to use the rendered ID of the "total" label, that is, $this->total->ClientID. We place this bit of code within a <%= %> to obtain the rendered HTML ID for the "total" label. The rest of the
javascript code innerHTML = "calculating..." simply changes
the content of the "total" label.
Adding Final Touches
So far we have built a simple currency converter web application with
little attention of the looks and feel. Now we can add a stylesheet
to improve the overall appearance of the application. We can simply
add the stylesheet inline with the template code or we may create
a "theme".
To create and use a theme with Prado applications, we simply create a new
directory "themes/Basic" in the currency-converter directory.
You may need to create the themes directory first. Any
directory within the themes are considered as a theme with the
name of the theme being the directory name. See the
Themes and Skins for further details.
We simply create a CSS file named "common.css" and save it in the
themes/Basic directory. Then we add the following code
to the beginning of "Home.page" (we add a little more HTML as well).
<%@ Theme="Basic" %>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
</head>
<body>
The first line <%@ Theme="Basic" %> defines the
theme to be used for this page. The
THead
corresponds to the HTML <head> element. In addition
to display the Title property by the THead, all CSS
files in the themes/Basic directory are also rendered/linked
for the current page. Our final currency converter web application
looks like the following.
This completes introduction tutorial to the Prado web application framework.