From 654a9cae43358c7eecf3b522e9876aa7815e2453 Mon Sep 17 00:00:00 2001
From: Fabio Bas
Date: Mon, 7 Dec 2015 15:57:51 +0100
Subject: Move urls from pradosoft.com to github's project page; drop
unmaintained quickstart tutorial translations
---
.../protected/pages/Tutorial/fr/AjaxChat.page | 755 ---------------------
.../pages/Tutorial/fr/CurrencyConverter.page | 404 -----------
.../protected/pages/Tutorial/fr/chat1.png | Bin 10533 -> 0 bytes
.../protected/pages/Tutorial/fr/chat2.png | Bin 13409 -> 0 bytes
.../protected/pages/Tutorial/fr/example1.png | Bin 11139 -> 0 bytes
.../protected/pages/Tutorial/fr/example2.png | Bin 13842 -> 0 bytes
6 files changed, 1159 deletions(-)
delete mode 100755 demos/quickstart/protected/pages/Tutorial/fr/AjaxChat.page
delete mode 100755 demos/quickstart/protected/pages/Tutorial/fr/CurrencyConverter.page
delete mode 100755 demos/quickstart/protected/pages/Tutorial/fr/chat1.png
delete mode 100755 demos/quickstart/protected/pages/Tutorial/fr/chat2.png
delete mode 100755 demos/quickstart/protected/pages/Tutorial/fr/example1.png
delete mode 100755 demos/quickstart/protected/pages/Tutorial/fr/example2.png
(limited to 'demos/quickstart/protected/pages/Tutorial/fr')
diff --git a/demos/quickstart/protected/pages/Tutorial/fr/AjaxChat.page b/demos/quickstart/protected/pages/Tutorial/fr/AjaxChat.page
deleted file mode 100755
index 568e920f..00000000
--- a/demos/quickstart/protected/pages/Tutorial/fr/AjaxChat.page
+++ /dev/null
@@ -1,755 +0,0 @@
-
-
Building an AJAX Chat Application
-
This tutorial introduces the Prado web application framework's
- ActiveRecord
- and Active Controls to build a Chat
- web application. It is assumed that you
- are familiar with PHP and you have access to a web server that is able to serve PHP5 scripts.
- This basic chat application will utilize the following ideas/components in Prado.
-
-
-
Building a custom User Manager class.
-
Authenticating and adding a new user to the database.
-
Using ActiveRecord to interact with the database.
-
Using Active Controls and callbacks to implement the user interface.
-
Separating application logic and application flow.
-
-
-
In this tutorial you will build an AJAX Chat web application that allows
- multiple users to communicate through their web browser.
- The application consists of two pages: a login page
- that asks the user to enter their nickname and the main application chat
- page.
- You can try the application locally or at
- Pradosoft.com.
- The main application chat page is shown bellow.
- class="figure" />
-
-
-
Download, Install and Create a New Application
-
The download and installation steps are similar to those in
- the Currency converter tutorial.
- To create the application, we run from the command line the following.
- See the Command Line Tool
- for more details.
-
-php prado/framework/prado-cli.php -c chat
-
-
-
-
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 chat directory.
- You should see the message "Welcome to Prado!"
-
-
-
Authentication and Authorization
-
The first task for this application is to ensure that each user
- of the chat application is assigned with a unique (chosen by the user)
- username. To achieve this, we can secure the main chat application
- page to deny access to anonymous users. First, let us create the Login
- page with the following code. We save the Login.php and Login.page
- in the chat/protected/pages/ directory (there should be a Home.page
- file created by the command line tool).
-
The login page contains
- a ,
- a ,
- a
- and a . The resulting
- page looks like the following (after applying some a style sheet).
- class="figure" />
- If you click on the Login button without entering any
- text in the username textbox, an error message is displayed. This is
- due to the
- requiring the user to enter some text in the textbox before proceeding.
-
-
Securing the Home page
-
Now we wish that if the user is trying to access the main application
-page, Home.page, before they have logged in, the user is presented with
-the Login.page first. We add a chat/protected/application.xml configuration
-file to import some classes that we shall use later.
-
-
-
-
-
-
-
-
-
-
-
-Next, we add a chat/protected/pages/config.xml configuration file to
-secure the pages directory.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-We setup the authentication using the default classes as explained in the
-authentication/authorization quickstart.
-In the authorization definition, we allow anonymous users to access the
-Login page (anonymous users is specified by the ? question mark).
-We allow any users with role equal to "normal" (to be defined later)
-to access all the pages, that is, the Login and Home pages.
-Lastly, we deny all users without any roles to access any page. The authorization
-rules are executed on first match basis.
-
-
-
If you now try to access the Home page by pointing your browser
-to the index.php you will be redirected to the Login page.
-
-
-
Active Record for chat_users table
-
The
-class only provides a read-only list of users. We need to be able to add or
-login new users dynamically. So we need to create our own user manager class.
-First, we shall setup a database with a chat_users table and create an ActiveRecord
-that can work with the chat_users table with ease. For the demo, we
-use sqlite as our database for ease of distributing the demo. The demo
-can be extended to use other databases such as MySQL or Postgres SQL easily.
-We define the chat_users table as follows.
-
-CREATE TABLE chat_users
-(
- username VARCHAR(20) NOT NULL PRIMARY KEY,
- last_activity INTEGER NOT NULL DEFAULT "0"
-);
-
-Next we define the corresponding ChatUserRecord class and save it as
-chat/protected/App_Code/ChatUserRecord.php (you need to create the
-App_Code directory as well). We also save the sqlite database file
-as App_Code/chat.db.
-
-class ChatUserRecord extends TActiveRecord
-{
- const TABLE='chat_users';
-
- public $username;
- public $last_activity;
-
- public static function finder($className=__CLASS__)
- {
- return parent::finder($className);
- }
-}
-
-Before using the ChatUserRecord class we to configure a default
-database connection for ActiveRecord to function. In the chat/protected/application.xml
-we import classes from the App_Code directory and add an
-ActiveRecord configuration module.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Custom User Manager class
-
To implement a custom user manager module class we just need
-to extends the TModule class and implement the IUserManager
-interface. The getGuestName(), getUser() and validateUser()
-methods are required by the IUserManager interface.
-We save the custom user manager class as App_Code/ChatUserManager.php.
-
-
-class ChatUserManager extends TModule implements IUserManager
-{
- public function getGuestName()
- {
- return 'Guest';
- }
-
- public function getUser($username=null)
- {
- $user=new TUser($this);
- $user->setIsGuest(true);
- if($username !== null && $this->usernameExists($username))
- {
- $user->setIsGuest(false);
- $user->setName($username);
- $user->setRoles(array('normal'));
- }
- return $user;
- }
-
- public function addNewUser($username)
- {
- $user = new ChatUserRecord();
- $user->username = $username;
- $user->save();
- }
-
- public function usernameExists($username)
- {
- $finder = ChatUserRecord::finder();
- $record = $finder->findByUsername($username);
- return $record instanceof ChatUserRecord;
- }
-
- public function validateUser($username,$password)
- {
- return $this->usernameExists($username);
- }
-}
-
-
-The getGuestName()
-method simply returns the name for a guest user and is not used in our application.
-The getUser() method returns a TUser object if the username
-exists in the database, the TUser object is set with role of "normal"
-that corresponds to the <authorization> rules defined in our
-config.xml file.
-
-
The addNewUser() and usernameExists()
-method uses the ActiveRecord corresponding to the chat_users table to
-add a new user and to check if a username already exists, respectively.
-
-
-
The next thing to do is change the config.xml configuration to use
-our new custom user manager class. We simply change the <module>
-configuration with id="users".
-
-
-
-
-
Authentication
-
To perform authentication, we just want the user to enter a unique
-username. We add a
-
-for validate the uniqueness of the username and add an OnClick event handler
-for the login button.
-
-<com:TCustomValidator
- ControlToValidate="username"
- Display="Dynamic"
- OnServerValidate="checkUsername"
- ErrorMessage="The username is already taken." />
-
-...
-
-<com:TButton Text="Login" OnClick="createNewUser" />
-
-In the Login.php file, we add the following 2 methods.
-
-function checkUsername($sender, $param)
-{
- $manager = $this->Application->Modules['users'];
- if($manager->usernameExists($this->username->Text))
- $param->IsValid = false;
-}
-
-function createNewUser($sender, $param)
-{
- if($this->Page->IsValid)
- {
- $manager = $this->Application->Modules['users'];
- $manager->addNewUser($this->username->Text);
-
- //do manual login
- $user = $manager->getUser($this->username->Text);
- $auth = $this->Application->Modules['auth'];
- $auth->updateSessionUser($user);
- $this->Application->User = $user;
-
- $url = $this->Service->constructUrl($this->Service->DefaultPage);
- $this->Response->redirect($url);
- }
-}
-
-The checkUserName() method uses the ChatUserManager class
-(recall that in the config.xml configuration we set the
-ID of the custom user manager class as "users") to validate the username
-is not taken.
-
-
-In the createNewUser method, when the validation passes (that is,
-when the user name is not taken) we add a new user. Afterward we perform
-a manual login process:
-
-
First we obtain a TUser instance from
-our custom user manager class using the $manager->getUser(...) method.
-
Using the TAuthManager we set/update the user object in the
- current session data.
-
Then we set/update the Application's user instance with our
- new user object.
-
-
-
-Finally, we redirect the client to the default Home page.
-
-
-
Default Values for ActiveRecord
-
If you try to perform a login now, you will receive an error message like
-"Property 'ChatUserRecord::$last_activity' must not be null as defined
-by column 'last_activity' in table 'chat_users'.". This means that the $last_activity
-property value was null when we tried to insert a new record. We need to either
-define a default value in the corresponding column in the table and allow null values or set the default
-value in the ChatUserRecord class. We shall demonstrate the later by
-altering the ChatUserRecord with the addition of a set getter/setter
-methods for the last_activity property.
-
-
-private $_last_activity;
-
-public function getLast_Activity()
-{
- if($this->_last_activity === null)
- $this->_last_activity = time();
- return $this->_last_activity;
-}
-
-public function setLast_Activity($value)
-{
- $this->_last_activity = $value;
-}
-
-Notice that we renamed $last_activity to $_last_activity (note
-the underscore after the dollar sign).
-
-
-
Main Chat Application
-
Now we are ready to build the main chat application. We use a simple
-layout that consist of one panel holding the chat messages, one panel
-to hold the users list, a textarea for the user to enter the text message
-and a button to send the message.
-
-
-
-
- Prado Chat Demo
-
-
-
-<com:TForm>
-
-</com:TForm>
-
-
-
-We added two Active Control components: a
-
-and a
-.
-We also added a
-
-that will be very useful for understanding how the Active Controls work.
-
-
-
Exploring the Active Controls
-
We should have some fun before we proceeding with setting up the chat buffering. We want
-to see how we can update the current page when we receive a message. First, we add
-an OnClick event handler for the Send button.
-
-
-<com:TActiveButton ID="sendButton" CssClass="send-button"
- Text="Send" OnClick="processMessage"/>
-
-And the corresponding event handler method in the Home.php class (we
-need to create this new file too).
-
-class Home extends TPage
-{
- function processMessage($sender, $param)
- {
- echo $this->userinput->Text;
- }
-}
-
-If you now type something in the main application textbox and click the send button
-you should see whatever you have typed echoed in the TJavascriptLogger console.
-
-
-
To append or add some content to the message list panel, we need to use
-some methods in the
-
-class which is available through the CallbackClient property of the
-current TPage object. For example, we do can do
-
-function processMessage($sender, $param)
-{
- $this->CallbackClient->appendContent("messages", $this->userinput->Text);
-}
-
-This is one way to update some part of the existing page during a callback (AJAX style events)
-and will be the primary way we will use to implement the chat application.
-
-
-
Active Record for chat_buffer table
-
To send a message to all the connected users we need to buffer or store
-the message for each user. We can use the database to buffer the messages. The
-chat_buffer table is defined as follows.
-
-CREATE TABLE chat_buffer
-(
- id INTEGER PRIMARY KEY,
- for_user VARCHAR(20) NOT NULL,
- from_user VARCHAR(20) NOT NULL,
- message TEXT NOT NULL,
- created_on INTEGER NOT NULL DEFAULT "0"
-);
-
-The corresponding ChatBufferRecord class is saved as
-App_Code/ChatBufferRecord.php.
-
-
-class ChatBufferRecord extends TActiveRecord
-{
- const TABLE='chat_buffer';
-
- public $id;
- public $for_user;
- public $from_user;
- public $message;
- private $_created_on;
-
- public function getCreated_On()
- {
- if($this->_created_on === null)
- $this->_created_on = time();
- return $this->_created_on;
- }
-
- public function setCreated_On($value)
- {
- $this->_created_on = $value;
- }
-
- public static function finder($className=__CLASS__)
- {
- return parent::finder($className);
- }
-}
-
-
-
-
Chat Application Logic
-
We finally arrive at the guts of the chat application logic. First, we
-need to save a received message into the chat buffer for all the
-current users. We add this logic in the ChatBufferRecord class.
-
-
-public function saveMessage()
-{
- foreach(ChatUserRecord::finder()->findAll() as $user)
- {
- $message = new self;
- $message->for_user = $user->username;
- $message->from_user = $this->from_user;
- $message->message = $this->message;
- $message->save();
- if($user->username == $this->from_user)
- {
- $user->last_activity = time(); //update the last activity;
- $user->save();
- }
- }
-}
-
-We first find all the current users using the ChatUserRecord finder
-methods. Then we duplicate the message and save it into the database. In addition,
-we update the message sender's last activity timestamp. The above piece of code
-demonstrates the simplicity and succinctness of using ActiveRecords for simple database designs.
-
-
-
The next piece of the logic is to retrieve the users' messages from the buffer.
-We simply load all the messages for a particular username and format that message
-appropriately (remember to escape the output to prevent Cross-Site Scripting attacks).
-After we load the messages, we delete those loaded messages and any older
-messages that may have been left in the buffer.
-
";
-}
-
-
-To retrieve a list of current users (formatted), we add this logic to the
-ChatUserRecord class. We delete any users that may have been inactive
-for awhile.
-
-public function getUserList()
-{
- $this->deleteAll('last_activity < ?', time()-300); //5 min inactivity
- $content = '
';
- foreach($this->findAll() as $user)
- $content .= '
'.htmlspecialchars($user->username).'
';
- $content .= '
';
- return $content;
-}
-
-
-
Note:
-For simplicity
-we formatted the messages in these Active Record classes. For large applications,
-these message formatting tasks should be done using Prado components (e.g. using
-a TRepeater in the template or a custom component).
-
-
-
-
Putting It Together
-
Now comes to put the application flow together. In the Home.php we update
-the Send buttons OnClick event handler to use the application
-logic we just implemented.
-
-function processMessage($sender, $param)
-{
- if(strlen($this->userinput->Text) > 0)
- {
- $record = new ChatBufferRecord();
- $record->message = $this->userinput->Text;
- $record->from_user = $this->Application->User->Name;
- $record->saveMessage();
-
- $this->userinput->Text = '';
- $messages = $record->getUserMessages($this->Application->User->Name);
- $this->CallbackClient->appendContent("messages", $messages);
- $this->CallbackClient->focus($this->userinput);
- }
-}
-
-We simply save the message to the chat buffer and then ask for all the messages
-for the current user and update the client side message list using a callback
-response (AJAX style).
-
-
-
At this point the application is actually already functional, just not very
-user friendly. If you open two different browsers, you should be able to communicate
-between the two users whenever the Send button is clicked.
-
-
-
The next part is perhaps the more tricker and fiddly than the other tasks. We
-need to improve the user experience. First, we want a list of current users
-as well. So we add the following method to Home.php, we can call
-this method when ever some callback event is raised, e.g. when the Send
-button is clicked.
-
-protected function refreshUserList()
-{
- $lastUpdate = $this->getViewState('userList','');
- $users = ChatUserRecord::finder()->getUserList();
- if($lastUpdate != $users)
- {
- $this->CallbackClient->update('users', $users);
- $this->setViewstate('userList', $users);
- }
-}
-
-
-
-
Actually, we want to periodically update the messages and user list as new
-users join in and new message may arrive from other users. So we need to refresh
-the message list as well.
-
-function processMessage($sender, $param)
-{
- ...
- $this->refreshUserList();
- $this->refreshMessageList();
- ...
-}
-
-protected function refreshMessageList()
-{
- //refresh the message list
- $finder = ChatBufferRecord::finder();
- $content = $finder->getUserMessages($this->Application->User->Name);
- if(strlen($content) > 0)
- {
- $anchor = (string)time();
- $content .= "";
- $this->CallbackClient->appendContent("messages", $content);
- $this->CallbackClient->focus($anchor);
- }
-}
-
-The anchor using time() as ID for a focus point is so that when the
-message list on the client side gets very long, the focus method will
-scroll the message list to the latest message (well, it works in most browsers).
-
-
-
Next, we need to redirect the user back to the login page if the user has
-been inactive for some time, say about 5 mins, we can add this check to any stage
-of the page life-cycle. Lets add it to the onLoad() stage.
-
-public function onLoad($param)
-{
- $username = $this->Application->User->Name;
- if(!$this->Application->Modules['users']->usernameExists($username))
- {
- $auth = $this->Application->Modules['auth'];
- $auth->logout();
-
- //redirect to login page.
- $this->Response->Redirect($this->Service->ConstructUrl($auth->LoginPage));
- }
-}
-
-
-
-
Improving User Experience
-
The last few details are to periodically check for new messages and
-refresh the user list. We can accomplish this by polling the server using a
-
-control. We add a TTimeTriggeredCallback to the Home.page
-and call the refresh handler method defined in Home.php.
-We set the polling interval to 2 seconds.
-
-<com:TTimeTriggeredCallback OnCallback="refresh"
- Interval="2" StartTimerOnLoad="true" />
-
-
-function refresh($sender, $param)
-{
- $this->refreshUserList();
- $this->refreshMessageList();
-}
-
-
-
-
The final piece requires us to use some javascript. We want that when the
-user type some text in the textarea and press the Enter key, we want it
-to send the message without clicking on the Send button. We add to the
-Home.page some javascript.
-
-
-<com:TClientScript>
-Event.observe($("<%= $this->userinput->ClientID %>"), "keypress", function(ev)
-{
- if(Event.keyCode(ev) == Event.KEY_RETURN)
- {
- if(Event.element(ev).value.length > 0)
- new Prado.Callback("<%= $this->sendButton->UniqueID %>");
- Event.stop(ev);
- }
-});
-</com:TClientScript>
-
-Details regarding the javascript can be explored in the
-Introduction to Javascript section of the quickstart.
-
-
-
This completes the tutorial on making a basic chat web application using
-the Prado framework. Hope you have enjoyed it.
-
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.
- class="figure" />
- You can try the application locally or at
- Pradosoft.com.
- Notice that the application still functions exactly the same if javascript
- is not available on the user's browser.
-
-
-
Downloading and Installing Prado
-
To install Prado, simply download the latest version of Prado from
- http://www.pradosoft.com
- and unzip the file to a directory not accessible by your web server
- (you may unzip it to a directory accessible by the web server if you wish
- to see the demos and test). For further detailed installation, see the
- Quickstart Installation guide.
-
-
-
Creating a new Prado web Application
-
The quickest and simplest way to create a new Prado web application is
- to use the command tool prado-cli.php found in the framework
- directory of the Prado distribution. We create a new application by running
- the following command in your
- command prompt or console. The command creates a new directory named
- currency-converter in your current working directory.
- You may need to change to the appropriate directory
- first.
- See the Command Line Tool
- for more details.
-
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>
-
-</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.
- class="figure" />
-
-
-
- The first component we add is a
-
- that basically corresponds to the HTML <form> element.
- In Prado, only oneTForm element is allowed per page.
-
-
-
The next two pair of component we add is the
-
- and
-
- 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
-
- 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
- , 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".
-
- 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.
-
- 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.
-
- 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
- . To ensure 2 and 3, we add one
- . 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
- . 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.
-
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,
- ,
- 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,
- , such that the server side can update the browser without
- reloading the page.
-
-
-
- Amount in Other Currency:
- <com:TActiveLabel ID="total" CssClass="result" />
-
- 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".
-
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).
-
The ClientSide.OnLoading and various
- 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).
-
- The first line <%@ Theme="Basic" %> defines the
- theme to be used for this page. The
-
- 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.
- class="figure" />
- This completes introduction tutorial to the Prado web application framework.
-
-
diff --git a/demos/quickstart/protected/pages/Tutorial/fr/chat1.png b/demos/quickstart/protected/pages/Tutorial/fr/chat1.png
deleted file mode 100755
index 8288b496..00000000
Binary files a/demos/quickstart/protected/pages/Tutorial/fr/chat1.png and /dev/null differ
diff --git a/demos/quickstart/protected/pages/Tutorial/fr/chat2.png b/demos/quickstart/protected/pages/Tutorial/fr/chat2.png
deleted file mode 100755
index 97cbc51d..00000000
Binary files a/demos/quickstart/protected/pages/Tutorial/fr/chat2.png and /dev/null differ
diff --git a/demos/quickstart/protected/pages/Tutorial/fr/example1.png b/demos/quickstart/protected/pages/Tutorial/fr/example1.png
deleted file mode 100755
index 0c7da7ba..00000000
Binary files a/demos/quickstart/protected/pages/Tutorial/fr/example1.png and /dev/null differ
diff --git a/demos/quickstart/protected/pages/Tutorial/fr/example2.png b/demos/quickstart/protected/pages/Tutorial/fr/example2.png
deleted file mode 100755
index 1df56cfb..00000000
Binary files a/demos/quickstart/protected/pages/Tutorial/fr/example2.png and /dev/null differ
--
cgit v1.2.3