Render partial through js.erb - ruby-on-rails

Im trying to render a form to add a comment via jquery, but i keep getting this error:
undefined method `render' for #<#<Class:0x007fc8aaa18860>:0x007fc8a0fddfc0>
Here is the js.erb file:
$(document).on('turbolinks:load', function(){
console.log('test');
$('.reply-comment-form').on('click', function(e) {
e.preventDefault();
body = this.id;
$('.nest-' + body).append( "<%= escape_javascript(render partial: 'comment_reply_form')%>");
});
});
Ive tried multiple different iterations of the code but still the same error.
When i try say, this for example:
$('.nest-' + body).append( " This is a test");
It does as it should do.
Ive checked the other questions here and i cant see anything different to what i'm doing so i'm a little stuck.
Here is what im trying to render:
<div class="body">
<span class="tip tip-left"></span>
<div class="message font-medium">
<%= form_for #message do |form| %>
<%= form.label :Reply_to_comment %> <br />
<%= form.text_area :content, :rows => 5, :cols => 80, autofocus: true %> <br />
<%= form.hidden_field :entry_id, value: params[:entry_id] %>
<%= form.hidden_field :parent_id, :value => params[:parent_id] %>
<%= form.submit "Submit"%>
<% end %>
</div>
<div class="flerowspb">
<span class="font-small">
</span>
</span>
</div>
</div>
Thanks

Ok so I've come across the answer, I cant call render from the assets folder.
Here is the link

Try to the following
$('.nest-' + body).append( "<%= escape_javascript(render("messages/comment_reply_form"))%>");
or
$('.nest-' + body).html("<%= escape_javascript(render("messages/comment_reply_form")) %>");

Try using j render:
$('.nest-' + body).append( "<%= j render 'comment_reply_form' %>");
and i think that path for partial view should be more accurate, like 'controller_name/view/partial' , or whatever you have in your code.

Related

One form element not being rendered when validation fails

I have not been able to figure out if this is a simple_fields_for problem, a cocoon issue, or something else. If I have blundered with a </div> placement, I don't see it.
When the form first displays, it renders an input field for protocol name. The user can click buttons to add form elements of interest. This works fine and looks like this:
Here's how it looks after the user has clicked on each of the "Add an element" buttons:
The user can add 0..many of each of the elements. When they click on 'Save' it all works really well.
If there is a validation error in one of the fields, the form re-renders fine with one exception. Validation errors for the "Imaging Step" elements do not re-display at all. The other elements re-render and are highlighted as expected when validation fails.
Here's a pictorial example. The user fills out part of the form, having forgotten to select a "Sequence" and having forgotten to enter text for "Tip Description":
After clicking 'save' and failing validation, the form re-renders like this:
As you can see, the Imaging Step section has not been redrawn.
If I look at params in the context of the view, everything seems to be there. #protocol.errors looks right to me as well. Models seem OK too.
Here is a pastebin of the form code.
Here is a pastebin of _step_item_fields.html.erb.
Here is a pastebin of _tip_fields.html.erb.
Here is a pastebin of my Gemfile.
UPDATE:
if I build a step_item like this:
<div id="step_items">
<%= f.simple_fields_for :step_items, #protocol.step_items.build do |si| %>
<%= render 'step_item_fields', :f => si %>
<%end%>
</div>
The Imaging Step section is always drawn, but (obviously) does not populate when validation fails. This also confuses the feature of letting the user add/remove 0..many Imaging Steps.
I also tried:
<div id="step_items">
<%= f.simple_fields_for :step_items, #protocol.step_items.build(protocol_params) do |si| %>
<%= render 'step_item_fields', :f => si %>
<%end%>
</div>
... and other variants when protocol_params is available, but ran in to forbidden params issues.
UPDATE2:
I also tried building a hash with params for a step_item. I can use this here:
<div id="step_items">
<%= f.simple_fields_for :step_items, #protocol.step_items.build(some_ok_params) do |si| %>
<%= render 'step_item_fields', :f => si %>
<%end%>
</div>
... but only for a single step_item. Am not sure how to pass a hash of hashes reflecting the 0..many functionality. Also, building a step_item this way populates the form element correctly, but does not include the error highlighting styling. This is about the time I started wondering why the simpler solution was not working.
Since StepItem is a sub-type of the STI class Step, I think the error detection for StepItems was getting missed. My hack fix here is not pretty and admittedly brittle. Please post a better way if you have one.
I changed this in _form.html.erb:
...
<%if params["protocol"] && params["protocol"]["step_items_attributes"].present?%>
<%params["protocol"]["step_items_attributes"].each do |sia|%>
<%v = sia[1]%>
<div id="step_items">
<%= f.simple_fields_for :step_items, #protocol.step_items.build(:orientation_id => v["orientation_id"], :sequence_id => v["sequence_id"], :note => v["note"], :id => v["id"], :protocol_id => v["protocol_id"], :institution_id => v["institution_id"] ) do |si| %>
<%= render 'step_item_fields', :f => si%>
<% end %>
</div><!-- end step_items-->
<%end%>
<%else%>
...
I changed this in _step_item_fields.html.erb:
...
<div class="nested-fields">
<div class= "form-inputs">
<div class="row">
<div class="col-sm-2 text-right">Imaging Step:</div>
<div class="col-sm-2 drop_col ">
<%= f.collection_select :orientation_id, Orientation.where("institution_id=?",current_user.current_institution_id),:id,:name, {:prompt => "Pick an Orientation", }, {class: "form-control #{"dropdown_error" if f.object.orientation_id.blank? && (f.object.sequence_id.present? || f.object.note.present?)}"}%>
</div>
<div class="col-sm-2 drop_col ">
<%= f.collection_select :sequence_id, Sequence.where("institution_id=?",current_user.current_institution_id),:id,:name, {:prompt => "Pick a Sequence"}, {class: "form-control #{ "dropdown_error" if f.object.sequence_id.blank? && (f.object.orientation_id.present? || f.object.note.present?) }"}%>
</div>
</div>
<div class="row">
<div class="col-sm-2"></div>
<%= f.input :note, :wrapper_html =>{:class => 'col-sm-8'}, label: false, placeholder: 'You can put an optional note here.' , :input_html => {:size => 50}%>
<%= f.input :institution_id,:as => :hidden, :input_html => {:value=>current_user.current_institution_id} %>
<%= f.input :id,:as => :hidden %>
<div class="col-sm-2">
<%= link_to_remove_association "Remove Imaging Step", f , :class=>"btn btn-danger btn-xs placemid",title: "Click here to delete this imaging step.", data: {toggle: "tooltip", placement: "auto", animation: true, delay: {show: 700, hide: 100}}%>
</div>
</div>
</div>
<div class="col-sm-12"><hr></div>
</div>
...
And I added this to the correct stylesheet:
.dropdown_error{
color: red;
}
The form now displays StepItem errors correctly as seen here:

Using a Method from Controller in Another Rails

I am using elasticsearch on my rails 4 app to search through my articles.
However, when an article is not found it redirects to a page where it alerts the user that no results are found, and allows to request a page. Instead of it saying "no results found" I want it to say "no results for ______ found" in which is takes the search bar query.
I have defined a method in the articles_controller in order to get the query but it won't show up on the page since the "no results page" uses a different controller.
What would be the best way to pull the method onto another controller or view in this case? Having trouble finding a straight forward answer for what I am trying to do. Thank you very much.
articles_controller:
def index
if params[:query].present?
#articles = Article.search(params[:query], misspellings: {edit_distance: 1})
else
#articles = Article.all
end
if #articles.blank?
return redirect_to request_path
end
get_query
end
private
def get_query
#userquery = params[:query]
end
new.html.erb (view for "no results found" page. Uses a different controller than articles page):
<body class="contactrequest">
<div class="authform" style="margin-top:15px">
<%= simple_form_for #request, :url => request_path do |f| %>
<h3 style = "text-align:center; color:red;">No results found. <%= #userquery %></h3>
<h1 style = "text-align:center; color:black;">Request a Page</h1>
<h5 style = "text-align:center; color:black; margin-bottom: 25px;">Our experts will gather the information,<br> and have your page us ASAP!</h5>
<%= f.error_notification %>
<div class="form-group">
<%= f.text_field :email, placeholder: 'Email', :autofocus => true, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.text_field :subject, placeholder: 'Item / Page Requested', class: 'form-control' %>
</div>
<div class="form-group">
<%= f.text_area :content, placeholder: 'Any additional details...', class: 'form-control', :rows => '5' %>
</div>
<%= f.submit 'Request it', :class => 'btn btn-lg btn-danger btn-block' %>
<% end %>
As you can see I've tried calling that #userquery method to display on the view page, but it doesn't show up since it's defined on a different controller. Any recommendations would be awesome.
I would suggest you render results and no results from the same controller/view. A nice clean way to do this is with partials. Your view could look something like:
<% if #articles.blank? %>
<%= render 'no_results' %>
<% else %>
<%= render 'results' %>
<% end %>
Then, you would simply create _no_results.html.erb and populate it with your current new.html.erb contents and do the same for your nominal results page (with partial _results.html.erb).

Error: Syntax - Html to RoR

I have a _form and in this _form I am putting one icon in front some fields.
I want wich when mouse hovers over it, it displays a tooltip. The text is there in translate file:
..
t('messages.issue_tittle_placeholder')
..
I can do this using only html, but I want do this using RoR.
<div class="clearfix">
<%= f.label :title %>
<div class="icon-question_enabled" rel="tooltip"
title="Keaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaa">
</div>
I tried to this:
<%= f.label :title %>
<%= image_tag('icons/question_enabled.png', class=> "tooltip-help") %>
Someone can help me?
Sorry for my english.
According to your html snippet, your icon is just a <div> with a css class that has a sprite background instead of an <img>. You should do:
<%= f.label :title %>
<%= content_tag(:div, nil, class: 'icon-question_enabled', rel: :tooltip, title: "Keaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaa") %>
Your syntax is off. For > Ruby 1.9 it should be:
<%= image_tag('icons/question_enabled.png', class: "tooltip-help") %>
else < 1.8
<%= image_tag('icons/question_enabled.png', :class => "tooltip-help") %>

How to save ids in the cookies

I am using will_paginate to list a huge ammont of files in different pages. I also have a check_box in order to choose files for the futher analysis.
controller:
#files = FileDB.search(search_string).paginate(:per_page => 10, :page => params[:page])
view:
<button type="button" id="check_all">Check/Uncheck all</button>
<%= button_tag :class => "btn btn-primary", :name => 'analyse' do %>Analyse<% end %>
<% #filess.each do |file| %>
<p><td> <%= check_box_tag "files[]", file.id %></td><%= file.name %></p>
lala...
My problem is that I can choose the files which are situated in one page.So by clicking on "check/uncheck all" it checks not all available files, but files of this specific page. I would like to be able to check different files from different pages together.
Example: 10 files on the page 1, 4 files on the page 2. I want to check 5 files from page one and all files from page 2 and then by clicking on the buttom "Analyse", those 9 files have to be analyzed together, so the checkbox should remember different files from different pages
I know it is possible to save ids in the cookies, but I have found nothing in internet how to do it. I need just a small example
Thanks in advance
edit:
or maybe there is an alternative to the will_paginate that uses POST?
edit2: according to Muntasim
<script type='text/javascript'>
$('#check_all').on("click", function(){ $('input[type="checkbox"]').click(); });
</script>
<script src="/assets/rails.validations.js" type="text/javascript"></script>
<script src="/assets/jquery.cookie.js" type="text/javascript"></script>
<script type="text/javascript">
var checkedIds = $.cookie('checked_file_ids');
$('p td input[type=checkbox]').on('change', function () {
if($(this).is(':checked')) {
checkedIds.push($(this).val())
}
else {
checkedIds.splice(checkedIds.indexOf($(this).val()), 1);
}
$.cookie('checked_file_ids', checkedIds);
})
</script>
<%= form_for Group.new, url: what_to_do_files_path ,method: :get ,:validate => true do |f| %>
<div class="field">
<%=f.text_field :group_name, placeholder: "Group Name" %>
</div>
<%= button_tag :class => "btn btn-primary", :name => 'analyse' do %>Analyse<% end %>
<button type="button" id="check_all" class="btn"> Check/Uncheck All</button>
<% #files.each do |file| %>
<p><td> <%= check_box_tag "files[]", file.id , false %></td><%= file.name %></p>
<%end%>
<%end%>
And in a controller:
def what_to_do
ids_to_compare = cookies['checked_file_ids']
end
But ids_to_compare is empty
You can simply do:
cookies[:ids] = #All checked ids
And then to retrieve the ids you can easily call the cookie like this:
cookies[:ids]
if you want to use cookie:
use jquery.cookie
Now put this in the view
<script type="text/javascript">
var checkedIds = $.cookie('checked_file_ids');
$('p td input[type=checkbox]').on('change', function () {
if($(this).is(':checked')) {
checkedIds.push($(this).val())
}
else {
checkedIds.splice(checkedIds.indexOf($(this).val()), 1);
}
$.cookie('checked_file_ids', checkedIds);
})
</script>
now when you need to compare them you can get the ids: (likely in a controller)
ids_to_compare = cookies['checked_file_ids']

How do I change the html tag and class generated by fields_for?

This is a simple question that I'm kinda ashamed to ask, but I've been banging my head against the wall and navigating through the rails 3 documentation without any success :/
So, here is the thing:
When I use the fields_for helper it wraps the generated fields in a <div class="fields"> ... </div> tag.
so, my code is
<ul class="block-grid two-up">
<%= f.fields_for :images do |image_builder| %>
<%= render "images/form", :f => image_builder %>
<% end %>
</ul>
and the generated html is:
<ul class="block-grid two-up">
<div class="fields">
<div>
<label for="company_images_attributes_0_image"> Image</label>
<input id="company_images_attributes_0_image"
name="company[images_attributes][0][image]" type="file">
</div>
</div>
<div class="fields">
<div>
<label for="company_images_attributes_1_image"> Image</label>
<input id="company_images_attributes_1_image"
name="company[images_attributes][1][image]" type="file">
</div>
</div>
</ul>
What I want to do is actually change the <div class="fields"> wrapper tag to <li>.
The documentation says you can pass options to the fields_for, but its not clear about what options you can pass, maybe you can change this wrapper tag?
A possibility could be to override a function, kinda like ActionView::Base.field_error_proc when there is an error in the form.
Quick edit: I forgot to mention that I'm using simple_form to generate this form. I tried looking in the simple_form.rb config file for a way to customize this, but I didn't see any way of doing it.
Solution
After further investigation, it turns out the form was using the nested_form gem as well to generate the form (not only simple_form). This generator was causing the fields_for to be wrapped in the div tag. Thanks everybody for their suggestions!
The following disables the wrapper:
f.fields_for :images, wrapper:false do |image_builder|
then you can add your own wrapper in the builder block.
A cheap solution would be just adding <li> tag into the form like:
<%= f.fields_for :images do |image_builder| %>
<li><%= render "images/form", :f => image_builder %></li>
<% end %>
I am not sure if you can completely eliminate the div tag by passing some params to field_for. But I think you can change the name of div class or id by passing the html block, like in form_for:
<%= form_for #image, :as => :post, :url => post_image_path,
:html => { :class => "new_image", :id => "new_image" } do |f| %>
You said you're using simple_form then you should be saying <%= f.simple_fields_for... Have you tried using wrapper_html option:
<%= f.input :name, :label_html => { :class => 'upcase strong' },
:input_html => { :class => 'medium' }, :wrapper_html => { :class => 'grid_6 alpha' } %>
Edit 1:
From SimpleForm documentation:
Wrapper
SimpleForm allows you to add a wrapper which contains the label, error, hint and input. The first step is to configure a wrapper tag:
SimpleForm.wrapper_tag = :p
And now, you don't need to wrap your f.input calls anymore:
<%= simple_form_for #user do |f| %>
<%= f.input :username %>
<%= f.input :password %>
<%= f.button :submit %>
<% end %>
Edit 2:
And there is this config option with which you can say what css class to use with the wrapper elements:
config/initializers/simple_form.rb
# CSS class to add to all wrapper tags.
config.wrapper_class = :input

Resources