Auto complete field on simple form with params - ruby-on-rails

I have two models 'activity_templates' and 'activity'. I want to create a link on the activity_template index to create a new activity. I want to send activity_template params to the active form. I want to autocomplete the activity_template field on new activity form.
I can't figure out how to pass the params on the index page.
I think its a problem with the link.
Link:
<div class="box">
<div class="box-header">
<h3 class="box-title">Activities</h3>
</div>
<div class="box-body table-responsive no-padding">
<table class="table table-bordered">
<tbody>
<% #activity_templates.each do |activity_template| %>
<tr>
<td><%= activity_template.name %></td>
</tr>
<% end %>
</tbody>
</table>
<div class="text-right">
<%= will_paginate #activity_templates %>
</div>
</div>
</div>
URL:
http://localhost:3000/app/activities/new
Form:
<%= simple_form_for([:app, #activity]) do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<div class="row">
<div class="col-md-6">
<%= f.association :resident, label_method: :full_name, prompt: "Choose a resident", collection: Resident.order(:first_name), selected: #resident.id %>
</div>
<div class="col-md-6">
<%= f.association :activity_template, collection: ActivityTemplate.order(:name).pluck(:name, :id), prompt: "Choose an activity template", selected: #activity_template.id %>
</div>
<div class="col-md-6">
<%= f.input :published_status, collection: ['Draft', 'Final'], default: 'Draft' %>
</div>
<div class="col-md-6">
<div class="form-group">
<label>Author</label>
<input class="form-control" type="text" placeholder="<%= #current_user.full_name %>" readonly value="<%= #activity.author.try(:full_name) %>">
</div>
</div>
</div>
<%= f.input :data %>
</div>
<div class="form-actions">
<%= f.button :submit %>
</div>
<% end %>
Activity controller:
def new
#activity = current_business.activities.new
if params[:resident_id].present?
#resident = Resident.find(params[:resident_id])
end
if params[:activity_template_id].present?
#activity_template = ActivityTemplate.find(params[:activity_template_id])
end
end

I want to send activity_template params to the active form.
You should change #activity_template to activity_template in the link as you are iterating #activity_templates as activity_template.
<td><%= activity_template.name %></td>
Now you should see activity_template_id value in the url
http://localhost:3000/app/activities/new?activity_template_id=value
As you already capturing the params[activity_template_id] in the new, the rest should work now.
Also I recommend using link_to
<%= link_to activity_template.name, new_app_activity_path(activity_template_id: activity_template) %>

Related

Nil:nil class error on each loop when Form to build object loaded on page first

I have a form on a page that is building a “tip” for a “guide”. Below the form, I am running an each loop over all the #guide.tips. I keep getting an error as the each loop is loading the forms blank object as it sees it as a tip. I’ve currently solved the problem by using jQuery to inject the form after page load, but there has to be a better solution.
Each Loop on Guide.html.erb
<% if !#guide.tips.blank? %>
<% #guide.tips.each do |tip| %>
<div class="row mx-1">
<div class="col-md-3 border-right">
<div class="float-left">
<%= image_tag avatar_url(tip.user), class: "float-left text-left align-middle rounded img-fluid mx-3", width: "30%" %>
<p><%= tip.user.fullname %></p>
</div>
<div class="float-right mr-3">
<%= link_to like_tip_path(tip), method: :put do %>
<div class="fas fa-angle-up"></div>
<%= tip.get_upvotes.size %>
<% end %><br/>
<%= link_to dislike_tip_path(tip), method: :put do %>
<div class="fas fa-angle-down"></div>
<%= tip.get_downvotes.size %>
<% end %>
</div>
</div>
<div class="col-md-8 ml-3">
<h6><%= tip.title %> -<span class="ml-1"><small><%= tip.created_at.strftime("%A, %d %b %Y %l:%M %p")%></small></span></h6>
<%= tip.tip %>
</div>
</div><hr/>
<% end %>
<% end %>
Tips_Controller.rb
def new
#guide = Guide.find(params[:guide_id])
#tip = Tip.new
end
def edit
end
def create
#guide = Guide.find(params[:guide_id])
params[:tip][:user_id] = current_user.id
#tip = #guide.tips.create!(tip_params)
redirect_to guide_path(#guide)
end
Tip Form Partial
<%= form_for([#guide, #guide.tips.build]) do |f| %>
<div class="form-group row">
<div class="col-sm-12">
<p class="text-left">Tip Title</p>
<%= f.text_field :title, placeholder: "Enter Title", class: "form-control" %>
</div>
<div class="col-sm-12 mt-2">
<p class="text-left">Your Tip</p>
<%= f.text_area :tip, placeholder:"What's your tip for this travel guide?", class: 'form-control' %>
</div>
</div>
<div class="form-group row">
<div class="col-md">
<%= f.submit 'Submit', class: 'btn btn-primary btn-block' %>
</div>
</div>
<% end %>
Here is another solution that does not separate the logic between the controller and the view and cleans up your empty array statement for your loop
Each Loop on Guide.html.erb
<% #guide.tips.each do |tip| %>
<div class="row mx-1">
<div class="col-md-3 border-right">
<div class="float-left">
<%= image_tag avatar_url(tip.user), class: "float-left text-left align-middle rounded img-fluid mx-3", width: "30%" %>
<p><%= tip.user.fullname %></p>
</div>
<div class="float-right mr-3">
<%= link_to like_tip_path(tip), method: :put do %>
<div class="fas fa-angle-up"></div>
<%= tip.get_upvotes.size %>
<% end %><br/>
<%= link_to dislike_tip_path(tip), method: :put do %>
<div class="fas fa-angle-down"></div>
<%= tip.get_downvotes.size %>
<% end %>
</div>
</div>
<div class="col-md-8 ml-3">
<h6><%= tip.title %> -<span class="ml-1"><small><%= tip.created_at.strftime("%A, %d %b %Y %l:%M %p")%></small></span></h6>
<%= tip.tip %>
</div>
</div><hr/>
<% end unless #guide.tips.blank? %>
Tip Form Partial
By creating the Tip from outside the association (i.e. not using build), it will not be loaded into the class variable's children
<%= form_for([#guide, Tip.new(guide: #guide)]) do |f| %>
<div class="form-group row">
<div class="col-sm-12">
<p class="text-left">Tip Title</p>
<%= f.text_field :title, placeholder: "Enter Title", class: "form-control" %>
</div>
<div class="col-sm-12 mt-2">
<p class="text-left">Your Tip</p>
<%= f.text_area :tip, placeholder:"What's your tip for this travel guide?", class: 'form-control' %>
</div>
</div>
<div class="form-group row">
<div class="col-md">
<%= f.submit 'Submit', class: 'btn btn-primary btn-block' %>
</div>
</div>
<% end %>
Another Example / Q&A
Using the structure you already have you could do:
<% if #guide.tips.count > 1 %> (assuming this will always be shown with an empty "build" tip)
or you can use:
<% next unless tip.persisted? %>
inside the loop, before the actual form.
You also don't need the blank? check as an .each on an empty enumerator simply won't execute the block, and as long as there's a has_many relationship between guide and tips it will always yield a collection proxy.
I would write it as:
<% #guide.tips.each do |tip| %>
<% next unless tip.persisted? %>
<div class="row mx-1">
<div class="col-md-3 border-right">
...
<% end %>

Submitting two forms in Rails sharing a same param

I have a form like that:
<%= form_for #report do |f| %>
<div class="row">
<div class="col-sm-9">
<h3 class="page-header">
Children
</h3>
<div class="row">
<% students.each do |student| %>
<div class="col-xs-4 col-md-2">
<div class="std_container">
<%= check_box_tag "student_ids[]", student.id, nil, {id: "check_#{student.id}", class: "student_check"} %>
<%= label_tag "check_#{student.id}" do %>
<div class="std_label"><%= student.name %></div>
<div class="std_img thumbnail"><img src="http://www.codeproject.com/KB/GDI-plus/ImageProcessing2/img.jpg" alt=""></div>
<% end %>
</div>
</div>
<% end %>
</div>
</div>
<%= render "form_categories", f: f, report_notes: #report.report_notes %>
<%= render "messages/form", ????? %>
</div>
</div>
</div>
<% end %>
And I need to render these two partials on the bottom. The 'messages' partial is a form that responds to a different controller but needs to use the "student_ids[]" parameter present on the #report form together with its own parameters. This partial is:
<%= form_for #message do |f| %>
<div class="row">
<div class="col-sm-10 col-sm-offset-1">
<%= f.hidden_field :professor_id, :value => current_user.professor.id %>
<%= f.label :text, "Texto" %>
<%= f.text_area :text %>
<%= f.submit "Enviar", class: "btn btn-default" %>
</div>
</div>
<% end %>
How do build this "messages" partial in a way that I can use the "student_ids[]" and submit it to its controller?
It is not possible. I solved this problem by using javascript.

How to pass parameters in controller in Ruby On Rails

I am trying to pass parameters in controller but it is not returning anything.Please help me how I can pass parameters .
Controller Code -
def print_salary_slip_monthwise
#month = params[:salary][:month]
#year = params[:salary][:year]
#company = params[:salary][:company_id]
#company_location = params[:salary][:company_location_id]
#department = params[:salary][:department_id]
#salaryslips = Salaryslip.where(month: #month,year: #year.to_s,employee_id: #salary1)
end
form.html.erb - This is my form in which I used on change event .
<div class="box">
<div class="box-header">
<h3 class="box-title">Salary Slip Department Wise</h3>
</div><!-- /.box-header -->
<div class="box-body">
<%= bootstrap_form_for(:pdf_salaries, url: { action: 'print_salary_slip_monthwise'},html: {id: 'pdf_salaries'},remote: true ) do |f| %>
<div class="row">
<div class="col-sm-2">
<label>Year</label>
<div class="field">
<%= select :salary,:year,['2015','2016','2017','2018','2019','2020','2021','2022','2023','2024','2025','2026','2027'],{label: 'Select Year',include_blank: " Select Year"},{class: 'form-control'} %>
</div>
</div>
<div class="col-sm-2">
<label>Month</label>
<div class="field">
<%= select :salary,:month, ['January','February','March','April','May','June','July','August','September','October','November','December'],{label: 'Select Month',include_blank: " Select Month"}, class: "form-control" %>
</div>
</div>
<div class="col-sm-2">
<div class="form-group required">
<div class="input-group">
<%= f.select :company_id, all_company,{include_blank: "Select Company"},{onchange:"var a={id:$(this).val(), form : 'employee'}; $.get('/employees/collect_company_location',a,function(response){});"}%>
</div>
</div>
</div>
<div class="col-sm-2">
<div class="form-group required">
<div id="company_location">
<%= render 'employees/company_location_dropdown' %>
</div>
</div>
</div>
<div class="col-sm-3">
<div class="form-group required">
<div class="input-group">
<div id="department">
<%= render 'employees/department_dropdown' %>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-2">
<div class="actions">
<%= f.submit "Display Report", class: "btn btn-sm btn-primary",id: "buttonCtc" %>
</div>
</div>
</div>
<div class="ajax-progress"></div>
<div id="employee_list_pdf"></div>
</div>
</div>
<%end%>
You can pass parameters using form or using ajax. Once you pass a parameters to your server (controller) you can check it to your server log to see the parameters. In rails 4 you need to use Strong Parameters to save these parameters to your database.
Take this as an example of the Form will below field.
<%= simple_form_for #user do |f| %>
<%= f.input :username %>
<%= f.input :password %>
<%= f.button :submit %>
<% end %>
When above form will be submitted. you can see the rails server terminal for params
Parameters: {"user"=>{"username"=>"user1", "password"=>"password"}, "commit"=>"Submit"}
Access params in controller like this:
params[:user][:username] # code in controller
Hope this give you the clear understaning.

Routing problems with STI

I've declared an STI on Works
class Work < ActiveRecord::Base
validates :title, presence: true
validates :visibility, presence: true
belongs_to :category
end
class Story<Work
end
class Poem<Work
end
Code for form:
<div class="panel panel-blue margin-bottom-40">
<div class="panel-heading">
<h3 class="panel-title"><i class="icon-tasks"></i> Item Details</h3>
</div>
<div class="panel-body">
<%= form_for(#work, :html =>{:class =>"margin-bottom-40 new_item ",:multipart => true}) do |f| %>
<% if #work.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#work.errors.count, "error") %> found </h2>
<ul>
<% #work.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="form-group">
<%= f.label "Title",:class=>"control-label" %>
<div class="controls">
<%= f.text_field :title,:class=>"form-control",:placeholder=>"Title of the story/poem" %>
<div class="description">
<div class="">
<strong>Enter a suitable title for your story/poem
</strong>
</div>
</div>
</div>
</div>
<div class="form-group">
<%= f.label :type,:class=>"control-label" %>
<div class="controls">
<%= f.select :type,{"Story"=>"Story","Poem"=>"Poem"},{},:class=>"form-control",:placeholder=>"Story/Poem" %>
<div class="description">
<div class="">
<strong>Is it a story or a poem?
</strong>
</div>
</div>
</div>
</div>
<%
visibilities=["Me Only","Anyone with link","Logged In Users","Everyone"]
%>
<div class="form-group">
<%= f.label :visibility,:class=>"control-label" %>
<div class="controls">
<% [ 3,2, 1, 0 ].each do |option| %>
<br><%= radio_button_tag :visiblity, option, #visibility == option %>
<%= label_tag "visibility_#{option}", visibilities[option].humanize %>
<% end %>
<div class="description">
<div class="">
<strong>
</strong>
</div>
</div>
</div>
</div>
<div class="form-group">
<%= f.label :category_id,:class=>"control-label" %>
<div class="controls">
<%= f.collection_select :category_id,Category.all,:id,:name,{},:class=>"form-control" %>
<div class="description">
<div class="">
<strong>
Type your story/Poem here
</strong>
</div>
</div>
</div>
</div>
<div class="form-group">
<%= f.label :content,:class=>"control-label" %>
<div class="controls">
<%= f.text_area :content,:class=>"form-control" %>
<div class="description">
<div class="">
<strong>
</strong>
</div>
</div>
</div>
</div>
<div class="actions">
<%= f.submit :class=>"btn btn-primary" %>
<%= link_to 'Back', works_path,:class=>"btn" %>
</div>
<% end %>
I have scaffolding for work with the parameter Type which accepts Story and Poem. When I submitted the form initially, I would get a stories_path not found error so I mapped stories and poems paths as follows:
resources :stories, :controller => 'works'
resources :poems, :controller => 'works'
So when I submit the first time, the form shows validation errors. When I submit it again after correcting validation, I get an exception
ActionController::ParameterMissing in WorksController#create
in this line:
params.require(:work).permit(:title, :type, :visibility, :category_id, :content)
I assume this is because its now renaming all the fields to story[] instead of work[]
How do I fix this and in the greater picture, how do I make STI work on the same controller. I just want to be able to use Poem.all and Story.all for fetching records.
Submisson currently works through the same interface
I am allowing the user to select the type of work in the form.

Bootstrap collapse within table/between table rows not working

I have a question regarding the Bootstrap collapse feature. I'm pretty sure that I'm overlooking something quite obvious or easy to fix, but I googled it alot and played with the code, but without success.
I have a "account settings" page, where all account information of a user is shown in a table-like format, with the table cells of the last table column always containing an "edit"-button to edit that information. When people click "edit", an edit form shall expand just beneath that table row.
I followed the scheme at http://twitter.github.com/bootstrap/javascript.html#collapse , the collapse function itself works fine, but the problem is that each form always expands above my table, regardless of which edit button I click on. I made a screenshot of how it looks like. http://imageshack.us/photo/my-images/834/problemyn.png/ Instead of being above the whole table I want it to expand just beneath the specific row, pushing the lower rows down.
Here my code:
<table class="table">
<tbody>
<tr>
<td>Username</td>
<td><%= #user.name %></td>
<td><button class="btn btn-danger" data-toggle="collapse" data-target="#username">Edit</button></td>
</tr>
<div id="username" class="collapse">
<div class="row">
<div class="span6 offset3">
<%= form_for(#user) do |form| %>
<%= render 'shared/error_messages', object: form.object %>
<%= form.label :name, "Change Username" %>
<%= form.text_field :name %>
<%= form.submit "Save changes", class: "btn btn-primary" %>
<% end %>
</div>
</div>
</div>
<tr>
<td>Email</td>
<td><%= #user.email %></td>
<td><button class="btn btn-danger" data-toggle="collapse" data-target="#email">Edit</button></td>
</tr>
<div id="email" class="collapse">
<div class="row">
<div class="span6 offset3">
<%= form_for(#user) do |form| %>
<%= render 'shared/error_messages', object: form.object %>
<%= form.label :email, "Change Email" %>
<%= form.text_field :email %>
<%= form.submit "Save changes", class: "btn btn-primary" %>
<% end %>
</div>
</div>
</div>
<tr>
<td>Password</td>
<td>Last time updated: <%= #user.updated_at %></td>
<td><button class="btn btn-danger" data-toggle="collapse" data-target="#password">Edit</button></td>
</tr>
<div id="password" class="collapse">
<div class="row">
<div class="span6 offset3">
<%= form_for(#user) do |form| %>
<%= render 'shared/error_messages', object: form.object %>
<%= form.label :password, "Change Password" %>
<%= form.text_field :password %>
<%= form.label :password_confirmation, "Confirm Password" %>
<%= form.password_field :password_confirmation %>
<%= form.submit "Save changes", class: "btn btn-primary" %>
<% end %>
</div>
</div>
</div>
<tr>
<td>Language</td>
<td>English</td>
<td><button class="btn btn-danger" data-toggle="collapse" data-target="#language">Edit</button></td>
</tr>
<div id="language" class="collapse">
<div class="row">
<div class="span6 offset3">
<!-- code for language form -->
</div>
</div>
</div>
<tr>
<td>Avatar</td>
<td><%= avatar_status %></td>
<td><button class="btn btn-danger" data-toggle="collapse" data-target="#demo">Edit</button></td>
</tr>
<div id="demo" class="collapse">
<div class="row">
<div class="span6 offset3">
<%= form_for(#user) do |form| %>
<%= form.label :avatar %>
<%= form.file_field :avatar %>
<%= form.submit "Add avatar", class: "btn btn-primary" %>
<% end %>
</div>
</div>
</div>
</tbody>
</table>
To collapse a table row, you should write extra css for the collapsed row:
table .collapse.in {
display: table-row !important;
}
It will fix the display issue after the row expanded.
Hi I'm sorry I won't have a satisfying answer. It is not allowed to have anything other than <tr> elements as descendants of <tbody> so your HTML is not valid. This is what causes the glitchy behavior. Your best bet is to wrap every part of your form in a new table element.

Resources