Posts Tagged ‘forms’

Extending Rails Form Builders

Posted 01 Mar 2010 — by admin
Category Ruby on Rails

Extending forms in Rails is simple and will greatly reduce the amount of code in your views. This example is taken right from the Agile Web Development book on Rails(2.1.*) with one minor tweak. I want to pass a label argument along with the field name so that I can display a more human friendly string to represent the form field.

# RAILS_ROOT/app/helpers/custom_tag_builder.rb
class CustomTagBuilder < ActionView::Helpers::FormBuilder

  def self.create_tagged_field(method_name)
    define_method(method_name) do |label, *args|
      label_name = args.first.blank? ? label : args.first[:label] # my change
      @template.content_tag("p",
        @template.content_tag("label",
          label_name.to_s.humanize, :for => "#{@object_name}_#{label}") +" 
"+ super) end end field_helpers.each do |name| create_tagged_field(name) end end

You can then use this in your views

form_for @your_model, :builder => CustomTagBuilder do |f|
  f.text_field :fullname
  f.text_field :email, :label => "Email (will not be published)"

My change tests for the presence of a label argument otherwise using the name of the form field/model attribute. In this case the fullname attribute will be outputted as “Fullname” while “Email (will not be published)” as the label for the email text field.

Trouble Using Attr_Accessor in Rails Models and Forms

Posted 07 Aug 2009 — by admin
Category Ruby on Rails

You might use the attr_accessible method to create getters and setters for a class that has attributes which don’t map directly to corresponding fields in a database. For example let’s take the scenario where you are processing a credit card transaction. You don’t want to save the credit card details, such as card number and verification value etc, however you still want to use these attributes in a form and you want to perform validations on them.

class CreditCardPurchase < ActiveRecord::Base
  attr_accessor :number, :cvv
end

The only probem that I've run into is using the attr_accessor on datetime select form fields. Rails won't be able to determine the "klass" and will spit out a nasty error. Looks there is some discussion around this bug. I've got another post about this topic http://seanbehan.com/ruby-on-rails/problem-slash-bug-in-rails-with-attr_accessor-and-datetime-select-fields/ but unfortunately not a whole lot of resultion :(

Nested Attributes in a Form for Has_One Model Association in Rails

Posted 23 Jul 2009 — by admin
Category Ruby on Rails

Just for reference…

class Member < ActiveRecord::Base
    has_one :member_profile
    accepts_nested_attributes_for :member_profile
end


<% form_for @member do |f| -%>
       <%= f.label :fullname %> <%= f.text_field :fullname %>
	<% f.fields_for :member_profile, @member.member_profile do |member_profile|%>

<%= member_profile.label :about %><%= member_profile.text_field :about %>

<%= member_profile.label :favorite_color %><%= member_profile.text_field :favorite_color %>

	<% end %>

Using Prototype to Access Form Data

Posted 26 Mar 2009 — by admin
Category Programming

Prototype has a powerful API for accessing and manipulating the Document Object Model, A.K.A the DOM. The following code will let you interact with a simple web form.

Suppose we have a form that contains hidden/or locked inputs and they need to be updated dynamically. If the user changes a select field or if a checkbox is de/selected, other values in the form need updating. This could be required when products have options and associated price points. If you want to offer the user the option to switch options without refreshing or navigation this is a simple and effective approach.

… Sample form…

<input type="hidden" name="option_plan_id" id="option_plan_id" value="1"><br/>
<input type="hidden" name="amount" value="150" id="amount">

<select name="select-plan" id="select-plan">
<option value="1, 150">
USD 150 - 1 person
</option>
<option value="2, 200">
USD 200 - 2 people
</option>
</select>

In this example I want to update the values on the amount and option_plan_id input fields. The first thing I need to make sure of is that the page has fully loaded. I’ll make sure that my code executes in this context by placing it inside the document.observe method. I’ll then set up an observer on my select field and if it changes, make assignments. Now, in this example, I just saved the plan id and amount information as a string. In my javascript code I split apart the string and then make the assignments. There are other, probably better, ways of doing this. For instance you could store serialized data/json, and then work with it inside your event. This seems simple enough, however, you’ll have to pay attention in the future, if your storage format changes! Here is the sample Prototype javascript code

<script type="text/javascript" charset="utf-8">
document.observe("dom:loaded", function(){ //when dom is fully loaded do -
//update fields when option is selected
Event.observe('select-plan', 'change', function(event){
var data = this.getValue();
var plan = data.split(",").first(); //breaks apart by comma
var amount = data.split(",").last();
$('plan_option_id').setAttribute('value', plan);
$('amount').setAttribute('value', amount);
});
});
</script>

Thats it for now!