As a first step, we should start with HTML as plain as we can get it.

Here's the HTML for the first result of "html radio example":

<input type="radio" name="group1" value="Milk"> Milk<br>
<input type="radio" name="group1" value="Butter" checked> Butter<br>
<input type="radio" name="group1" value="Cheese"> Cheese

To integrate with Hobo and rails we need to get both name and value set correctly. How do we figure that out? Simple, take a look at the source code output by the stock Hobo app for the select box. In your case, you'd probably find the name is recipe[country_id], and the values for the options in the select are probably 1 & 2 (but could quite likely be something else).

So this should work.   Terribly hard coded, but it would work:

<input type="radio" name="recipe[country_id]" value="1" checked />American<br/>
<input type="radio" name="recipe[country_id]" value="2" />Chinese

Note that I had to adjust the tags slightly to use valid XML syntax.

Let's remove the hardcoding one by one. First let's make sure we're both working in the same context:

<form>
  <field-list fields="title,body,country">
    <country-view:>
<input type="radio" name="recipe[country_id]" value="1" checked />American<br/>
      <input type="radio" name="recipe[country_id]" value="2"/>Chinese<br/>
    </country-view:>
  </field-list>
</form>

Inside of country-view our context (aka this) is set to the country, and this_parent is set to the recipe.

The first obvious problem is those numbers: they'll be different on different installations -- some fiddling in the console let's us come up with code to figure them out dynamically:

<input type="radio" name="recipe[country_id]" value="#{Country.find_by_name('American').id}" checked/>American</br>

The next obvious problem is that "checked". Our hardcoded code always sets it to "American", we want it to be set to our current value. The current value is in 'this', so let's use it:

<input type="radio" name="recipe[country_id]" value="#{Country.find_by_name('American').id}" checked="&this._?.name=='American'"/>American<br/>

(Note the difference between #{} and &: #{} does string substitution and & uses the ruby value. If we used #{} for checked, it would get converted from a boolean to a string before Hobo noticed.

Many people could stop here, but let's keep going. The next step would be to pull the countries from the database rather than hardcoding them.

<% Country.all.each do |country| %>
<input type="radio" name="recipe[country_id]" value="#{country.id}" checked="&this==country"/><%= country.name %><br/>
<% end %>

We used an ERB style loop here.  Let's compare with a DRYML style loop:

<% saved_this = this %>
<repeat with="&Country.all">
<input type="radio" name="recipe[country_id]" value="#{this.id}" checked="&saved_this==this"/><view/><br/>
</repeat>

Notice a couple of things: repeat changes the context, so I saved off the old context so it could be used inside the loop. I also used the view polymorphic tag to display the country name rather than just printing it directly.

We're getting closer.   Let's make it accessible:

<input type="radio" name="recipe[country_id]" value="#{this.id}" checked="&saved_this==this" id="recipe-country-#{this.id} /><label for="recipe-country-#{this.id}"><view/></input>

Pretty sweet. But for a general tag, we need to remove our hardcoding to country. So that's do that before we try to make the tag.

<% saved_this = this %>
<repeat with="&Country.all">
<input type="radio" name="recipe[country_id]" value="#{this.id}" checked="&saved_this==this"/><view/><br/>
</repeat>

Our first try might start something like this:

<repeat with="&this.class.all">...

But that will fail miserably when this is null. At this stage, we'll dive into the source code for select-one to see what it does:

conditions = ActiveRecord::Associations::BelongsToAssociation.new(this_parent, this_field_reflection).conditions options = this_field_reflection.klass.all(:conditions => conditions, :limit => limit).select {|x| can_view?(x)}

The other place that has country hardcoded is the name="recipe[country_id]"

Normally, we'd just use the `param_name_for_this` function, but that will return "recipe[country]". And we don't want to change our context from country to country_id because then the snippet we stole from select-one won't work.

So we take a look into the Hobo source code to find the definition for param_name_for_this to see how it's generated and see that this scenario has already been accounted for in its first parameter. Sweet. Putting it together:

<% saved_this = this
   limit = 100
conditions = ActiveRecord::Associations::BelongsToAssociation.new(this_parent, this_field_reflection).conditions options = this_field_reflection.klass.all(:conditions => conditions, :limit => limit).select {|x| can_view?(x)} %>
<repeat with="&options">
<input type="radio" name="&param_name_for_this(true)" value="&this.id" checked="&saved_this==this"/><view/><br/>
</repeat>

Now that's something we can make a tag out of:

<!-- radio for a belongs_to -->
<def tag="radio-one" attrs="options,limit">
<% saved_this = this
conditions = ActiveRecord::Associations::BelongsToAssociation.new(this_parent, this_field_reflection).conditions if options.nil? options ||= this_field_reflection.klass.all(:conditions => conditions, :limit => limit).select {|x| can_view?(x)} %>
  <repeat with="&options">
<input type="radio" name="&param_name_for_this(true)" value="&this.id" checked="&saved_this==this"/><view/><br/>
  </repeat>
</def>

Hopefully this lengthy post fulfills two long outstanding frequently asked requests: radios and progressive enhancement.

Of course, I typed all of this in without running any of the code, so there are bound to be typos. Does somebody have time to double check everything, edit and clean it up so it can be a recipe on the cookbook or even better a chapter in the book?

Bryan


On 11-03-29 12:41 PM, simple_n00b wrote:
My example is an attempt to change selects to radio buttons in "the
rapid rails 3 with hobo" draft.
This would go on the recipes form (child) to select the country
(parent).

The models are
recipe:

  fields do
     title   :string
     body    :text
     timestamps
   end

belongs_to :country
validates_presence_of :country

country:

  fields do
     name :string
     timestamps
   end

has_many :recipes
children :recipes

thanks for your help

On Mar 29, 11:58 am, Bryan Larsen<[email protected]>  wrote:
You probably want

<%= radio_button("country", "name", "american") %>
<%= radio_button("country", "name", "chinese") %>

assuming you are on a form for="Country".   If it's actually a form for
a different model where you want to select something on a child model,
post your model and we'll give you a hand.

Bryan

On 11-03-29 09:17 AM, simple_n00b wrote:

Thanks bryan,
I have been able to get the radio buttons to appear on the page, but
when using them to make a selection, it doesnt seem to save to the
database.
I was trying to modify<select-one>    in
libraries>Ruby 1.9.2-
p0>hobo-1.3.0.pre26>lib>hobo>rapid>taglibs>rapid_forms.dryml

to use
<%= radio_button("countries", "name", "american") %>
<%= radio_button("countries", "name", "chinese") %>

What would you recommend as the best place to start in the hobo
documentation with regard to implementing non-default form elements,
like radio for single select, checkboxes for multiple select, etc...?

On Mar 28, 11:04 am, Bryan Larsen<[email protected]>    wrote:
How's your html-fu?   You can write pure HTML radio buttons and drop
them into the middle of your DRYML.   If you need to parameterize it a
little bit, just use a minimal amount of ERB rather than writing a DRYML
tag.  Knowing HTML&    ERB is essential for hobo-fu, so it won't be wasted
effort.

Once you've got it working the "pure Rails" way, we can certainly help
you turn it into a DRYML tag that everybody can use.   We can help you
you get to that stage too, but small steps are the best way to learn
something.

Bryan

On 11-03-28 09:52 AM, simple_n00b wrote:

Thanks Mark, That is currently beyond the scope of my hobo-fu.
Is there a reference somewhere that would show me how to create a new
tag, and where to find the method that a tag uses to generate the
html, etc?

On Mar 28, 8:18 am, Mark Sobkowicz<[email protected]>      wrote:
The code for<select-one>      is in the gem, and also in the manual

http://cookbook.hobocentral.net/api_tag_defs/select-one

You could modify this and make your own<select-one-with-buttons>      tag.

On Mar 28, 2011, at 7:11 AM, Piotroslav wrote:

There is no radio buttons in hobo out of the box.
I was advised to create them myself.- Hide quoted text -

- Show quoted text -




--
You received this message because you are subscribed to the Google Groups "Hobo 
Users" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/hobousers?hl=en.

Reply via email to