How can I do a helper inside other helper? - ruby-on-rails

I want make a helper how in this example
def textForm()
'<div class="form-group">
<%= f.label :nombre, :class => "col-md-3 control-label" %>
<div class="col-md-9">
<%= f.text_field :nombre, :class=> "form-control"%>
</div>
</div>'.html_safe
end
but... when I call this helper with <%= textForm %> just print html syntax.
apparently I need make something as "pre-render". Do you have any ideas?

Partial
As mentioned in the comments, you'll be better using a partial to sort this out:
#app/views/controller/_your_partial.html.erb
<div class="form-group">
<%= f.label :nombre, :class => "col-md-3 control-label" %>
<div class="col-md-9">
<%= f.text_field :nombre, :class=> "form-control"%>
</div>
</div>
This will allow you to call the partial as follows:
<%= render partial: "controller/your_partial" %>
--
Helper
If you want to call HTML directly from a helper, you should probably look at using the raw method:
<%= raw textForm %>
and then
#app/helpers/application_helper.rb
def textForm()
'<div class="form-group">
<%= f.label :nombre, :class => "col-md-3 control-label" %>
<div class="col-md-9">
<%= f.text_field :nombre, :class=> "form-control"%>
</div>
</div>'
end

Related

Rails Ransack gem slider

I want to be able to performa range search with ransack. I was hoping I could do this with a slider that has two thumbs. I'm thinking that the _in predicate would be perfect for a situation like this. However, I cannot find an example on how to appropriately configure this. Here would be some example code:
CONTROLLER `users_controller.rb:
def index
#page_title = 'Users'
#page_icon = 'store'
#q = User.search(params[:search]).ransack(params[:q])
#retailers = #q.result.order("#{sort_column} #{sort_direction}").paginate(page: params[:page], per_page: 20)
end
VIEW users/index.html.erb:
<%= search_form_for #q, url: users_path, class: 'form' do |f| %>
<div class="row">
<div class="col-sm-3">
<div class="form-group">
<%= label_tag :search %>
<%= text_field_tag :search, params[:search], class: "form-control" %>
</div>
</div>
<div class="col-sm-3">
<div class="form-group">
<%= f.label :first_name_eq, "First Name" %>
<%= f.select :first_name_eq, {include_blank: true}, {class: "chosen-select"} %>
</div>
</div>
<div class="col-sm-3">
<div class="form-group">
<%= f.label :team_eq, "Team" %>
<%= f.select :team_eq, Team.options_for_select, {include_blank: true}, {class: "chosen-select"} %>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-3">
<div class="form-group">
<%= f.label :score_in, "Score Range" %>
<%= f.search_field :score_in, {include_blank: true} %>
</div>
</div>
</div>
<div>
<%= f.submit 'Apply Filters', class: 'btn btn-outline-dark btn-md' %>
<%= link_to 'Reset Filters', users_path(q: {reset: true}), class: 'btn btn-outline-danger btn-md' %>
</div>
<% end %>
I guess where I'm lost is how to start or implement a slider w/ two thumbs that would appropriately pass the parameters when submitted. Or even if I just create a two thumbed slider from a js library, how to connect it then to ransack, or at least pass the values of the two thumbs to ransacks params. Another thing that might be helpful is if someone has an example, both in controller/view, of what the _in predicate should look like.

I can't figure out why I'm getting this error in rails app: First argument in form cannot contain nil or be empty error

Ok I've been trying to figure this out for awhile... I wan´t to render a partial in the views/users/show.html.erb
This is the form code in the partial that I want rendered
<%= form_for #addon, :html => {:class => "form-horizontal center"} do |f| %>
<div class="form-group">
<%= f.label :addon_1, "1.Addon:", class: "col-md-4 control-label" %>
<div class="col-md-8">
<%= f.text_field :addon_1, class: "form-control" %>
</div>
</div>
<div class="form-group">
<%= f.label :addon_2, "2.Addon:", class: "col-md-4 control-label" %>
<div class="col-md-8">
<%= f.text_field :addon_2, class: "form-control" %>
</div>
</div>
<div class="form-group">
<%= f.label :addon_3, "3.Addon:", class: "col-md-4 control-label" %>
<div class="col-md-8">
<%= f.text_field :addon_3, class: "form-control" %>
</div>
</div>
<%= f.submit "Submit", class: "btn btn-default btn-primary" %>
I have an addon.rb model and user.rbmodel
this is the addon.rb model
class Addon < ActiveRecord::Base
belongs_to :user
end
And this is the user.rbmodel
class User < ActiveRecord::Base
has_many :addons
end
And in the users_controller.rb I have, this in the showaction
def show
##addon = current_user.addons.build
#addons = current_user.addons
end
I've tried to both use #addons and #addon it both gives errors.
If I use #addons rails gives back this error First argument in form cannot contain nil or be empty
and if I try to use #addon rails gives back this error :unknown attribute 'user_id' for Addon
Am I missing something here, I can't see why this shouldn't work, can anyone please advise.
I think you are not logged in, so there is no current_user & #addon.

My rendered partial '_form' appears, but is not submitting

Ruby 2.1.5 on Rails 4.2.0:
I have two directories. One directory is a rails-generate scaffold named 'inqueries'. The other directory is named 'welcome', which only houses a landing paged named index.html.erb. The inquery form works & submits fine as long as I'm using the view from the actual 'inquery' scaffold/directory.
I am able to render the inquery _form on my index.html.erb landing page using :
<%= render partial: "inqueries/form", locals: {inquery: #Inquery} %>
However, this JUST renders the form. When I hit the submit button, no errors, flash messages, or inquery is submitted. It is complete non-action, including on my rails terminal.
How can I properly make the form work on my landing page?
Here is my welcome_controller.rb file. This controller handles the landing page where I am trying to render the inquery scaffold's form:
class WelcomeController < ApplicationController
def index
#inquery = Inquery.new
render layout: false
end
end
This is my new rails scaffold-generated method in the inqueries_controller.rb:
def new
#inquery = Inquery.new
respond_with(#inquery)
end
Sorry, Here is the Inquery _form itself:
<%= form_for(#inquery) do |f| %>
<div class="form-group col-lg-4">
<%= f.label t('.name') %><br>
<%= f.text_field :name, class: "form-control" %>
</div>
<div class="form-group col-lg-4">
<%= f.label t('.email') %><br>
<%= f.text_field :email, class: "form-control" %>
</div>
<div class="form-group col-lg-4">
<%= f.label t('.phone') %><br>
<%= f.text_field :phone, class: "form-control" %>
</div>
<div class="clearfix"></div>
<div class="form-group col-lg-12">
<%= f.label t('.message') %><br>
<%= f.text_area :message, rows: 8, class: "form-control"%>
</div>
<%= f.submit t('.submit'), class: "btn btn-primary" %>
<% end %>
EDIT 2: I saw there were a couple of suggestions with the logic. I have simplified the partial just to see if I could get it to work and it still does not submit properly outside of its directory. I am new to rails, do I need to render a new action in the second directory that I am calling it into?
Your partial has 2 forms. The one which submits to inqueries#create is an empty form with no submit button, the other which has no action contains the text fields and the submit action.
The form_for tag will create the html tags, you dont need to specify them again.
Tip - Switch to haml. You won't ever look back at erb :)
This should work (not tested) -
<%= form_for(#inquery) do |f| %>
<div id="error_explanation">
<% if #inquery.errors.any? %>
<h2>
<%= pluralize(#inquery.errors.count, "error") %> prohibited this inquery from being saved:
</h2>
<ul>
<% #inquery.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
<% end %>
</div>
<br />
<div class="col-lg-12">
<div class="form-group col-lg-4">
<%= f.label t('.name') %><br>
<%= f.text_field :name, class: "form-control" %>
</div>
<div class="form-group col-lg-4">
<%= f.label t('.email') %><br>
<%= f.text_field :email, class: "form-control" %>
</div>
<div class="form-group col-lg-4">
<%= f.label t('.phone') %><br>
<%= f.text_field :phone, class: "form-control" %>
</div>
<div class="clearfix"></div>
<div class="form-group col-lg-12">
<%= f.label t('.message') %><br>
<%= f.text_area :message, rows: 8, class: "form-control"%>
</div>
<div class="form-group col-lg-12">
<input type="hidden" name="save" value="contact">
<%= f.submit t('.submit'), class: "btn btn-primary" %>
</div>
</div>
<% end %>
Figured it out. Foolish error,
My welcome page is a bootstrap theme that I hadn't fully gone over. I had imported some unnecessary javascript files that I think were blocking the form.

Rails - prepopulate textarea with existing attribute

I have following situation:
I've got two models
a Risk model with the attributes name, risk_class_id, description, level
a Risk_Class model with the attributs name and description
A Risk has one Risk Class and a Risk Class has many Risks. This association works fine. I can assign a Risk Class to a Risk. To create a Risk I use the following form:
<%= form_for #risk, :html => { :class => 'form-horizontal' } do |f| %>
<div class="control-group">
<%= f.label :name, :class => 'control-label' %>
<div class="controls">
<%= f.text_area :name, :class => 'text_area' %>
</div>
</div>
<div class="control-group">
<%= f.label :risk_class_id, :class => 'control-label' %>
<div class="controls">
<%= collection_select( :risk, :risk_class_id, RiskClass.all, :id, :name, :prompt => true ) %>
</div>
</div>
<div class="control-group">
<%= f.label :description, :class => 'control-label' %>
<div class="controls">
<%= f.text_area :description, :class => 'text_area' %>
</div>
</div>
<div class="control-group">
<%= f.label :level, :class => 'control-label' %>
<div class="controls">
<%= f.text_area :level, :class => 'text_area' %>
</div>
</div>
<div class="form-actions">
<%= f.submit nil, :class => 'btn btn-primary' %>
</div>
<% end %>
Now i would like to have that the textarea field for the description gets prepopulated based on the selected risk class, as a risk class has a description.
Thankful for any help!
EDIT
I've added following javascript code to the form and edited the collection select the following way:
<%= javascript_tag do %>
function risk_class_selection(riskclassId){
window.alert(riskclassId);
}
<% end %>
<div class="control-group">
<%= f.label :risk_class_id, :class => 'control-label' %>
<div class="controls">
<%= collection_select( :risk, :risk_class_id, RiskClass.all, :id, :name, {:prompt => true} , {:onchange => "risk_class_selection(this.value)"}) %>
</div>
</div>
SOLUTION:
in case anyone is interested i followed the way grotori described and my solution looks now like this:
I've got this risk.js file:
function risk_class_selection(riskclassId){
if (riskclassId != ""){
$.getJSON("/risk_classes/"+riskclassId+".json", function(data){
if ( $('#risk_description').val() == "" ){
$("#risk_description").val(data.description);
}
else{
if ( confirm('Are you sure you want to change the risk description?') ){
$("#risk_description").val(data.description);
}
else{
}
}
}
)
}
else{}
}
And in the Risk Form i've got the first div with the onchange event and the second where the textarea should be prepopulated:
<div class="control-group">
<%= f.label :risk_class_id, :class => 'control-label' %>
<div class="controls">
<%= collection_select( :risk, :risk_class_id, RiskClass.all, :id, :name, {:prompt => true} , {:onchange => "risk_class_selection(this.value)"}) %>
</div>
</div>
<div class="control-group">
<%= f.label :description, :class => 'control-label' %>
<div class="controls">
<%= f.text_area :description, :class => 'text_area' %>
</div>
</div>
You must bind an onchange event to your select field that will post back to your server the user's selection and respond with javascript that will re-render the textarea with the desired value you want.
You can do it in controller when preparing the object #risk. Something like this:
#risk = Risk.new(description: "blah blah")
Then the form will have this value with form_for tag.

Adding Twitter bootstrap styling to Rails form helpers

After reading the answer which suggested I use Simple_form gem with bootstrap integration, I installed it and created my form according to simple_form instructions, but the input boxes are floating right.
This is the layout. The form is being called with the partial 'shared/reg'
<div class="container">
<div class="row">
<div class="span8"><%= yield %></div>
<div class="span4">
<%= render 'shared/reg' %>
</div>
</div>
</div>
This is my simple form form
<%= simple_form_for("user", :url => main_app.user_registration_path, :html => { :class => "form-horizontal" } ) do |f| %>
<%= f.input :name %>
<%= f.input :vote, :collection => [ "For", "Against", "Undecided"] %>
<%= f.input :country, :collection => [ "Canada", "Iceland", "Other"] %>
<%= f.input :email %>
<%= f.input :image, :as => :file %>
<%= f.input :password %>
<%= f.input :password_confirmation %>
<%= f.button :submit %>
<% end %>
Below you can see how the input boxes are floating right in relation to the submit button.
Update
Rather than using the .form-actions class, which wraps the submit button in gray block (which might not work for your page design), you can also wrap the button in a control group like this:
<div class="control-group">
<div class="controls">
<%= f.button :submit %>
</div>
</div>
This is only really needed if you're using the .form-horizontal class on the form itself.
If you're looking for a drop-in replacement form builder that outputs bootstrap-style markup for Rails, you might want to check out a gem that I put together to handle this sort of thing:
https://github.com/potenza/bootstrap_form
Here's how you'd setup a horizontal-style form with the submit button properly lined up:
<%= bootstrap_form_for(#user, html: { class: 'form-horizontal' }) do |f| %>
<%= f.text_field :email %>
<%= f.password_field :password %>
<%= f.password_field :password_confirmation, label: 'Confirm Password' %>
<%= f.control_group do %>
<%= f.primary "Save User" %>
<% end %>
<% end %>
This is the example output:
<form accept-charset="UTF-8" action="/users" class="form-horizontal" id="new_user" method="post">
<div class="control-group">
<label class="control-label" for="user_email">Email</label>
<div class="controls">
<input id="user_email" name="user[email]" size="30" type="text" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="user_password">Password</label>
<div class="controls">
<input id="user_password" name="user[password]" size="30" type="password" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="user_password_confirmation">Confirm Password</label>
<div class="controls">
<input id="user_password_confirmation" name="user[password_confirmation]" size="30" type="password" />
</div>
</div>
<div class="control-group">
<div class="controls">
<input class="btn btn-primary" name="commit" type="submit" value="Save User" />
</div>
</div>
</form>
You should try the following:
<%= form_for("user", :url => main_app.user_registration_path, :html => { :class => "form-horizontal" } ) do |f| %>
<fieldset>
<legend>User Registration</legend>
<div class="control-group">
<%= f.label :name, class: "control-label" %>
<div class="controls">
<%= f.text_field :name %></p>
</div>
</div>
<div class="form-actions">
<%= f.submit %>
</div>
</fieldset>
Note that the bootstrap uses some specific selectors for some classes / html elements, so that if you forget to add an element or a class, everything else will be messed up... In this aspect there's no leeway.
On a side note, you should definitely try simple_form, and the bootstrap integration. It will make your life easier.
Update:
<%= simple_form_for("user", :url => main_app.user_registration_path, :html => { :class => "form-horizontal" } ) do |f| %>
<fieldset>
<legend>User Registration</legend>
<%= f.input :name %>
<%= f.input :vote, :collection => [ "For", "Against", "Undecided"] %>
<%= f.input :country, :collection => [ "Canada", "Iceland", "Other"] %>
<%= f.input :email %>
<%= f.input :image, :as => :file %>
<%= f.input :password %>
<%= f.input :password_confirmation %>
<div class="form-actions">
<%= f.submit %>
</div>
</fieldset>
<% end %>

Resources