I'm not sure if this is in the proper portion of the forum because it's part code critique and part question.

I've been working on a form generator basically to practice using oop which I have no experience with. But in doing so I started to wonder if there is a practical use to creating a form generator because it seems like the code I'm using to create the form using oop is just as much work as creating a form strictly with html. Then I started thinking maybe my implementation is flawed. Here is the code I've created so far

<?php
class create_Form
{
	var $formAction;
	var $formMethod;
	var $formClass;

function start_form()
{
	printf("<form action=\"%s\" method=\"%s\">", $this->formAction, $this->formMethod, $this->formClass);
}
function end_form()
{
	printf('</form>');
}
}
?>
<?php
class create_text_Field
{

function input_field($fieldSize)
	{
		printf("<input type=\"text\" size=\"%s\" />", $fieldSize);
	}

}
?>
<?php
include("formGenerator.php");
include("formFieldGenerator.php");
$clientForm = new create_Form();
$clientForm->formAction = "http://www.myaction.com";
$clientForm->formMethod = "post";
$clientForm->formClass = "default";

$clientForm->start_form();
$nameField = new create_Text_Field;
$nameField->input_field("20");
$clientForm->end_form();
?>

So I have one class to create the form and one to create the fields. But it just seems like when I start to assign values to the form fields it's just as much work or more than just doing it in html. So my questions are 1) is my implementation of oop flawed 2) or is it just not worth it to build a class for forms?

By the way this code isn't the complete form generator I still have lots of work to do on it. I just need some direction.

    One clear advantage to a form-generation class is that it makes it possible to provide input types that go beyond just plain HTML form elements (date pickers and tree views spring to mind); since the class can contain all the HTML and any associated Javascript for the more elaborate field, and to the programmer it would be as easy to use as any other.

    Another advantage is that the class would be easier to use by other parts of the script, to build up forms programmatically.

    A third is that the class could then be replaced by another with a different interface that produces forms for other applications.

      Thanks, I appreciate the comments. I'll work on it more then.

        No wait, stop, stop, stop... You need to take a step back.

        You are going about this the wrong way, no doubt you are still in Procedural mode and I have been through this as I was starting out.

        The name of the class "Create_Form" is wrong. Create_Form cannot be an object and SHOULD NOT be an object.

        First thing's first, you need to name your classes as Objects.

        The idea behind the Object Oriented Paradigm is that everything is an object. I know that it's a little vague and general, so let me explain.

        As I look around me now, I see many objects. For instance at this point in time, I am looking at a speaker.

        It's an object. The speaker is sent messages from my amplifier which takes messages from the computer.

        So in essense we have three objects here:

        i) The speaker
        ii) The amplifier
        iii) The computer.

        Now say that you wanted to write up a program to play sound, you wouldn't want to call your classes names like "Play_Sound" or "Send_Sound" you'd call it the object you were designing the class for.

        Same goes for your Form Generator.

        If you can imagine the Form Generator was a machine, what would you call it? Create_form? no. We'll call it "Form_Generator"

        What does a form generator do? Generate forms...

        So that's a method (or rather action) of the Form_generator.

        So your form generator would look something like so.

        
        Class Form_Generator
        {
             function Form_Generator() 
             {
        
         }
        
         function generate_form()
         {
        
         }
        }
        
        

        Now let's think about the form generator for a little bit here. The name "Form_Generator" mainly deals with creating Forms as a whole. So what kinds of forms would there be? There are Login Forms, Search Forms, Application Forms. Many different form types.

        So let's reflect this in our Form_Generator class. Which is a blueprint of our Form_Generator object.

        
        Class Form_Generator
        {
            var $_type; // as you go on with your learning, you'll find that the underscore is a naming convention people use in PHP 4 to specify that a property/method is private/protected. Visibility is not implemented in PHP 4. You'll learn more about visibility later on. 
        
         function Form_Generator($form_type) 
         {
              $this->_type = $type;
         }
        
         function generate_form()
         {
        
         }
        }
        
        $form_generator =& new Form_Generator('login');
        
        

        So what we have now is a Form_Generator which has been initialised to be creating a login form.

        At this stage, I am at a class design crossroads. Do I... create new methods/actions for each form type? or... do I use PHP magic to do some nifty self discovery tricks? At this stage, let's be lazy and do the latter (php magic).

        Now, to my experience, whenever something is called "Generator" I automatically think. "Factory Method" a common design technique used in classes.

        What a factory method does is as its name says. It pumps out objects. In the form generator's case, Form Objects.

        Let's try this out.

        
        Class Form_Generator
        {
            var $_type; // as you go on with your learning, you'll find that the underscore is a naming convention people use in PHP 4 to specify that a property/method is private/protected. Visibility is not implemented in PHP 4. You'll learn more about visibility later on. 
        
         function Form_Generator($form_type) 
         {
              $this->_type = $form_type;
         }
        
         function &generate_form()
         {
              $formClassName = $this->_type . '_Form';
              if (class_exists($formClassName)) {
                   $form_object =& new $formClassName();
                   return $form_object;
              } else {
                   trigger_error($formClassName . ' does not exist!');
              }
         }
        }
        
        $form_generator =& new Form_Generator('login');
        $login_form = $form_generator->generate_form();
        

        Alright, so what we need to have here now, is the login form... What does a login form do? what does it have? It has form elements...

        The design continues...

        It is a Form and has form Elements like input fields of different sorts, textareas and select elements.

        The keywords "is a" that were uttered while thinking outloud put together with the consideration that we will have other objects like search_form and application_form later on signifies that inheritance could be used here.

        To cut a long story short, we'll skip creating the "Elements" object if you need it, you can add it later on - that's the great thing about OOP, if you design it well enough you can change the code up with less mess later on.

        So... we have a base Form class - this is the parent and will have common functionality all the other children will inherit. Like say... the login class for instance.

        class Form 
        {
             function Form()
             {
        
         }
        
         function _input_field($type, $value, $name, $is_checked = false)
         {
               $checked = ($is_checked) ? 'checked' : null;
               return '<input type="' . $type . '" value="' . $value . '" name="'.$name.'" ' . $checked . '/>'."\n";
         }
        
         function _textarea($value, $name, $rows, $cols)
         {
              return '<textarea name="'.$name.'" rows ="'.$rows.'" cols="'.$cols.'">' . $value . '</textarea>'."\n";
         }
        
         function _select($default,$name)
         {
               //whatever - too lazy
         }
        
         function _get_form($method, $action, $enctype, $html)
         {
               $formHtml .= '<form method="'.$method.'" action="'.$action.'" enctype="'.$enctype.'">'."\n";
               $formHtml .= $html."\n";
               $formHtml .= '</form>'."\n";
               return $formHtml;
         }
        }
        

        Now for the Form's first child, the login class. Notice that we do not need a constructor for the child class as it inherits the parents constructor also.

        
        Class Login_Form
            extends Form
        {
             function _make_login_form()
             {
                   $html = '<table>'."\n";
                   $html .= "\t".'<tr>'."\n";
                   $html .= "\t\t".'<td>username</td>'."\n";
                   $html .= '<td>'.$this->_input_field('text','enter username here','user_name').'</td>';
                   $html .= "\t".'</tr>'."\n";
                   $html .= "\t".'<tr>'."\n";
                   $html .= "\t\t".'<td>password</td>'."\n";
                   $html .= '<td>'.$this->_input_field('password','passwordhere','user_pass').'</td>';
                   $html .= "\t".'</tr>'."\n";
                   $html .= "\t".'<tr>'."\n";
                   $html .= "\t\t".'<td nowrap>Remember me:</td>'."\n";
                   $html .= '<td>'.$this->_input_field('checkbox','1','remember',true).'</td>';
                   $html .= "\t".'<tr>'."\n";
                   $html .= "\t\t".'<td>&nbsp;</td>'."\n";
                   $html .= '<td>'.$this->_input_field('submit','login','user_name').'
                   			'.$this->_input_field('reset','reset','user_name').'</td>';
                   $html .= "\t".'</tr>'."\n";
                   return $html;
             }
        
         function output_form()
         {
              return $this->_get_form('POST','','multipart/form-data',$this->_make_login_form());
         }
        }
        
        

        So finally our little form generator example is ready for use.

        
        $form_generator =& new Form_Generator('Login');
        $login = $form_generator->generate_form();
        echo $login->output_form();
        
        

        Sorry it's a little rushed, I went shallow in my explanations and there may have been some subjects covered in this little example that you may not know about just yet. Don't be disheartened, use this as a reference.

        I've been told once or twice about the "give the man a fish vs teach a man to fish" analogy... You can look at this as me giving you a Fishing Rod. a very simple fishing Rod, but one that has the necessary components for you to learn from and improve on.

        The classes I've written in this example have been tested and work.

        The thought process that went into development of the three classes have been noted down as I was developing them from scratch. This is how the thought process works as opposed to procedural where you think of actions first modules later.

        Object Oriented Analysis and Design works the other way around.

        Object (singular) First, Actions later.

        Remember, name your classes well. It is part of the design.

        Hope this helps.

        Regards,

          Thanks for the instruction. Looks like it's back to the drawing board for me. I think this example is one that I can definitely learn from along with the comments in the "Learning OOP (need guidance)" thread.

          Also, thanks for redirecting my thinking. It was much needed.

            you are most welcome...
            (always wanted to say that)

            Good luck with it!

            regards,

              Write a Reply...