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="¶m_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="¶m_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.
