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!
Building a Rails 3.1 app Ruby 1.9 with Devise for user authentication.
Since i'm using Devise to authenticate users I used jquery UI tabs display in the users/edit view. I have one tab to display form for user profile settings and and another for user security settings.
Problem is when i click submit to update either profile or security information it attempts to submit the forms for both. I have the submit buttons set up for each tab separately. How can i set this up so that i can submit the forms on each tab individually?
My users/edit.html.erb file
div id="tabs">
<ul id="user-config-tabs">
<li>Profile Settings</li>
<li>Security Settings</li>
</ul>
<div id="profile-tab"> <!-- Start security settings tab info-->
<%= render 'profilesettings'%>
</div>
<div id="security-tab"> <!-- Start Profile settings tab info-->
<%= render 'securitysettings'%>
</div>
</div>
Profile settings PArtial
<h3 style = "text-align: left">Profile Settings</h3>
<div class="row">
<p id="privacy"><%=link_to "privacy policy", privacy_path%></p>
<div class="span6 offset3">
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :method => :put }) do |f| %>
<fieldset>
<legend>General Information</legend>
<div><%= f.label "First Name" %>
<%= f.text_field :name, :autofocus => true %>
<%= f.label "Last Name" %>
<%= f.text_field :last_name, :autofocus => true %>
<%= f.label "Age" %>
<%= f.text_field :age, :autofocus => true%>
<%= f.label "Gender" %>
<%= f.select :gender, User::GENDER_TYPES, prompt: 'Select'%>
</div>
</fieldset>
<div><%= f.submit "Update", class: "btn btn-large btn-primary" %></div>
<% end %>
</div>
</div>
Can't you just let the whole form submit but then only use the information that you want to ?
If you dont want the page to submit then I would use ajax to submit the form and serialize only what you need. For example:
$.ajax({
url: "/post_path",
type: 'POST',
cache: false,
async: false,
data: $("#security_form").serialize(),
success: function(data){
if(data.valid == "true"){
$('#notice').html("Updated succesfully").slideDown();
}else{
$('#errors').html(data.errors).slideDown();
}
}
});
Then you can handle this in the controller.
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
In my app use tinymce editor and the problem is that the form send empty textarea. When I remove Tinymce from this form, so everything's working well.
<%= form_tag({ :controller => 'home', :action => 'process_note' }) do %>
<%= hidden_field_tag 'user_id', #user_note.id%>
<div style="width: 800px;">
<div>Your note:</div>
<div>
<%= text_area_tag 'new_note', #user_note.note, :class => 'mceEditor text', :style => 'width: 700px;height: 250px;' %></td>
</div>
<div>
<%= submit_tag "Save" %>
</div>
</div>
<% end %>
Have anyone a similar experience with this behavior? I have already no idea, where could be a problem
I have a form as follows:
<%= form_for(:session, :url => sessions_path, :remote => true, :html => {:id => 'login_form'}) do |f| %>
<div class="formRow">
<%= f.label :email %><br>
<%= f.text_field :email, :value => (#email if #email) %>
</div>
<div class="formRow">
<%= f.label :password %><br>
<%= f.password_field :password %>
</div>
<div class="formRow small">
<%= link_to "I forgot my password",'#' %>
</div>
<div class="formRow">
<%= f.submit signin_button_text, :class => "button-big left" %>
</div>
<% end %>
It goes to this controller:
def create
#email = params[:session][:email]
user = User.authenticate(params[:session][:email],params[:session][:password])
respond_to do |format|
if user.nil?
#title = "Sign in"
flash.now[:error] = "Invalid email/password combination"
format.js {render :action => :new }
else
sign_in user
format.js {render :action => :create }
end
end
end
Here is the new.js file:
$('#login_form').replaceWith("<%=escape_javascript(render 'login_form')%>");
if($('.flash-block').length ==0) {
$('#login_form').before("<div class='flash-block error'><span><%=escape_javascript(flash[:error])%></span></div>");
}
For some reason if the form is submitted with errors it loops four times.
I don't understand why.
Is there something in the code that causes this to loop?
I am assuming that you are using jquery. This is usually happened when there is an incomplete call or there is some sort of error and you haven't refresh the page. Try something like this:
<script type="text/javascript">
$('#login_form').submit(function() {
$(this).unbind('submit').submit();
});
</script>
I was using Fancybox and was not opening it in an iframe. So I wound up loading the jquery libraries twice and thus when I submitted the form I had multiple submissions.
Once I opened Fancybox in an iframe it submitted only once.