I wrote everything out as I did it in tutorial form. This works with
the application as it is at the end of tutorial seven, and goes until
the last part which I haven't been able to get working yet. Hopefully
it will help others.
----------------

In Views > taglibs > application.dryml
Add:

<extend tag="form" for ="Recipe">
   <old-form merge>
      <field-list: fields="title,body,country">
        <country-view:>
          test
        </country-view:>
      </field-list:>
  </old-form>
</extend>

In the browser, make sure you are logged in as administrator, and go
to: http://localhost:3000/recipes/new and see the word “test”
appearing next to the “Country” Label. Then navigate to the edit page
of a particular recipe, for example:http://localhost:3000/recipes/1-
barbequed-chicken-wings/edit and see the same ”test” text.

Going back to Views > taglibs > application.dryml replace the word
“test” with the following:

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

To see it on the edit page, return there:
http://localhost:3000/recipes/1-barbequed-chicken-wings/edit and
select a country.

Then go back to the recipes show page: 
http://localhost:3000/recipes/1-barbequed-chicken-wings

If the result is not what you selected, it is because you do not have
that country name associated with that country_id. This will have been
based on the order in which you added the countries. You should be
able to correct it by shuffling around the values in your radio button
code.

A quick way to find what your country_id values should be is to view
your database. For a SQLite db, it can be done with the firefox
extension “SQLite manager”. With this installed and open, navigate to
one_table\db and open development.sqlite3. View the countries table,
and note which id is next to which name. These are the values to be
used in the radio buttons.
So this will work for this hardcoded example, but ultimately we want
the correct values to automatically be populated dynamically.

Lets start by having it find the right id number given the name:
<input type="radio" name="recipe[country_id]"
value="#{Country.find_by_name('American').id}" checked />American<br/>
<input type="radio" name="recipe[country_id]"
value="#{Country.find_by_name('Chinese').id}" />Chinese<br/>
<input type="radio" name="recipe[country_id]"
value="#{Country.find_by_name('French').id}" />French

Next we want to eliminate the hardcoded check for “American” and
instead have our current value display as checked.

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

(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.

Next, lets remove the need to manually add the country names and
correct number of radio buttons, and instead have them populate from
the database.

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


On Mar 30, 12:24 pm, simple_n00b <[email protected]> wrote:
> Hi Bryan, I tried this and got everything to work until the last
> example. I put it in application.dryml like so:
>
> <!-- 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>
>
> <extend tag="form" for ="Recipe">
>    <old-form merge>
>       <field-list: fields="title,body,country">
>         <country-view:>
> <radio-one/>
>         </country-view:>
>       </field-list:>
>   </old-form>
> </extend>
>
> and got an error:
> DRYML cannot provide the correct form-field name here...
>
> On Mar 30, 9:38 am, Bryan Larsen <[email protected]> wrote:
>
> > Both your suggestions will work, it's just that application.dryml is one
> > place, and new/edit.dryml are two places.
>
> > If you put it in application.dryml, the form definition would look
> > something like:
>
> > <extend tag="form" for ="Recipe">
> >    <old-form merge>
> >       <field-list: fields="title,body,country">
> >         <country-view:>
>
> > ...
>
> >         </country-view:>
> >       </field-list:>
> >   </old-form>
> > </extend>
>
> > On 11-03-30 09:15 AM, simple_n00b wrote:
>
> > > Hi Bryan, thank you for the in depth reply.
> > > I plan to try all of this code out, and will debug appropriately and
> > > post the working results, if no one else beats me to it.
> > > The only thing that is a little bit difficult for me to figure out is
> > > what file each of these snippets should go in with regard to the
> > > standard hobo structure. I will probably be working with the project
> > > as it looks at the end of tutorial 7.
>
> > > should all of this go in application.dryml, or views>  recipes>
> > > new.dryml / edit.dryml?
>
> > > should I be following the instructions in "Tutorial 15 - New and Edit
> > > Pages with The Form Tag"
> > > and start with:
>
> > > <extend tag="form" for ="Recipe">
> > > <old-form merge/>
> > > </extend>
>
> > > Again thanks for your help.
> > > I would love to see all form elements be made easy to implement in
> > > hobo, and will gladly contribute my own time and limited knowledge to
> > > finding a solution.
>
> > > On Mar 29, 2:23 pm, Bryan Larsen<[email protected]>  wrote:
> > >> 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:
>
> > >>>  
>
> ...
>
> read more »

-- 
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