Well I have had this idea in mind for a while. In my script I have php variables passed to html(now tpl thanks to smarty!) template file, and the process of building tables and forms are handled in PHP. This is usually sufficient for small forms/tables, like this one:
$form = "<form name='form1' method='post' action='login.php'>
<p>Username: <input name='username' type='text' id='username'></p>
<p>Password: <input name='password' type='password' id='password'></p>
<p><input type='submit' name='Submit' value='Submit'></p>
</form>";
The form above is a simple login form, which is easy to build anyway. Nonetheless, real life aint as simple as we imagine. In circumstances we come across different types of html elements, some have pre-defined values from MYSQL database! Even worse is a situation of select/option dropdown menu, which means we have to use a while/for loop in any forms/tables that contain them. This can soon turn our script into a mess.
So what is the solution? You get it, its this PHP GUI package I am meditating and actually have already begun working on. With this GUI package, it will be possible to write professional and well organized object oriented code like the one below to construct a page:
$page = new Frame;
$form = new Form("myform", "post", "index.php");
$form->add(new TextField("mytext", "This is a text field"), 1);
$text = new TextField();
$text->setID("text2");
$text->setName("my2ndtext");
$text->setValue("This is yet another text field");
$text->setMaxLength(10);
$form->add($text, 2);
$form->add(new TextArea("mytextarea", 45))
$submit = new Button();
// Default type is submit for button object
$submit->setName("My Button");
$submit->setValue("Click Me");
$submit->setAutofocus(TRUE);
// We are adding submit button to the index 500, lol. It works so long as we do not override existing indexes.
$form->add($submit, 500);
$page->add($form);
echo $page->render();
The GUI structure is defined as below:
Namespace GUI
Abstract Class GUIComponent
Abstract Class GUIContainer
Class Frame
Class Table
Class Row
Class Column
Class Form
Class Field
Abstract Class GUIList
Class RadioList
Class DataList
Class SelectList
Class MultiSelectList
Abstract Class Button
Class StdButton
Class RadioButton
Class CheckBox
Abstract Class TextField
Class TextField
Class PasswordField
Class TextArea
Abstract Class Basics
Class Option
Class Label
Class Legend
Class Cell
Abstract Class GUIRenderer
Class ButtonRenderer
Class TextRenderer
Class ListRenderer
Class TableRenderer
Class FormRenderer
Class ListRenderer
Class BasicsRenderer
So this looks quite complicated and ambitious? Maybe, but I'd say its worth trying. The GUI has two basic categories: Components and Renderers. Components can be pure components, or containers that enclose other components or containers. Renderers are objects that convert data field in each GUI component/container to the corresponding html readable string format. This GUI package is written in Composite design pattern, which turns out to be rather powerful. I also considered Decorator pattern, it might work out as well but right now I am sticking to Composite.
The idea is that each page is defined by a frame, a frame is apparently the top level container. But an empty frame renders to nothing, so you may want to add components and other containers to it. Many pages on my site have forms and tables, they are major players in the GUI system since almost all GUI components can be added to them. Basic components include button, which also have subcategories such as StdButton, RadioButton and CheckBox. TextField component has subcategories such as TextField, PasswordField and TextArea. Each component can be added to a container at any given index, the index determines the order they are displayed. The way the script is designed allows multi-layer rendering, which means you can simply render the frame and all tables, forms and buttons, textfields it contains will get rendered too.
So if you want to see an example, this is how it works out on a test script I have just written for StdButton. The script works rather well, as you can see from the screenshot. Right now I only have StdButton and ButtonRenderer concrete classes, but in not so distant all these GUI components will be made available one by one. Should be interesting, isnt it?
<?php
include_once("classes/abstract/abstract_object.php");
include_once("classes/abstract/abstract_guicomponent.php");
include_once("classes/abstract/abstract_guicomponent.php");
include_once("classes/abstract/abstract_guirenderer.php");
include_once("classes/abstract/abstract_button.php");
include_once("classes/class_stdbutton.php");
include_once("classes/class_buttonrenderer.php");
$button = new StdButton();
$button->setText("This is a Button!");
$button->setName("My Button");
$button->setType("button");
$button->setValue("Click Me!");
echo $button->getText();
echo "<br>";
echo $button->getName();
echo "<br>";
echo $button->getType();
echo "<br>";
echo $button->getValue();
echo "<br>";
echo $button->render();
$button2 = new StdButton("Yet Another Button", "your button", "Meh, what's going on?");
echo $button2->render();
?>
Screenshot:
So what do you think? I hope this will not take me more than 2-3 months to complete, and in fact my winter break is coming up soon so I should have fun doing this GUI project. I know many of you here are better programmers than me, so I definitely would love to hear suggestions and criticism. Thanks, and hope you all have enjoyed your thanksgiving.