Subversion-Projekte lars-tiefland.prado

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<com:TContent ID="body">
2
	<h1 id="16001">Building a Simple Currency Converter</h1>
3
	<p id="80053" class="block-content">This tutorial introduces the Prado web application framework and teaches
4
		you how to build a simple web application in a few simple steps. This
5
		tutorial assumes that you are familiar with PHP and you have access
6
		to a web server that is able to serve PHP5 scripts.
7
	</p>
8
 
9
	<p id="80054" class="block-content">In this tutorial you will build a simple web application that converts
10
		a dollar amount to an other currency, given the rate of that currency
11
		relative to the dollar. The completed application is shown bellow.
12
		<img src=<%~ example2.png %> class="figure" />
13
		You can try the application <a href="../currency-converter/index.php">locally</a> or at
14
		<a href="http://www.pradosoft.com/demos/currency-converter/">Pradosoft.com</a>.
15
		Notice that the application still functions exactly the same if javascript
16
		is not available on the user's browser.
17
	</p>
18
 
19
	<h1 id="download">Downloading and Installing Prado</h1>
20
	<p id="80055" class="block-content">To install Prado, simply download the latest version of Prado from
21
		<a href="http://www.pradosoft.com/">http://www.pradosoft.com</a>
22
		and unzip the file to a directory <b>not</b> accessible by your web server
23
		(you may unzip it to a directory accessible by the web server if you wish
24
		to see the demos and test). For further detailed installation, see the
25
		<a href="?page=GettingStarted.Installation">Quickstart Installation</a> guide.
26
	</p>
27
 
28
	<h1 id="16002">Creating a new Prado web Application</h1>
29
	<p id="80056" class="block-content">The quickest and simplest way to create a new Prado web application is
30
		to use the command tool <tt>prado-cli.php</tt> found in the <tt>framework</tt>
31
		directory of the Prado distribution.  We create a new application by running
32
		the  following command in your
33
		command prompt or console. The command creates a new directory named
34
		<tt>currency-converter</tt> in your current working directory.
35
		You may need to change to the appropriate directory
36
		first.
37
		See the <a href="?page=GettingStarted.CommandLine">Command Line Tool</a>
38
		for more details.
39
	</p>
40
<com:TTextHighlighter Language="text" CssClass="source block-content" id="code111">
41
php prado/framework/prado-cli.php -c currency-converter
42
</com:TTextHighlighter>
43
 
44
	<p id="80057" class="block-content">The above command creates the necessary directory structure and minimal
45
		files (including "index.php" and "Home.page") to run a Prado  web application.
46
		Now you can point your browser's url to the web server to serve up
47
		the <tt>index.php</tt> script in the <tt>currency-converter</tt> directory.
48
		You should see the message "Welcome to Prado!"
49
	</p>
50
 
51
	<h1 id="16003">Creating the Currency Converter User Interface</h1>
52
	<p id="80058" class="block-content">We start by editing the <tt>Home.page</tt> file found in the
53
		<tt>currency-converter/protected/pages/</tt> directory. Files ending
54
		with ".page" are page templates that contains HTML and Prado controls.
55
		We simply add two textboxes, three labels and one button as follows.
56
	</p>
57
<com:TTextHighlighter Language="prado" CssClass="source block-content" id="form1">
58
&lt;com:TForm&gt;
59
    <fieldset>
60
        <legend>Currency Converter</legend>
61
        <div class="rate-field">
62
            &lt;com:TLabel ForControl="currencyRate" Text="Exchange Rate per $1:" /&gt;
63
            &lt;com:TTextBox ID="currencyRate" /&gt;
64
        </div>
65
        <div class="dollar-field">
66
            &lt;com:TLabel ForControl="dollars" Text="Dollars to Convert:" /&gt;
67
            &lt;com:TTextBox ID="dollars" /&gt;
68
        </div>
69
        <div class="total-field">
70
            <span class="total-label">Amount in Other Currency:</span>
71
            &lt;com:TLabel ID="total" CssClass="result" /&gt;
72
        </div>
73
        <div class="convert-button">
74
            &lt;com:TButton Text="Convert" /&gt;
75
        </div>
76
    </fieldset>
77
&lt;/com:TForm&gt;
78
</com:TTextHighlighter>
79
	<p id="refresh" class="block-content">
80
	If you refresh the page, you should see something similar to the following figure.
81
	It may not look very pretty or orderly, but we shall change that later using CSS.
82
	<img src=<%~ example1.png %> class="figure" />
83
	</p>
84
 
85
	<p id="80059" class="block-content">
86
		The first component we add is a
87
		<com:DocLink ClassPath="System.Web.UI.TForm" Text="TForm" />
88
		that basically corresponds to the HTML <tt>&lt;form&gt;</tt> element.
89
		In Prado, only <b>one</b> <tt>TForm</tt> element is allowed per page.
90
	</p>
91
 
92
	<p id="80060" class="block-content">The next two pair of component we add is the
93
		<com:DocLink ClassPath="System.Web.UI.WebControls.TLabel" Text="TLabel" />
94
		and
95
		<com:DocLink ClassPath="System.Web.UI.WebControls.TTextBox" Text="TTextBox" />
96
		that basically defines a label and a textbox for the user of the application
97
		to enter the currency exchange rate.
98
		The <tt>ForControl</tt> property value determines which component
99
		that the label is for. This allows the user of the application to click
100
		on the label to focus on the field (a good thing). You could have used
101
		a plain HTML <tt>&lt;label&gt;</tt> element to do the same thing, but
102
		you would have to find the correct <tt>ID</tt> of the textbox (or
103
		<tt>&lt;input&gt;</tt> in HTML) as Prado components may/will render the
104
		<tt>ID</tt> value differently in the HTML output.
105
	</p>
106
 
107
	<p id="80061" class="block-content">The next pair of components are similar and defines the textbox
108
		to hold the dollar value to be converted.
109
		The <tt>TLabel</tt> with <tt>ID</tt> value "total" defines a simple label.
110
		Notice that the <tt>ForControl</tt> property is absent. This means that this
111
		label is simply a simple label which we are going to use to display the
112
		converted total amount.
113
	</p>
114
 
115
	<p id="80062" class="block-content">The final component is a
116
		<com:DocLink ClassPath="System.Web.UI.WebControls.TButton" Text="TButton" />
117
		that the user will click to calculate the results. The <tt>Text</tt>
118
		property sets the button label.
119
	</p>
120
 
121
	<h1 id="16004">Implementing Currency Conversion</h1>
122
 
123
	<p id="80063" class="block-content">If you tried clicking on the "Convert" button then the page will refresh
124
		and does not do anything else. For the button to do some work, we need
125
		to add a "Home.php" to where "Home.page" is. The <tt>Home</tt> class
126
		should extends the
127
		<com:DocLink ClassPath="System.Web.UI.TPage" Text="TPage" />, the default base
128
		class for all Prado pages.
129
	</p>
130
<com:TTextHighlighter Language="php" CssClass="source block-content" id="code3">
131
&lt;?php
132
class Home extends TPage
133
{
134
 
135
}
136
?&gt;
137
</com:TTextHighlighter>
138
	<p id="1111" class="block-content">
139
		Prado uses PHP's <tt>__autoload</tt> method to load classes. The convention
140
		is to use the class name with ".php" extension as filename.
141
	</p>
142
 
143
	<p id="80064" class="block-content">So far there is nothing interesting about Prado, we just declared some
144
		"web components" in some template file named Home.page and created
145
		a "Home.php" file with a <tt>Home</tt> class. The more interesting
146
		bits are in Prado's event-driven architecture as we shall see next.
147
	</p>
148
 
149
	<p id="80065" class="block-content">We want that when the user click on the "Convert" button, we take the
150
		values in the textbox, do some calculation and present the user with
151
		the converted total. To handle the user clicking of the "Convert" button
152
		we simply add an <tt>OnClick</tt> property to the "Convert" button in
153
	 	the "Home.page" template and add a corresponding event handler method
154
		in the "Home.php".
155
	</p>
156
<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code4">
157
&lt;com:TButton Text="Convert" OnClick="convert_clicked" /&gt;
158
</com:TTextHighlighter>
159
	<p id="222" class="block-content">
160
		The value of the <tt>OnClick</tt>, "<tt>convert_clicked</tt>", will be the method
161
		name in the "Home.php" that will called when the user clicks on the
162
		"Convert" button.
163
	</p>
164
<com:TTextHighlighter Language="php" CssClass="source block-content" id="code5">
165
class Home extends TPage
166
{
167
    public function convert_clicked($sender, $param)
168
    {
169
        $rate = floatval($this->currencyRate->Text);
170
        $dollars = floatval($this->dollars->Text);
171
        $this->total->Text = $rate * $dollars;
172
    }
173
}
174
</com:TTextHighlighter>
175
<div id="3332" class="block-content">
176
	<p id="333">
177
		If you run the application in your web browser, enter some values and click
178
		the "Convert" button then you should see that calculated value displayed next
179
		to the "Amount in Other Currency" label.
180
	</p>
181
 
182
	<p id="80066">In the "<tt>convert_clicked</tt>" method the first parameter, <tt>$sender</tt>,
183
		corresponds to the object that raised the event, in this case,
184
		the "Convert" button. The second parameter, <tt>$param</tt> contains
185
		any additional data that the <tt>$sender</tt> object may wish to have added.
186
	</p>
187
 
188
	<p id="80067">We shall now examine, the three lines that implements the simply currency
189
		conversion in the "<tt>convert_clicked</tt>" method.
190
	</p>
191
</div>
192
<com:TTextHighlighter Language="php" CssClass="source block-content" id="code6" >
193
$rate = floatval($this->currencyRate->Text);
194
</com:TTextHighlighter>
195
	<p id="444" class="block-content">
196
		The statement <tt>$this->currencyRate</tt> corresponds to the
197
		<tt>TTextBox</tt> component with <tt>ID</tt> value "currencyRate" in the
198
		"Home.page" template. The <tt>Text</tt> property of the <tt>TTextBox</tt>
199
		contains the value that the user entered. So, we obtain this
200
		value by <tt>$this->currencyRate->Text</tt> which we convert the
201
		value to a float value.
202
	</p>
203
<com:TTextHighlighter Language="php" CssClass="source block-content" id="code7">
204
$dollars = floatval($this->dollars->Text);
205
</com:TTextHighlighter>
206
<div id="5551" class="block-content">
207
	<p id="555">
208
		The next line does a similar things, it takes the user value from
209
		the <tt>TTextBox</tt> with <tt>ID</tt> value "dollars and converts it to
210
		a float value.
211
	</p>
212
 
213
	<p id="80068">The third line calculates the new amount and set this value in the
214
		<tt>Text</tt> property of the <tt>TLabel</tt> with <tt>ID="total"</tt>.
215
		Thus, we display the new amount to the user in the label.
216
	</p>
217
</div>
218
<com:TTextHighlighter Language="php" CssClass="source block-content" id="code8">
219
$this->total->Text = $rate * $dollars;
220
</com:TTextHighlighter>
221
 
222
	<h1 id="16005">Adding Validation</h1>
223
	<p id="80069" class="block-content">The way we convert the user entered value to float ensures that the
224
		total amount is always a number. So the user is free to enter what
225
		ever they like, they could even enter letters. The user's experience
226
		in using the application can be improved by adding validators
227
		to inform the user of the allowed values in the currency rate and the
228
		amount to be calcuated.
229
	</p>
230
 
231
	<p id="80070">For the currency rate, we should ensure that</p>
232
		<ol id="o111" class="block-content">
233
			<li>the user enters a value,</li>
234
			<li>the currency rate is a valid number,</li>
235
			<li>the currency rate is positive.</li>
236
		</ol>
237
	<p id="666" class="block-content">
238
	 To ensure 1 we add one
239
	<com:DocLink ClassPath="System.Web.UI.WebControls.TRequiredFieldValidator" Text="TRequiredFieldValidator" />. To ensure 2 and 3, we add one
240
	<com:DocLink ClassPath="System.Web.UI.WebControls.TCompareValidator" Text="TCompareValidator" />. We may add these validators any where within
241
	the "Home.page" template. Further details regarding these validator and other
242
	validators can be found in the
243
	<a href="?page=Controls.Validation">Validation Controls</a> page.
244
	</p>
245
<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code9">
246
&lt;com:TRequiredFieldValidator
247
	ControlToValidate="currencyRate"
248
	ErrorMessage="Please enter a currency rate." /&gt;
249
&lt;com:TCompareValidator
250
	ControlToValidate="currencyRate"
251
	DataType="Float"
252
	ValueToCompare="0"
253
	Operator="GreaterThan"
254
	ErrorMessage="Please enter a positive currency rate." /&gt;
255
</com:TTextHighlighter>
256
 
257
	<p id="80071" >For the amount to be calculated, we should ensure that</p>
258
		<ol id="o222" class="block-content">
259
			<li>the user enters a value,</li>
260
			<li>the value is a valid number (not including any currency or dollar signs).</li>
261
		</ol>
262
	<p id="777" class="block-content">
263
	To ensure 1 we just add another <tt>TRequiredFieldValidator</tt>, for 2
264
	we could use a
265
	<com:DocLink ClassPath="System.Web.UI.WebControls.TDataTypeValidator" Text="TDataTypeValidator" />. For simplicity we only allow the user to enter
266
	a number for the amount they wish to convert.
267
	</p>
268
<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code9a">
269
&lt;com:TRequiredFieldValidator
270
	ControlToValidate="dollars"
271
	ErrorMessage="Please enter the amount you wish to calculate." /&gt;
272
&lt;com:TDataTypeValidator
273
	ControlToValidate="dollars"
274
	DataType="Float"
275
	ErrorMessage="Please enter a number." /&gt;
276
</com:TTextHighlighter>
277
	</p>
278
 
279
	<p id="80072" class="block-content">Now if you try to enter some invalid data in the application or left out
280
		any of the fields the validators will be activated and present the user
281
		with error messages. Notice that the error messages are presented
282
		without reloading the page. Prado's validators by default validates
283
		using both javascript and server side. The server side validation
284
		is <b>always performed</b>. For the server side, we
285
		should skip the calculation if the validators are not satisfied. This can
286
		done as follows.
287
	</p>
288
<com:TTextHighlighter Language="php" CssClass="source block-content" id="code10" >
289
public function convert_clicked($sender, $param)
290
{
291
    if($this->Page->IsValid)
292
    {
293
        $rate = floatval($this->currencyRate->Text);
294
        $dollars = floatval($this->dollars->Text);
295
        $this->total->Text = $rate * $dollars;
296
    }
297
}
298
</com:TTextHighlighter>
299
 
300
	<h1 id="16006">Improve User Experience With Active Controls</h1>
301
 
302
	<com:RequiresVersion Version="3.1a" />
303
 
304
	<p id="80073" class="block-content">In this simple application we may further improve the user experience
305
		by increasing the responsiveness of the application. One way to achieve
306
		a faster response is calculate and present the results without reloading
307
		the whole page.
308
	</p>
309
 
310
	<p id="80074" class="block-content">We can replace the <tt>TButton</tt> with the Active Control counter part,
311
		<com:DocLink ClassPath="System.Web.UI.ActiveControls.TActiveButton" Text="TActiveButton" />,
312
		that can trigger a server side click event without reloading the page.
313
		In addition, we can change the "totals" <tt>TLabel</tt> with the
314
		Active Control counter part,
315
		<com:DocLink ClassPath="System.Web.UI.ActiveControls.TActiveLabel" Text="TActiveLabel" />, such that the server side can update the browser without
316
		reloading the page.
317
	</p>
318
<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code11">
319
<div class="total-field">
320
    <span class="total-label">Amount in Other Currency:</span>
321
         &lt;com:TActiveLabel ID="total" CssClass="result" /&gt;
322
    </div>
323
    <div class="convert-button">
324
        &lt;com:TActiveButton Text="Convert" OnClick="convert_clicked" /&gt;
325
</div>
326
</com:TTextHighlighter>
327
	<p id="1232" class="block-content">
328
		The server side logic remains the same, we just need to import the
329
		Active Controls name space as they are not included by default. We
330
		add the following line to the begin of "Home.php".
331
	</p>
332
<com:TTextHighlighter Language="php" CssClass="source block-content" id="code12">
333
Prado::using('System.Web.UI.ActiveControls.*');
334
</com:TTextHighlighter>
335
 
336
	<p id="80075" class="block-content">If you try the application now, you may notice that the page no longer
337
		needs to reload to calculate and display the converted total amount.
338
		However, since there is not page reload, there is no indication or not obvious
339
		that by clicking on the "Convert" button any has happened.
340
		We can further refine the user experience by change the text of "total" label
341
		to "calculating..." when the user clicks on the "Convert" button. The text of
342
		the "total" label will still be updated with the new calculate amount as before.
343
	</p>
344
 
345
	<p id="80076" class="block-content">To indicate that the calculation is in progress, we can change the text
346
		of the "total" label as follows. We add a <tt>ClientSide.OnLoading</tt> property
347
		to the "Convert" button (since this button is responsible for requesting
348
		the calculation).
349
	</p>
350
<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code13">
351
&lt;com:TActiveButton Text="Convert" OnClick="convert_clicked" &gt;
352
    &lt;prop:ClientSide.OnLoading&gt;
353
        $('&lt;%= $this->total->ClientID %&gt;').innerHTML = "calculating..."
354
    &lt;/prop:ClientSide.OnLoading&gt;
355
&lt;/com:TActiveButton&gt;
356
</com:TTextHighlighter>
357
 
358
	<p id="80077" class="block-content">The <tt>ClientSide.OnLoading</tt> and various
359
	<com:DocLink ClassPath="System.Web.UI.ActiveControls.TCallbackClientSide" Text="other properties" /> accept a javascript block as their content or value.
360
	The javascript code <tt>$('...')</tt> is a javascript function that is
361
	equivalent to <tt>document.getElementById('...')</tt> that takes a string
362
	with the ID of an HTML element. Since Prado renders its components's IDs, we need
363
	to use the rendered ID of the "total" label, that is, <tt>$this->total->ClientID</tt>. We place this bit of code within a <tt>&lt;%= %&gt;</tt> to obtain the rendered HTML ID for the "total" label. The rest of the
364
	javascript code <tt>innerHTML = "calculating..."</tt> simply changes
365
	the content of the "total" label.
366
	</p>
367
 
368
	<h1 id="16007">Adding Final Touches</h1>
369
	<p id="80078" class="block-content">So far we have built a simple currency converter web application with
370
		little attention of the looks and feel. Now we can add a stylesheet
371
		to improve the overall appearance of the application. We can simply
372
		add the stylesheet inline with the template code or we may create
373
		a "theme".
374
	</p>
375
 
376
	<p id="80079" class="block-content">To create and use a theme with Prado applications, we simply create a new
377
		directory "themes/Basic" in the <tt>currency-converter</tt> directory.
378
		You may need to create the <tt>themes</tt> directory first. Any
379
		directory within the <tt>themes</tt> are considered as a theme with the
380
		name of the theme being the directory name. See the
381
		<a href="?page=Advanced.Themes">Themes and Skins</a> for further details.
382
	</p>
383
 
384
	<p id="80080" class="block-content">We simply create a CSS file named "common.css" and save it in the
385
		<tt>themes/Basic</tt> directory. Then we add the following code
386
		to the beginning of "Home.page" (we add a little more HTML as well).
387
	</p>
388
<com:TTextHighlighter Language="prado" CssClass="source block-content" id="code14">
389
&lt;%@ Theme="Basic" %&gt;
390
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
391
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
392
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" >
393
&lt;com:THead Title="Currency Converter" /&gt;
394
<body>
395
</com:TTextHighlighter>
396
	<p id="4334" class="block-content">
397
		The first line <tt>&lt;%@ Theme="Basic" %&gt;</tt> defines the
398
		theme to be used for this page. The
399
		<com:DocLink ClassPath="System.Web.UI.WebControls.THead" Text="THead" />
400
		corresponds to the HTML <tt>&lt;head&gt;</tt> element. In addition
401
		to display the <tt>Title</tt> property by the <tt>THead</tt>, all CSS
402
		files in the <tt>themes/Basic</tt> directory are also rendered/linked
403
		for the current page. Our final currency converter web application
404
		looks like the following.
405
		<img src=<%~ example2.png %> class="figure" />
406
		This completes introduction tutorial to the Prado web application framework.
407
	</p>
408
<div class="last-modified">$Id: CurrencyConverter.page 1846 2007-04-07 10:35:16Z wei $</div></com:TContent>