Love Fuel?    Donate

FuelPHP Forums

Ask your question about FuelPHP in the appropriate forum, or help others by answering their questions.
Form, validation, model. Fieldset?
  • I begun to migrate an extended Form module I built in CI to a Fuel package. Before continue, I thought it's a good idea to hear the community opinion on my approach to the problem.
    Perhaps I'm going the wrong way, perhaps someone have a suggestion (or finds it useful), or maybe what I'm doing is what the Fieldset class is intended for (I've read the documentation for the Fieldset class, downloaded the FuelDocGenerator, but I'm not sure I get it well).
    When building a form I usually do a javascript validation first and then a server validation.
    I like the error messages, if any, appear next to the field with the problem are they generated via javascript or in a server response.
    The CI form class (as Fuel does) covers the standard html inputs, but you may want to have a rich text editor, an autocomplete field, a nice custom checkbox, etc. When retreiving data from the user my approach follows this pattern:
    - If we are modifying a current record, first populate a model with it, or create a new empty model.
    - Override the model with the post data
    - Validate the model, and if it's ok, save it. - If the model does not pass the validation (or if you are displaying the form for first time), you can pass the model when creating the form fields.
    - The Form package is a main Form class and a subset of Input classes which extends the properties of some of the classic ones (text, textarea, select, etc), and also provides wrappers for a Tiny editor, autocomplete, datepicker, colorpicker, uploads via uplodify, and a kind of 'media control' which handles and organize a set of images in a gallery.
    - Javascript needed for each control is part of the input class definition. The form class gathers this info and adds it to the template via the Asset Class.
    - Once you added the fields to the Form object, you can render in your view the complete form, by groups of fields or one by one.
    - Rendering the fields takes care of showing labels, the values of the field and the error messages. Here is an example of a working form:
    In the controller
    public function action_edit($id=0)
    {
      // get the current data for the id
      $model = \Content\Model_page::find($id);
      if(!$model) $model = new \Content\Model_page();
    
      // validate the model
      if($model->validate()) // I've extended the ORM model to get the Post data and validate it
      {
       $model->module = 'pages';
       $model->save();
       \Response::redirect('your_action_list');
      }
      
      // create the form passing the action as parameter. Second parameter is the asset group for the associated javascript
      $form = new \Forms\Form("admin/content/pages/edit/$id", 'backend');
      
      // information on validation rules, label and input info can be stored in the model $_properties variable
      $form->add_model('id',$model); 
      // wich is a shorcut for
      $form->add('hidden', 'input-name', 'input-value');
    
      $f = $form->add_model('title',$model); // a text field
      // wich is a shorcut for
      $f = $form->add('text', 'input-name', 'input-value', 'input-label');
      $f ->rules('required'); // if not setted in the model.
      
      // a tiny editor field, with few edit buttons
      $f = $form->add_model('preview', $model, 'main_left');
      $f->config(array('mode'=>'simple'));
    
      // a tiny editor field, with all edit options
      $f = $form->add_model('body', $model, 'main_left');
      $f->config(array('mode'=>'advanced'));
      
      
      $data = array(
       'form'=> $form, 
       'cancel'=>'your_list_action',
      );
      $this->template->content =  \View::factory('admin/edit', $data, false);
     }
    

    In the 'edit' View just:
    $form->render() // this renders the complete form
    
    // or if you wish to render the fields individually
    $form->open()
    $form->title->render()
    $form->preview->render()
    // etc
    $form->close();
    

    One flaw I see in this approach is that works fine if you are working with data models, but it's not well suited for a contact form.
    I'll be glad in hearing any comment. Best regards.
  • I'm the wrong person to ask (not that you did). I believe in strict separation between bussines logic and presentation, and therefore never use layout defining elements in my code. I'm still contemplating about using the Viewmodel, and declare it 'part of the presentation layer', but I know several of the UI designers I work(ed) with haven't got a clue about PHP (and both parties like to keep it that way). Using Fuel code to do HTML markup would make both our lives more complicated. I'm still thinking about doing something clever with Form and Fieldset objects in the Viewmodel, so they're easy to use for an UI designer (as in full markup flexibility)...
  • WanWizard, I understand your point of view.
    As a 'one man band web developer', I usually do UI my self also in the projects I work so my point of view is very influenced with that. About strict separation of bussines logic and presentation, I think is mandatory for some work environments. Also believe the current trends of UI behavior design is leading to and intermediate figure who can 'struggle' (don't know if it's the correct word) with both presentation and logic (at least to understand how to deal with a Form::anchor() code and to setup a javascript accordion menu).
    I'm still thinking about doing something clever with Form and Fieldset objects in the Viewmodel, so they're easy to use for an UI designer (as in full markup flexibility)...
    Can you expand your thoughts on this a little further? Thanks for your answer.
  • I haven't gotten around to the clever bit yet. I might go for something like simpletags, and provide a tag interface to Fuel methods, something like
    {fuel:form name="test" action="/here/there"}
    <!-- html here -->
    {/fuel:form}
    

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion