Tags: php rails ruby-on-rails

HTML_QuickForm in .... Rails ?

Caution Thinking Out Aloud: Okay the purists have just decided to kill me. Let the religious wars begin ! No seriously, everytime I do some coding in an old PHP app which is heavily dependent on HTML_QuickForm, I keep questioning how possible would it be to convert it across to Rails, and whether any other persons like myself would think all of their Christmases have come at once. Here's my hopefully rational thought processes behind this. Rails is a fantastic CRUD machine. If you want to build single model forms with validations in them, absolutely beautiful. Nothing could feel more clean and make you as a developer go 'thats sweet'. Fantastic. Now try and do a model-less form, with validations, or combine multiple models within one form. Things like the presenter pattern get bandied about. Real world case example - a form to choose options for defining a report. Nothing that you want to put in a model as it's not a represenation of a 'thing' (although some may argue it is). I wonder and am sitting on the fence of, whether to try implementing quickform for rails. For those that haven't been exposed to it, in a nutshell it's a brilliant little php library that lets you create a representation of a form, with rules, pass the form into a renderer which dumps out the html on a page, but that's not all, it assists you in processing the form on submission. So some code can look like this (not syntactically correct, but close enough), which does all of the hard work of writing out html, setting up client side js, and server side processing.
//page myform.php

$myform = new HtmlQuickForm('form_name', 'myform.php'); 
$abc = $myform->addElement('text', 'product_name', 'Product Name:'); 
$myform->addRule('product_name', 'required', 'You must enter a product name'); 
if ($myform->validate()) {
   //process form
   var_dump( $abc->getValue() ); 
} else {
   //setup form 
   $abc->setValue('123')
}

// then in any template which dumps out the rails code
$myForm->display(); 
It doesn't seem like much, but put half a dozen or more options on the form, different processing rules, and suddenly it's done a lot of the heavy lifting for you. What would it take to add this to Rails ? How would (I personally) fit it in. It doesn't really sit within either the model, view, or controller. The view should render the output, it doesn't really fit within a model as it's not a representation of a thing. It most closely sits in the controller, but you don't really want to clutter the controller with your form models. Here's some thoughts An initial idea, with everything defined in the controller, then dumped into the view by a @my_form.output
class FormController < Application 
  def do_form
    get_form
    if @myForm.posted 
       #do stuff
    else
       #populate stuff
    end
  end

protected
  def create_report
    @myform = RFormBuilder.new do |f|
       f.call_back_url = { :controller => 'form', :action => 'do_form' }
       f.name = 'myform'
    end
    @myform.add_text( :name => 'product_name', :label => 'Product Name', 
              :rule => { :required => :true, :msg => 'You must add this' } )

  end

end

OR Maybe we add in a new folder in the main app
  /app/
      /controllers
      /models
      /views
      /forms 
        myform.rb
And the treat myform.rb kinda like a model, but kinda not.

class MyForm < RFormBuilder
  defaults :name => 'my_form', :call_back_url => '/myform' 
  text_field :name => 'product_name', :label => 'Product Name', :required => :true
   
  #gets called when form is posted   
  def validate
    return true if field_product_type == 'abc'
  end 
end


# now in FormController 

 def do_form
    get_form
    @my_form = MyForm.new
    if @myForm.valid
       #do stuff
       render :text => @my_form.field_product_name
    else
       #populate stuff
    end
  end

What do you think ? Am I stark raving mad. Could this just work ? I think so and am willing to take up the challenge... Rowan
blog comments powered by Disqus
Creative Commons License
This work is licensed under a Creative Commons Attribution 3.0 Unported License.