Lesson 12 - Form framework for PHP - InputBox
In the previous lesson, Finishing the FormControl class in PHP, we finished the parent for our form controls. Now, everything is set for us to create our first control.
InputBox
An InputBox is a control based on HTML's input element. We'll use it to enter texts, emails, URL addresses, telephone numbers, and passwords. We'll also use the control on hidden fields and buttons.
The class will be very minimalistic:
class InputBox extends FormControl { private $text; public $type; public function __construct($name, $type, $label = '', $htmlParams = array()) { $this->type = $type; parent::__construct($name, $label, $htmlParams); } public function setText($text) { $this->text = $text; return $this; } public function setData($key, $text) { $this->text = $text; } public function renderControl($isPostBack) { $value = ($isPostBack && isset($_POST[$this->name]) && $this->type != 'password') ? $_POST[$this->name] : $this->text; $this->htmlParams['value'] = $value; $this->htmlParams['type'] = $this->type; $builder = new HtmlBuilder(); $builder->addElement('input', $this->htmlParams); return $builder->render(); } }
We inherited the class from the FormControl, which means that it comes with the validating mechanisms and has to implement the renderControl() method.
There are only two properties, the input name and the input type (just like in HTML).
As you can see, we store the type and leave the rest to the parent constructor. You should get what the setters do just by looking at them.
The only interesting method, here, is the renderComponent() method. Its $isPostBack parameter indicates whether the form has already been submitted (in case it finds some data in POST).
We store a value in the $value variable which will be displayed in the input. It will either be a value which the user has submitted or the field's default value. We display the submitted value in case the form has been submitted and we need to display its data. This situation will only happen if the user has filled something wrong and we returned the form to him/her. Therefore, we'll fill the form in with values from POST. If the input is of the password type, we won't fill anything in because passwords should always be re-entered for security reasons. If the user fills the form properly, we'll redirect them once the form processing is done, which clears the POST data and avoids the previous situation. We'll add this functionality in later on in the course. In all other cases, we'll fill the input with the default value. It's currently empty by default, however, we can also specify a default value. Then, we'll simply render the input using the HtmlBuilder and return the resulting HTML.
Testing
We've been adding stuff in for several lessons now and we still haven't tested any measurable output. Creating the Form class will take several more lessons and programming that long without seeing any results can make things less than exciting. Therefore, we'll take a little break and test our InputBox without a form (for now).
We'll create several form fields. Their definition will be a bit more complicated without the Form class, but we can't do anything about that as of right now.
$nameBox = new InputBox('name', 'text'); $nameBox->addRequiredRule() ->addMinLengthRule(3); $emailBox = new InputBox('email', 'email'); $emailBox->addRequiredRule() ->addPatternRule(FormControl::PATTERN_EMAIL) ->setText('@'); $passwordBox = new InputBox('password', 'password'); $passwordBox->addPasswordRule(); $ssnBox = new InputBox('social_security_number', 'text'); $ssnBox->addPatternRule('[0-9]{3}\-[0-9]{2}\-[0-9]{4}'); $button = new InputBox('submit', 'submit'); $button->setText('Submit'); $validateClient = true; $postBack = false;
You may add the code into a controller or even place it in a PHP file without any architecture. The form only contains four fields and a submit button.
The name is an input of the text type, which is a required field. The value has to be at least three characters long.
The email is an input of the email type and contains an "@" character as the default text. Then, we apply the email validation rule using a regular expression. On the client-side, this rule is not necessary since the browser validates email addresses automatically. However, we'll keep it there as well, for safe keeping.
The password is an input of the password type and contains the password validation rule (the password has to be longer than 5 characters).
The social security number is an input of the text type with a regular expression for the following pattern XXX-XX-XXXX.
The $validateClient variable specifies whether client validations should be generated. The $postBack variable contains information on whether the form has already been submitted. As you already know, these variables should be properties of the form. However, we don't have the form yet, so we'll have to work around that.
Let's go ahead and render the controls, manually, for now:
<form method="POST"> Name <br /> <?= $nameBox->render($validateClient, $postBack) ?> <br /> Email <br /> <?= $emailBox->render($validateClient, $postBack) ?> <br /> Password <br /> <?= $passwordBox->render($validateClient, $postBack) ?> <br /> Social security number <br /> <?= $ssnBox->render($validateClient, $postBack) ?> <br /><br /> <?= $button->render($validateClient, $postBack) ?> </form>
Here's what the result looks like:
Here's the HTML code for it:
<form method="POST"> Name <br /> <input name="name" id="name" required="required" pattern=".{3,}" value="" type="text" /> <br /> Email <br /> <input name="email" id="email" required="required" pattern="[a-z0-9._-]+@[a-z0-9.-]+\.[a-z]{2,4}$" value="@" type="email" /> <br /> Password <br /> <input name="password" id="password" pattern=".{6,}" value="" type="password" /> <br /> Social security number <br /> <input name="social_security_number" id="social_security_number" pattern="[0-9]{3}\-[0-9]{2}\-[0-9]{4}" value="" type="text" /> <br /> <input name="submit" id="submit" value="Submit" type="submit" /> </form>
Make sure to check that the client-side validations work. Enter a shorter name, an invalid email, or a short password. The password can be left blank since it's not a required field. The social security number has to be entered in the actual form, however, it's currently not required.
Last of all, we'll execute the validations on the server-side. Then, we set the $validateClient variable to false. Another way to submit an invalid form would be to open the development tools in your browser and simply remove the "required" and "pattern" attributes from the HTML code.
Now, let's execute the validations after the form is submitted. We'll have to do it manually again (for now):
if ($_POST) { $postBack = true; try { $nameBox->checkValidity(); $emailBox->checkValidity(); $passwordBox->checkValidity(); $ssnBox->checkValidity(); } catch (UserException $e) { echo($e->getMessage()); } }
Try to enter some invalid values, they'll all be caught on the server and a UserException will be thrown. You will then see that the values remain filled-in even after the form is submitted. The fields will be highlighted in red, once we add it later on, by the actual form.
As you can see, we're well on our way. The project in its current state can be downloaded below. In the next lesson, Form framework for PHP - Form, we'll implement the Form class.
Did you have a problem with anything? Download the sample application below and compare it with your project, you will find the error easily.
Download
By downloading the following file, you agree to the license terms
Downloaded 27x (8.19 kB)
Application includes source codes in language PHP