I noticed a bug with my view where my form could not be submitted after the initial submission to generate a PDF, and during research saw that form_with was the recommended way to build forms going forward with rails. I updated my form, and everything seems to be working the way it's supposed to, but now the PDF doesn't download as before and just seems to render the string in a response without generating the file. Using Wicked-PDF and Rails 5.2.1. Sorry if I'm missing something super obvious!
Using form_tag (pdf downloads as expected):
form in view:
<%= form_tag("download_pdf", format: :pdf, method: "get") do %>
<div class="input-group mb-3">
<%= collection_select(:location, :id, Location.all, :id, :name, {:include_blank => 'Filter by location'}, {:id => 'qr_code_loc_select', :selected_value => '', :name => 'location', :style=> 'width: 17em', :autocomplete => 'off'}) %>
</div>
<div class="input-group mb-3">
<%= collection_select(:name, :id, DeviceType.all, :id, :name, {:include_blank => 'Filter by device type'}, {:id => 'qr_device_type_select', :selected_value => '', :name => "device_type", :style=> 'width: 17em', :autocomplete => 'off'}) %>
</div>
<div class="input-group mb-3">
<input type="number" name="width" class="form-control label_size_input" id="label_width" step="0.001" placeholder="Label Width" autocomplete ='off' aria-describedby="basic-addon3">
<div class="input-group-append">
<span class="input-group-text">inches</span>
</div>
</div>
<div class="input-group mb-3">
<input type="number" name="height" class="form-control label_size_input" id="label_height" step="0.001" placeholder="Label Height" autocomplete ='off' aria-describedby="basic-addon3">
<div class="input-group-append">
<span class="input-group-text">inches</span>
</div>
</div>
<%= label_tag "qr_col", "Columns:", class:"ml-2 text-light" %>
<div class="input-group mb-3">
<%= select_tag "qr_col", options_for_select(["1","2", "3", "4", "5"], "3"), {:autocomplete => 'off'}%>
</div>
<%= label_tag "paper_size", "Paper Size:", class:"ml-2 text-light" %>
<div class="input-group mb-3">
<%= select_tag "paper_size", options_for_select(#paper_size, "A4"), {:autocomplete => 'off'}%>
</div>
<div class="btn-group mb-3" role="group" aria-label="pdf_export_button" id="pdf_export">
<%= hidden_field_tag :column_number %>
<%= hidden_field_tag :label_size %>
<%= hidden_field_tag :format, "pdf" %>
<%= submit_tag("Create PDF Document", {:class=> "btn btn-secondary"}) %>
<% end %>
</div>
in controller:
def download_pdf
#columns = params[:column_number].to_i
#height = params[:height]
#width = params[:width]
#paper_size = params[:paper_size]
#type = params[:device_type]
#location = params[:location]
if #type.blank?
if #location.blank?
#devices = Device.all
else
#devices = get_devices_by_location(#location)
end
else
if #location.blank?
#devices = Device.where('device_type_id=?', #type)
else
#devices = get_devices_by_type_and_location(#type, #location)
end
end
pdf_string = render_to_string(
template: "qr_codes/show.html.erb",
layout: "layouts/pdf_layout.pdf.erb",
viewport_size: '1280x1024',
page_size: #paper_size
)
respond_to do |format|
format.pdf do
pdf = WickedPdf.new.pdf_from_string(pdf_string)
send_data pdf, :filename => "report.pdf", :type => "application/pdf"
end
end
end
in console:
Started GET "/qr_codes/download_pdf?utf8=%E2%9C%93&location=&device_type=&width=&height=&qr_col=3&paper_size=A4&column_number=3&label_size=&format=pdf&commit=Create+PDF+Document" for 127.0.0.1 at 2018-11-14 20:03:51 -0500
Processing by QrCodesController#download_pdf as PDF
Parameters: {"utf8"=>"✓", "location"=>"", "device_type"=>"", "width"=>"", "height"=>"", "qr_col"=>"3", "paper_size"=>"A4", "column_number"=>"3", "label_size"=>"", "commit"=>"Create PDF Document"}
Rendering qr_codes/show.html.erb within layouts/pdf_layout.pdf.erb
(0.4ms) SELECT COUNT(*) FROM "devices"
Device Load (0.6ms) SELECT "devices".* FROM "devices"
Rendered qr_codes/show.html.erb within layouts/pdf_layout.pdf.erb (778.0ms)
"***************[\"/Users/joe/.rbenv/versions/2.5.0/bin/wkhtmltopdf\", \"-q\", \"file:////var/folders/pf/kl12j8g91w5bj7ssc_0fdv3c0000gn/T/wicked_pdf20181114-912-1opkhpt.html\", \"/var/folders/pf/kl12j8g91w5bj7ssc_0fdv3c0000gn/T/wicked_pdf_generated_file20181114-912-m57i12.pdf\"]***************"
Rendering text template
Rendered text template (0.1ms)
Sent data report.pdf (1.7ms)
Completed 200 OK in 3077ms (Views: 1.2ms | ActiveRecord: 1.0ms)
Using form_with (pdf does not generate as expected and only has an unformatted string in response):
form in view:
<%= form_with url: download_pdf_path(format: :pdf), method: "get" do |f| %>
<div class="input-group mb-3">
<%= f.collection_select(:id, Location.all, :id, :name, {:include_blank => 'Filter by location'}, {:id => 'qr_code_loc_select', :selected_value => '', :name => 'location', :style=> 'width: 17em', :autocomplete => 'off'}) %>
</div>
<div class="input-group mb-3">
<%= f.collection_select(:id, DeviceType.all, :id, :name, {:include_blank => 'Filter by device type'}, {:id => 'qr_device_type_select', :selected_value => '', :name => "device_type", :style=> 'width: 17em', :autocomplete => 'off'}) %>
</div>
<div class="input-group mb-3">
<%= f.number_field nil, {:name => "width", :id => "label_width", :class => "form-control label_size_input", :step => "0.001", :placeholder => "Label Width", :autocomplete => 'off'} %>
<div class="input-group-append">
<span class="input-group-text">inches</span>
</div>
</div>
<div class="input-group mb-3">
<%= f.number_field nil, {:name => "height", :id => "label_height", :class => "form-control label_size_input", :step => "0.001", :placeholder => "Label Height", :autocomplete => 'off'} %>
<div class="input-group-append">
<span class="input-group-text">inches</span>
</div>
</div>
<%= label_tag "qr_col", "Columns:", class:"ml-2 text-light" %>
<div class="input-group mb-3">
<%= f.select "column_number", options_for_select(["1","2", "3", "4", "5"], "3"), {:autocomplete => 'off'}, :id => "qr_col"%>
</div>
<%= label_tag "paper_size", "Paper Size:", class:"ml-2 text-light" %>
<div class="input-group mb-3">
<%= f.select "paper_size", options_for_select(#paper_size, "A4"), {:autocomplete => 'off'}%>
</div>
<div class="btn-group mb-3" role="group" aria-label="pdf_export_button" id="pdf_export">
<%= f.hidden_field :label_size %>
<%= f.submit("Create PDF Document", {:class=> "btn btn-secondary", :data => { turbolinks: false }}) %>
</div>
<% end %>
controller:
def download_pdf
#columns = params[:column_number].to_i
#height = params[:height]
#width = params[:width]
#paper_size = params[:paper_size]
#type = params[:device_type]
#location = params[:location]
if #type.blank?
if #location.blank?
#devices = Device.all
else
#devices = get_devices_by_location(#location)
end
else
if #location.blank?
#devices = Device.where('device_type_id=?', #type)
else
#devices = get_devices_by_type_and_location(#type, #location)
end
end
respond_to do |format|
format.pdf do
pdf = WickedPdf.new.pdf_from_string(
render_to_string(
template: 'qr_codes/show.html.erb',
layout: 'layouts/pdf_layout.pdf.erb',
page_size: #paper_size
),
)
send_data pdf, :filename =>'PDF Report-' + Time.now.strftime('%v %H:%M:%S').to_s, disposition: 'attachment', :type => "application/pdf"
end
end
end
in console:
Started GET "/qr_codes/download_pdf_path?utf8=%E2%9C%93&location=&device_type=&width=&height=&column_number=3&paper_size=A4&label_size=&format=pdf&commit=Create%20PDF%20Document" for 127.0.0.1 at 2018-11-14 20:01:04 -0500
Processing by QrCodesController#download_pdf as PDF
Parameters: {"utf8"=>"✓", "location"=>"", "device_type"=>"", "width"=>"", "height"=>"", "column_number"=>"3", "paper_size"=>"A4", "label_size"=>"", "commit"=>"Create PDF Document"}
Rendering qr_codes/show.html.erb within layouts/pdf_layout.pdf.erb
(0.3ms) SELECT COUNT(*) FROM "devices"
Device Load (1.2ms) SELECT "devices".* FROM "devices"
Rendered qr_codes/show.html.erb within layouts/pdf_layout.pdf.erb (453.5ms)
"***************[\"/Users/joe/.rbenv/versions/2.5.0/bin/wkhtmltopdf\", \"-q\", \"file:////var/folders/pf/kl12j8g91w5bj7ssc_0fdv3c0000gn/T/wicked_pdf20181114-912-1ym4a9q.html\", \"/var/folders/pf/kl12j8g91w5bj7ssc_0fdv3c0000gn/T/wicked_pdf_generated_file20181114-912-edkha0.pdf\"]***************"
Rendering text template
Rendered text template (0.1ms)
Sent data PDF Report-14-NOV-2018 20:01:07 (1.6ms)
Completed 200 OK in 2682ms (Views: 1.1ms | ActiveRecord: 1.5ms)
IT WAS SOMETHING DUMB--decided to turn my attention to the form_with documentation and found out that remote: true is set by default. If you set this to local: true, the issue is resolved. Hope that helps someone else!
I'm trying to use the input-append feature of Twitter Bootstrap. However, I want to try and keep my code cleaner with the simple_form.
<div class="control-group string required">
<label class="string required control-label" for="video_company_id"><abbr title="required">*</abbr> Company</label>
<div class="controls">
<div class="input-append">
<%= f.text_field :company_id, :class => "span2" %>
<span class="add-on"><%= link_to image_tag('/assets/button/magnifier.png'), "#select_company", :"data-toggle" => "modal" %></span>
</div>
</div>
</div>
yields
What is a better way to write this with simple_form using f.input?
Edit to mdepolli
Thanks mdepolli. That does get me closer to where I need to be. However, it just puts the lookup inline with the form instead of an 'add-on'.
<%= f.input :company_id, :as => :string, :class => "span2", :wrapper_html => { :class => "input-append"} %>
<%= link_to image_tag('/assets/button/magnifier.png'), "#select_company", :"data-toggle" => "modal", :class => "add-on", :wrapper_html => { :class => "input-append"} %>
edit again
with the content_tag, it takes it to the separate line
First off, let's create a custom wrapper in the SimpleForm initializer.
In config/initializers/simple_form.rb:
config.wrappers :append, :tag => 'div', :class => "control-group", :error_class => 'error' do |b|
b.use :html5
b.use :placeholder
b.use :label
b.wrapper :tag => 'div', :class => 'controls' do |input|
input.wrapper :tag => 'div', :class => 'input-append' do |append|
append.use :input
end
input.use :hint, :wrap_with => { :tag => 'span', :class => 'help-block' }
input.use :error, :wrap_with => { :tag => 'span', :class => 'help-inline' }
end
end
Now let's go back to your form.
Be sure to replace #model with the actual instance variable attached to the ActiveRecord model you're using.
<%= simple_form_for #model do |f| %>
<%= f.input :company_id, :wrapper => :append do %>
<%= f.input_field :company_id %>
<%= content_tag :span, link_to(image_tag('/assets/button/magnifier.png'), "#select_company", :"data-toggle" => "modal"), :class => 'add-on' %>
<% end %>
<%= f.button :submit %>
<% end %>
Edit: Sorry it took me a bit, ended up having to make a custom wrapper in the end.
I can't remove element by data-erb-id.
Here a code from http://deface.heroku.com/:
<p class="field" data-erb-id='<%="#{address_id}address1" %>'>
<code erb-loud> form.label :address1, t(:street_address) </code><span class="required">*</span><br><code erb-loud> form.text_field :address1, :class => 'required' </code>
</p>
<p class="field" data-erb-id='<%="#{address_id}address2" %>'>
<code erb-loud> form.label :address2, t(:street_address_2) </code><br><code erb-loud> form.text_field :address2 </code>
</p>
Here is my selector:
p[data-erb-id='<%="#{address_id}address2" %>']
It matches one time, exactly what I need
Here is my closing selector:
p[class='field']
The result is:
<p class="field" id='<%="#{address_id}address1" %>'>
<%= form.label :address1, t(:street_address) %><span class="required">*</span><br><%= form.text_field :address1, :class => 'required' %>
</p>
<p class="field" id='<%="#{address_id}country" %>'>
<%= form.label :country_id, t(:country) %><span class="required">*</span><br><span id='<%="#{address_id}country-selection" %>'>
<%= form.collection_select :country_id, available_countries, :id, :name, {}, {:class => 'required'} %>
</span>
</p>
So the block I need has been removed.
This one declaration in my app doesn't remove anything:
Deface::Override.new(:virtual_path => "spree/address/_form",
:remove => "p[data-erb-id='<%=\"\#{address_id}address2\" %>']",
:name => "checkout_address")
Deface::Override.new(:virtual_path => "spree/address/_form",
:remove => "p[data-erb-id='<%=\"\#{address_id}address2\" %>']",
:name => "checkout_address")
Here is the solution.
I have two models, contest and submission. submission belongs_to contest and contest has_many submissions.
In the index action for submissions I have a search:
def index
contest_id = params[:contest_id]
#contest = Contest.find(contest_id)
if params[:search].blank?
#submissions = Submission.paginate(:per_page => 10, :page => params[:page])
else
#submissions = Submission.search(params[:search]).paginate(:per_page => 10, :page => params[:page])
end
#search = params[:search]
end
I think the right way to pass it in is through the search form in the submissions>index view:
<div class ="span12 row">
<%= form_tag submissions_path, :method => 'get', :class => "form-search pull-right" do %>
<%= text_field_tag :search, params[:search], :class => 'input-xlarge', :placeholder => 'Search by member, title or description' %>
<%= submit_tag "Search", :title => nil, :class => 'btn btn-primary' %>
<% end %>
</div>
And I have been able to come close using this:
<%= hidden_field :contest_id, #contest.id %>
In the form, but it's returning this in the url:
http://localhost:3000/submissions?utf8=%E2%9C%93&search=test&contest_id%5B%5D=&commit=Search
And an error:
Couldn't find Contest with id=
I've also tried this:
<%= hidden_field(:contest_id, :value => #contest.id ) %>
But it's returning similar url and error.
Right now, I'm stuck. If you have any idea, please let me know.
[edit - added html]
Before search:
<div class ="span12 row">
<form accept-charset="UTF-8" action="/submissions" class="form-search pull-right" method="get"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓" /></div>
<input class="input-xlarge" id="search" name="search" placeholder="Search by member, title or description" type="text" />
<input id="contest_id_5" name="contest_id[5]" type="hidden" />
<input class="btn btn-primary" name="commit" type="submit" value="Search" />
</form>
</div>
Here's what works from other links going to submissions:
From the submission show page:
<%= link_to 'Browse All Submissions', submissions_path(:contest_id => #contest.id), :class => 'btn btn-mini pull-right' %>`
and from the contest show page:
<%= link_to 'Browse All Submissions', submissions_path(:contest_id => #contest.id), :class => 'btn btn-mini pull-right' %>
Both of these pass the url "contest_id=5" which is what the controller needs to find a contest. The issue I'm having with search is finding the right syntax to get contest_id=5 to appear without the mumbo jumbo mucking it up.
This turned out to be an easy solution. Insert a hidden_field_tag in the search form:
<%= hidden_field_tag 'contest_id', #contest.id %>
This will pass the correct value into params:
http://localhost:3000/submissions?utf8=%E2%9C%93&search=new&contest_id=5&commit=Search
I'm learning how to build rails applications and I still do not fully understand how to make buttons do stuff. How do I make a particular method run using the attributes supplied in a form?
<%= button_to "Acknowledged", { :controller => 'practice_sessions',
:id => #practice_session.id},
:method => :put %>
from https://stackoverflow.com/a/4198918/643500
Read http://edgeguides.rubyonrails.org/getting_started.html
More Examples
<%= button_to "New", :action => "new" %>
# => "<form method="post" action="/controller/new" class="button_to">
# <div><input value="New" type="submit" /></div>
# </form>"
<%= button_to "New", :action => "new", :form_class => "new-thing" %>
# => "<form method="post" action="/controller/new" class="new-thing">
# <div><input value="New" type="submit" /></div>
# </form>"
<%= button_to "Create", :action => "create", :remote => true, :form => { "data-type" => "json" } %>
# => "<form method="post" action="/images/create" class="button_to" data-remote="true" data-type="json">
# <div><input value="Create" type="submit" /></div>
# </form>"
<%= button_to "Delete Image", { :action => "delete", :id => #image.id },
:confirm => "Are you sure?", :method => :delete %>
# => "<form method="post" action="/images/delete/1" class="button_to">
# <div>
# <input type="hidden" name="_method" value="delete" />
# <input data-confirm='Are you sure?' value="Delete" type="submit" />
# </div>
# </form>"
from http://apidock.com/rails/ActionView/Helpers/UrlHelper/button_to