'undefined local variable or method' with render partial rails 5 - javascript

I want to render a modal form and be able to render it on differents places; hence I want to be able to change the order_id that is required to create a new feedback on server side (I use AJAX).
However, my render partial does not work. I get the following error:
undefined local variable or method `user_order_id' for #<#<Class:0x007fec6be26af8>:0x007fec6bf1b2d8>
any Idea ?
index.html.erb
[...]
<%= render partial: 'feedback_modal', locals: {user_order_id: #user_last_order} %>
[...]
_feedback_modal.html.erb
<%= simple_form_for(#review, method: :post, url: review_path(current_user.id, user_order_id), remote: true) do |f| %>
<%= f.input :rating, collection: [1,2,3,4,5], prompt: "Rate this meal", class: "col-sm-3" %>
<%= f.label :comment, "Your comments" %>
<%= f.text_area :comment, class: "commentaire" %>
<%= f.button :submit ,"Send Feedback", class: "btn" %>
<% end %>
controller:
[...]
#user_last_oder = Order.where(user_id: current_user.id, status: nil).last.id
[...]

Related

AJAX call being handled but not rendering in rails view

In a rails 4.2 application, a div lists and renders existing cartitems
<div id='yield_cartitem'>
<%= render 'cartitems' %>
</div>
and the same page has forms (one per listed products).
<%= form_for(#cartitem, remote: true, id: 'data-js-cartitem-form', data: {'js-cartitem-form' => true}) do |f| %>
<%= f.hidden_field :product_id, value: product.id %>
<%= f.hidden_field :price, value: product.price %>
<%= f.submit 'Add to cart' %>
<% end %>
The javascript for the class defines via jQuery
$(document).on('turbolinks:load', function() {
$('[data-js-cartitem-form]').on("ajax:success", function(event, data, status, xhr){
var cartitem = $(xhr.responseText).hide();
$('#cartitems').append(cartitem);
cartitem.fadeIn(1000);
document.getElementById('data-js-cartitem-form').reset();
});
$('#cartitems').on("ajax:success", function(event, data, status, xhr){
var cartitem_id = xhr.responseJSON.id;
$('[data-js-cartitem-id=' + cartitem + ']').hide();
});
});
The controller create action runs as by design with the following rendering instruction.
if #cartitem.save
render partial: 'cartitem', locals: {cartitem: #cartitem}
end
_cartitems.html.erb has
<div id=cartitems class='tableize'>
<%= render partial: 'cartitem', collection: #cartitems %>
</div>
while _cartitem.html.erb defines
<div class='row' data-js-cartitem-id=<%= cartitem.id %>>
<%= cartitem.quantity %>
<%= cartitem.um %>
<%= cartitem.product.try(:name) %>
<%= cartitem.price %>
</div>
_cartitem.js.erb calls $("div#yield_cartitem").html('< %=j (render 'cartitem') %>');
The XHR response payload is returning $("div#yield_cartitem").html('< %=j (render 'cartitem') %>'); but the div is not refreshing with the newly created cartitem.
Where has this gone wrong?
update
Trying to simplify matters by changing the _cartitems.js.erb to an alert:
alert("<%= cartitem.quantity %> <%=j cartitem.um %> <%=j cartitem.product.try(:name) %> <%= number_to_currency(cartitem.price) %> Added")
The alert does effectively render.
alert("1.0 kg Prod 1,89 € Added")
I may be wrong but I noticed that in controller you are passing locals to cartitem html partial but not in js.erb file. So do that in cartitem.js.erb file:
$("div#yield_cartitem").html('< %=j (render 'cartitem', cartitem: cartitem) %>');
it's really hard to debug js.erb files but it's possible. Try to use gem pry to see context and variables inside the partial.
$("div#yield_cartitem").html('<%= binding.pry; j(render 'cartitem', cartitem: cartitem) %>');
$("div#yield_cartitem").html('<%=j (render 'cartitem') %>') this will replace the contents of #yield_cartitem
instead use $('#cartitems').append('<%= j render('cartitem', cartitem: #cartitem) %>')
and update this function
$('[data-js-cartitem-form]').on("ajax:success", function(event, data, status, xhr){
// var cartitem = $(xhr.responseText).hide();
// $('#cartitems').append(cartitem);
// cartitem.fadeIn(1000);
document.getElementById('data-js-cartitem-form').reset();
});
Additionally rename _cartitem.js.erb to create.js.erb then create will render it automatically

Getting the individual checkbox value in JQuery

I have several checkboxes and have a JQuery function that I want to print out the value I give each checkbox when I click on the checkbox. However, 1 keeps printing out. I assign each checkbox an item.id based on a primary key from my db using Rails. Here is my code
<script>
$(document).ready(function(){
$('input[type="checkbox"]').on("change", function() {
var hall_id = $(this).val(); // here is where I want to get the value that I assigned to the checkbox
if (this.checked) {
console.log( hall_id );
} else {
console.log( hall_id );
}
});
});
</script>
<%= link_to "Logout", root_path %>
<h1>Hello <%= #user.first_name%> <%= #user.last_name%></h1>
<%= form_for #item do |f| %>
<%= f.label :to_do %>:
<%= f.text_field :to_do %><br />
<%= f.hidden_field :email, :value => #user.email%>
<%= f.submit %>
<% end %>
<% #items.each do |item|%>
<%if item.email == #user.email%>
<%= form_for #item do |f| %>
<%= item.id%>
<%= f.check_box :to_do, :value => item.id%> //This is where I assign the value for the check box
<%= item.to_do%><br />
<% end %>
<%end%>
<%end%>
In the image I am trying to print out the number by the checkbox(item.id), but in the console it only prints out 1
Look at the documentation on the check_box helper method: http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-check_box
Notice that the optional 4th argument is the checked_value which defaults to 1. Here is how you can switch it to the id of your item object:
<%= f.check_box :to_do, :id, {}, item.id %>

undefined method `map' for :id:Symbol

ActionView::Template::Error (undefined method `map' for :id:Symbol):
1: <div id="dropdown-no-2">
2: <%= collection_select 'challenge_id', challenges, :id, :full_challenge, include_blank: true %>.
3: </div>
How can I solve this error so that only the challenges for that respective user are listed?
duels/_dueler_fields.html.erb
<%= f.select :user_id, User.order(:name).map { |user| [user.full_name, user.id] }, include_blank: true, id: "change-challenge-options" %>
will
<%= render :partial => 'user_challenges', locals: {challenges: Challenge.order(:created_at)} %>
<script>
$( "#change-challenge-options" ).change(function() {
$.ajax({
type: "GET",
url: '<%= user_challenges_path %>',
data: {name: $('#change-challenge-options').prop('value')}
});
});
</script>
duels/_user_challenges.html.erb
<div id="dropdown-no-2">
<%= collection_select(':challenge_id', challenges, :id, :full_challenge, include_blank: true) %>.
</div>
duels/user_challenges.html.erb
$("#dropdown-no-2").html('<%=j render :partial => "user_challenges", locals: {challenges: #challenges} %>');
duels_controller.rb
def user_challenges
#user = User.find(params[:id])
#challenges = #user.challenges.order(:created_at)
end
def new
#duel = Duel.new
#duel.duelers << Dueler.new(user_id: current_user.id, user_name: current_user.name, user_last_name: current_user.last_name)
respond_with(#duel)
end
routes.rb
get 'duels/user_challenges', :to => 'duels#user_challenges', as: 'user_challenges'
Change this to:
<%= collection_select(:duel, :challenge_id, challenges, :id, :full_challenge, include_blank: true) %>
Refer collection_select
Third parameter of collection_select has to be a collection (to populate the select), not a symbol.
http://apidock.com/rails/ActionView/Helpers/FormOptionsHelper/collection_select

client_side_validation gem - boolean as check boxes

I'm using the client_side_validation gem to do js validations in my app. I'm using the simple_form version.
I've got a boolean attributes in my permission model which are validated
class Permission < ActiveRecord::Base
validates :local, :regional, :national, :inclusion => {:in => [true, false]}
end
However in the view they are rendered as checkboxes, which have value of either 1 or 0, so they are never marked as validated.
Any ideas?
You will have to set :validate => false for checkboxes. E.g.
<%= simple_form_for #permission, :validate => true do |f| %>
<%= f.input :name, :label => 'Name' %>
<%= f.label :local %>
<%= f.check_box :local, :validate => false %>
<%= f.label :national %>
<%= f.check_box :regional, :validate => false %>
<%= f.label :regional %>
<%= f.check_box :national, :validate => false %>
<%= f.button :submit %>
<% end %>
As checkboxes are by definition true or false, client side validation is not really necessary. With your server-side validation, you are still protected from someone trying to maliciously submit non-boolean values.

Routing error that appears to have something to do with partials and/or forms

In a Rails 3 application, I have a "table" partial that contains a data entry form table, plus a separate smaller form (mostly hidden fields) below it to clear the table data. I have a third form underneath the partial to add a new column to the table contained in the partial. The page loads fine. The small form to clear the table data works, and refreshes the partial as it is supposed to. BUT, When I submit the add-new-column form, I get this routing error:
ActionView::Template::Error (No route matches {:controller=>"outcome_results", :action=>"clear_table"}):
70: </table>
71: <%= submit_tag "Save" %>
72: <% end %>
73: <%= form_tag url_for(:controller => 'outcome_results', :action => 'clear_table'), :id => "clear_data_table_link", :remote => true do %>
74: <%= hidden_field_tag "subgroup_id", subgroup_id %>
75: <%= hidden_field_tag "outcome_id", #selected_outcome_object.id %>
76: <%= hidden_field_tag "timepoint_id", timepoint_id %>
app/views/outcome_results/_table.html.erb:73:in `_app_views_outcome_results__table_html_erb__204353865_18893424_435027370'
app/controllers/outcome_columns_controller.rb:36:in `block (3 levels) in create'
app/controllers/outcome_columns_controller.rb:35:in `block (2 levels) in create'
app/controllers/outcome_columns_controller.rb:33:in `create'
Line 72 is the end tag of the first (table/data entry) form.
Line 73 is the form tag for my clear-table-data form which works fine on its own - no routing errors there.
My routes.rb is crazy long but contains this line:
match 'projects/:project_id/studies/:study_id/clear_table' => 'outcome_results#clear_table'
The add-new-column form looks like this:
<div id="outcome_column_validation_message"></div>
<%= form_for #outcome_column, :action => :create, :remote => true, :id=>"outcome_columns_form" do |f| %>
<%= hidden_field_tag "outcome_id", !#selected_outcome_object.nil? ? #selected_outcome_object.id : nil %>
<%= hidden_field_tag "subgroup_id", !#selected_timepoint.nil? ? #selected_timepoint : 0 %>
<%= hidden_field_tag "timepoint_id", !#selected_subgroup.nil? ? #selected_subgroup : 0 %>
<div class="field">
Custom Column Title: <%= f.text_field :name %> Description: <%= f.text_field :description %> <%= f.submit "Add Custom Column" %>
<% end %>
and the format section of the "create" action in the "outcome_column" controller looks like this:
respond_to do |format|
format.js {
render :update do |page|
page.replace_html 'outcome_results_table', :partial => 'outcome_results/table'
page['outcome_columns_form'].reset
page.replace_html 'outcome_column_validation_message', ""
end
}
end
I can post more code if it would help... anyone have any ideas about this routing error?
Thanks in advance.
The route would take two arguments: a project_id and a study_id. This is not matching the route because you have not passed through these two parameters to the url_for in your form_tag.

Categories