adding size option to file_field tag in rails - ruby-on-rails-3

ANSWERED
I actually found the answer while formulating the question but I'm posting it any way since some might find this useful(as said here: https://meta.stackexchange.com/questions/49922/should-i-continue-adding-a-question-if-i-have-found-the-answer-myself)
I'm having trouble adding size to a file field in ROR3. Here was my syntax:
= f.file_field :file, :size => "11"
this doesnt appear but creates an file input field with this:
<input type="file" name="soap_test_zip_file[file]" id="soap_test_zip_file_file">
now I KNOW I made it work before so I looked into some old code and found this:
= file_field_tag :file, :size => 11
which outputs this:
<input type="file" size="11" name="file" id="file">
which gives me the correct size, but the wrong file id and name. So I tried this:
<input type="file" size="11" name="soap_test_file_file" id="soap_test_file_file">
which gives me the RIGHT ID, but the WRONG NAME. Question is how do I reproduce that file_field but with the size?
I looked into this answer by Ryan Bigg btw: Problem showing the 'size' attribute for a 'file_field' using Ruby on Rails 3
and he's saying it's a cross browser thing that they render file fields differently. That is the case, but I would like to render a short file field IF the browser can handle it.

I used:
= file_field_tag :soap_test_zip_file, {:name => 'soap_test_zip_file[file]', :size => 11}
This made me override the name(for the controller) and the size

doesn't seem to work for me..
I thought of another alternative :
jquery ..
$('#user_photo_photo').attr('size', 1);
bingo!!

If you want to not rewrite the name attribute you can do something like this :
keep your form
= f.file_field :file, :size => "11"
add an override for the file_field method
# lib/my_override.rb
module ActionView
module Helpers
module FormHelper
def file_field(object_name, method, options = {})
InstanceTag.new(object_name, method, self, options.delete(:object)).to_input_field_tag("file", options.update({:size => options[:size]}))
end
end
end
end
And load it through an initializer
# config/initializers/load_lib.rb
require 'my_override'

Related

Rails field_with_errors and Bootstrap 4 vertical form

I have a simple rails 5 form for New/Edit using vertical alignment using Bootstrap4. Everything looks fine until I get an error. The .field_with_errors is breaking the alignment.
It seems like the .col-x-x selectors are being ignored once the field_with_errors is introduced. I know bootstrap 4 is still in alpha, but hoping someone has found a work around.
Here is the form:
.container.wow.fadeInUp{style: "visibility: visible; animation-name: fadeInUp;"}
%h2.state New State
.w-75
= errors_for(#state)
.card
= form_for [:admin, #state] do |f|
.card-block
.form-group.row
= f.label :name, class: 'col-sm-4 col-form-label'
.col-sm-5
= f.text_field :name, class: 'form-control'
.form-group.row
.col-sm-3
= f.submit "Save", class: 'btn btn-primary'
you can remove the field_with_error div that breaks your css
Here's a simple trick to do away with those pesky wrappers once and for all. Just add this block to your config/environment.rb file.
ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
html_tag.html_safe
end
Difficult to find a good answer to this, as all the old answers seem to refer to .has-error, and this is no longer supported in Bootstrap.
An extention of the answer given by #LifterCoder, inspired by this blog post, allows the label tags to be ignored, but still wrap the other tags with .field_with_error tags.
ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
if instance.kind_of?(ActionView::Helpers::Tags::Label)
html_tag.html_safe
else
"<div class=\"field_with_errors\">#{html_tag}</div>".html_safe
end
end

simple_form radio button (need to add <span> tag inside of <label>

What is the best way to create the following HTML using simple_form_for gem?
<label>
<input name="form-field-radio" type="radio" />
**<span class="lbl"> radio option 2</span>**
</label>
Note that by default when I create a radio buttons using the following statements, the above is not created. How can I add that tag in?
<%= f.input :state, :collection => Project::STATES, :as => :radio_buttons %>
I had a similar need (to embed a <span> within the <label>). It isn't the cleanest solution but it did work and I think with some tweaking it could get you the ability to have your input and span embedded within the label. The following modification results in:
<label>Name:
<span class="hint">this is a hint...</span>
</label>
I added the following as an initializer (using rails 4 and simple_form 3) to override the label_text method:
# initializers/simple_form_custom.rb
module SimpleForm
module Components
module Labels
def label_text
if hint
hint_text = %[<span class="hint">#{hint}</span>]
else
hint_text = ""
end
SimpleForm.label_text.call(raw_label_text, required_label_text, hint_text).strip.html_safe
end
end
end
end
Then in initializers/simple_form.rb I have:
config.label_text = lambda { |label, required, hint| "#{label}: #{required} #{hint}" }

How to get the current view name from layout template in Rails?

Is it possible to get the name of the currently rendered view from inside layout?
I did something like this for css namespacing:
# config/initializers/action_view.rb
ActionView::TemplateRenderer.class_eval do
def render_template_with_tracking(template, layout_name = nil, locals = {})
# with this gsub, we convert a file path /folder1/folder2/subfolder/filename.html.erb to subfolder-filename
#view.instance_variable_set(:#_rendered_template, template.inspect.gsub(/(\..*)/, '').split('/')[-2..-1].join('-'))
out = render_template_without_tracking(template, layout_name, locals)
#view.instance_variable_set(:#_rendered_template, nil)
return out
end
alias_method_chain :render_template, :tracking
end
# application.html.erb
<body class="<%= :#_rendered_template %>" >
Use <% __FILE__ %> to get the complete file path of current view, but you can only use it from within the file itself without writing some helpers
The method active_template_virtual_path method returns the template as a name in the following form "controller/action"
class ActionController::Base
attr_accessor :active_template
def active_template_virtual_path
self.active_template.virtual_path if self.active_template
end
end
class ActionView::TemplateRenderer
alias_method :_render_template_original, :render_template
def render_template(template, layout_name = nil, locals = {})
#view.controller.active_template = template if #view.controller
result = _render_template_original( template, layout_name, locals)
#view.controller.active_template = nil if #view.controller
return result
end
end
I had a similar question. I found <%= params[:controller] %> and <%= params[:action] %> to suit my need, which was to add the controller name and action name as classes on the body tag.
Just in case that helps anyone. :)
I'm currently using a modified version of Peter Ehrlich's solution. The resulting string is of the form controller_name/view_name, e.g. users/new, which means it can be passed directly to render later on, or altered to suit other uses. I've only tried this with Rails 4.2, though as far as I know it ought to work all the way back into the 3.xes.
ActionView::Base.class_eval do
attr_accessor :current_template
end
ActionView::TemplateRenderer.class_eval do
def render_template_with_current_template_accessor(template, layout_name = nil, locals = {})
#view.current_template = template.try(:virtual_path)
render_template_without_current_template_accessor(template, layout_name, locals)
end
alias_method_chain :render_template, :current_template_accessor
end
For debugging purpose, you can use gem 'current_template' from here.
This gem inspects logfile and display file name of view/partial template.
For example:
Also, you can simply add this line
<%= "#{`tail log/development.log`}".scan(/\s[a-z]+\/\S+/) %>
to your layout/application.html.erb.

How do I specify a custom class on a formtastic 1.2.4 field?

I have this custom form builder, and it calls:
basic_input_helper(:text_field, :date, :date_value, options.merge!({:html_options => {:class => "datepicker"}})) if options[:response_class] == "date"
The fourth parameter there are the options (the html options, if I read the code correctly), and I would expect that line to add class="datepicker" to my input field, but instead I get:
<input id="r_3_date_value" name="r[3][date_value]" size="30" type="text" value="2012-07-02" />
No class attribute at all. What am I missing?
You have to use the key :input_html instead of :html_options
basic_input_helper(:text_field, :date, :date_value, options.merge!({:input_html => {:class => "datepicker"}})) if options[:response_class] == "date"
The code gets evaluated like this (source on github), you can see the evaluation for input html on line 647

Rails 3 Rendering Binary Content

I need to render binary content(images) on web page. I'm saving images in the database with datatype binary. Now I need to iterate available images from the database and render on webpage.
Please check the below code that I'm doing. Icon is the image column name in material.
// iterating all materials
<% #materials.each do |material| %>
// for each material
<span><%= image_tag(material.icon) %></span>
<% end %>
Any help would be greatly appreciated..
You need to add an action to your controller along these lines (cribbed from here):
def image
#material = Material.find(params[:id])
send_data #material.icon, :type => 'image/png',:disposition => 'inline'
end
Then call the path to that action in your image_tag. You obviously need to make sure the :type field has the right MIME type, add a route, etc.