Rendering with jquery and locals - ruby-on-rails

Im having trouble rendering with jquery, I have a notification page which shows all notifications, then when i click on 1 for example it will show all the 1's and if i click 2 it will show all the 2's etc etc.
This is where all the notifications are rendered to start with. The locals work fine here.
<% #notifications.each do |x| %>
<div class="testing123">
<%= render 'notification', x: x %>
</div>
<% end %>
Then i click the link to change them
and here is the controller
def index
if params[:type]
#notifications = Notification.where(notification_type: params[:type])
else
#notifications = Notification.all
end
respond_to do |format|
format.html
format.js{
render 'notifications/jserb/select_notifications'
}
end
end
Which then arrives here:
$('.testing123').empty();
$("<%= escape_javascript(render #notifications, :locals => {:x => x}) %>").appendTo(".testing123");
But i keep getting this error
ActionView::Template::Error (undefined local variable or method x' for #<#<Class:0x007fae10882ed8>:0x007fae0f6234b8>):
EDIT-1: here is where i click the link:
<%= link_to "likes", notifications_path, remote: true %>
EDIT-2: here is the notification:
<div class="notification-body flerowspb" id="body<%=x.id%>">
<div class="flerowspb" style="width:80%">
<div class="notif-check flecolcen">
<%= check_box_tag "read_notif[]", value="#{x.id}", checked = false, options = {class: 'checked-id', id: "check-#{x.id}"} %>
</div>
<div class="notif-details ">
<div class="notif-time flerowspb">
<% if !x.viewed %>
<span class="glow" id="glow-<%=x.id%>"> New <%= x.notification_type.capitalize %></span>
<% else %>
<span><span class="text-grey"> New <%= x.notification_type.capitalize %></span></span>
<% end %>
<span class="text-grey font-small"> <%= time_ago_in_words(x.created_at) %> ago</span>
</div>
<div class="notif-body font-medium text-grey">
You have <%= x.status_count %> <%= x.title %> <br>
Click <span class="text-blue"><%= link_to "Here", entry_path(x.entry_id, notification_id: x.id) %> </span> to view it
</div>
</div>
</div>
<div class="notif-image">
<%= image_tag x.entry.image.small_thumb %>
</div>
</div>
EDIT-3: here is the full error that i get:
ActionView::Template::Error (undefined local variable or method `x' for #<#<Class:0x007fae0e6f32b8>:0x007fae11ac1838>):
1: <div class="notification-body flerowspb" id="body<%=x.id%>">
2: <div class="flerowspb" style="width:80%">
3: <div class="notif-check flecolcen">
4: <%= check_box_tag "read_notif[]", value="#{x.id}", checked = false, options = {class: 'checked-id', id: "check-#{x.id}"} %>
Any help will be appreciated

Issue with your code is after click on link it hits the notifications action and where you are getting #notifications as array of notifications, so after this in your js.erb you are rendering appending partial notification.html.erb with local variable x but here at your controller you are getting #notifications variable,
This should be like:
in notifications/_notification.html.erb
<div class="testing123">
<% notifications.each do |x| %>
<%#= render 'notification', x: x %>
#...
<% end %>
</div>
and in notification.js.erb
$('.testing123').empty();
$(".testing123").append("<%= escape_javascript(render 'notifications/notification', notifications: #notifications) %>");

Related

I am newbie in ruby on rails and trying to link into "changelog_settings.html.erb" page, but in the end, it redirect to different page

controller:
def add_changelog
changlog_alert= params[:program][:changlog_alert]
#program.update(changlog_alert: changlog_alert)
flash[:notice] = "Changelog Updated Successfully."
redirect_to portal_admins_changelog_settings_path(#enterprise, #program)
end
routes:
namespace :admins do
get "changelog_settings"
post "add_changelog"
end
changelog_settings.html.erb
<div class="large-12 small-12 columns settings_menu_content px-6 white_shadow p-5">
<%= render partial: "portal/admins/dashboard_settings/changelog" %>
</div>
_changelog.html.erb
<%= form_for #program, url: portal_admins_add_changelog_path(#enterprise, #program), method: :post do |f| %>
<%= f.text_area :changelog_alert, value: #program.changelog_alert, rows: "3" %>
<div style="text-align: right;">
<p id="limit" style="text-align: right;margin-top: -10px;color: gray;"> <%= #program.changelog_alert ? (300 - #program.changelog_alert.split(" ").count) : '300' %> Words Remaining </p>
<%= f.submit "Save Changes", class: "btn btn-blue" %>
</div>
<% end %>
Rake route
portal_admins_changelog_settings GET /app/:enterprise_id/:program_id/admins
changelog_settings(.:format) portal/admins#changelog_settings {:subdomain=>"portal"}
So mainly this _changelog.html.erb file trying to show and seems like route also fine but everytime it goes to different page

Button not calling a controller in ruby

I have a screen where a user can select differente kinds of plans for his account. Like this:
#plans
<% Plan.all.order(:amount).each do |plan| %>
<%= render 'shared/plan_detail', {plan: plan, button_text: 'Choose this' } %>
<% end %>
#plan_detail
<div class="plan-details">
<header class= <%= plan.css %> >
<h3><%= plan.name %></h3>
<small><%= plan.visibility %></small>
<p><%= plan.card_description.html_safe %></p>
<span class="plan-price"><sup>$</sup><%= plan.amount.to_s %></span>
</header>
<article>
<%= plan.features_description.html_safe %>
<%= link_to button_text, {:controller => "accounts", :action => "update_plan", :plan => plan.id }, title: button_text, :class=>"btn btn-md btn-block btn-outline-green dialog-open" %>
</article>
</div><!-- end plan details -->
And In my controller i have:
#accounts_controller.rb
def update_plan
#plan = Plan.find(params[:plan])
current_user.plan = #plan
current_user.save
end
My routes its like this
get '/account/plans', to: 'accounts#plans', as: :update_plan
put '/account/plans', to: 'accounts#update_plan'
But I click on the button, and nothing happens. What Im doing wrong here?
This is a long shot, but seeing that your link has dialog-open I wouldn't be surprised if there was some Javascript preventing your link from working. In order to debug this further I would
a) Check browser's Javascript console for any errors
b) Remove the dialog-open class to see what happens

Remote: true not working after submit via Jquery

Im submitting my form with checkboxes via Jquery with remote true but its not working. Its keeps rendering the html format in the controller and i can work out why.
Here is my submit button and form:
<%= button_to "Read sel", root_path, class: "btn btn-info btn-sm padlr", id: "notification-submit" %>
<%= form_tag read_selected_notifications_path, :authenticity_token => true, remote: true ,id: "notification-form" do %>
<% #notifications.each do |x| %>
<div class="notification-body flerowspb">
<div class="flerowspb" style="width:80%">
<div class="notif-check flecolcen">
<%= check_box_tag "read_notif[]", value="#{x.id}" %>
</div>
<div class="notif-details ">
<div class="notif-time flerowspb">
<% if !x.viewed %>
<span class="glow"> New <%= x.notification_type.capitalize %></span>
<% else %>
<span><span class="text-grey"> New <%= x.notification_type.capitalize %></span></span>
<% end %>
<span class="text-grey font-small"> <%= time_ago_in_words(x.created_at) %> ago</span>
</div>
<div class="notif-body font-medium text-grey">
<span class="text-blue"><%= link_to x.sender.username, profile_path(x.sender) %> </span> <%= x.title %> <br>
Click <span class="text-blue"><%= link_to "Here", entry_path(x.entry_id, notification_id: x.id) %> </span> to view it
</div>
</div>
</div>
<div class="notif-image">
<%= image_tag x.entry.image.small_thumb %>
</div>
</div>
<% end %>
<% end %>
So there is no actual submit button for the form as i want the button above the form not below it like this,
I understand i have to add :authenticity_token => true as rails doesnt add this to form_tag with remote: true
Here is my controller:
def read_selected
Notification.read_selected(current_user.id, params[:read_notif])
respond_to do |format|
format.html{
flash[:success] = "Selected notifications marked as read"
redirect_to notifications_path
}
format.js{
render 'notifications/jserb/read_selected'
}
end
end
Here is the js code:
$(document).on('turbolinks:load', function(){
if (window.location.href.match(/\/notifications/)) {
$('#notification-submit').on('click', function(e){
console.log('oisdjfilds');
e.preventDefault();
$('#notification-form').submit();
});
}
});
EDIT: I added in a submit button at the bottom of the form and it works as it should do, So it something to do with the way i'm submitting the form
I assume you're using Rails 5, since there is such an inconsistency in its behavior. Please, check out the issue
As far as I understand the quick solution for your problem is going to be:
Get the form HTML element:
form = document.getElementById('notification-form');
or
form = $('#notification-form')[0]
And then fire Rails submit:
Rails.fire(form, 'submit');
or
form.dispatchEvent(new Event('submit', {bubbles: true}));

Rails: 'Load More' button with Ajax & Kaminari

I would like to create a "load more" ajax pagination, with Kaminari.
I'm using this code :
class BienvenueController < ApplicationController
def index
#articles = Admin::Article.page(1).per(2)
respond_to do |format|
format.html
format.js
end
end
end
# Bienvenue#index
<div class="container" style="min-width:<%= #width %>px">
<%= render "shared/articles" %>
<%= link_to_next_page #articles, 'Load More', :remote => true, :id=>"load_more_link" %>
# Shared/articles
<% #articles.each do |a| %>
<article class="<%= a.rubrique.color %>">
<div class="sharing">
<%= image_tag "facebook-32.png" %>
</div>
<p class="color<%= a.rubrique.color %>"><i>Le <%= I18n.localize(a.created_at, :format => :long) %> par David Perrotin</i></p>
<h1><%= a.titre %></h1>
<div class="excerpt">
<%= a.chapo.html_safe %>
</div>
<div class="image">
<%= image_tag a.mainphoto.url(:medium), :width=>"100%" %>
</div>
<div class="contenu">
<%= a.contenu.html_safe %>
</div>
<div class="readmore">
<%= link_to "Continuer la lecture", article_path(a) %>
</div>
</article>
<% end %>
# index.js.erb
$('.container').append("<%= escape_javascript(render 'shared/articles')%>");
$('#load_more_link').replaceWith("<%= escape_javascript(link_to_next_page(#articles, 'Load More', :remote => true, :id=>'load_more_link'))%>");
But the problem is that when I click on "Load More", it always shows the two same articles, the partial is never refreshed with two more articles, like I would like.
I just ran into an issue with this that might help others. Depending on your version of jQuery, don't use replaceWith on the #load_more_link in index.js.erb.
There is a regression (http://bugs.jquery.com/ticket/13401) that an empty replaceWith does nothing, so on the very last page of your set, the link_to_next will be empty, making the line: $('#load_more_link').replaceWith(''); and thus will not replace the last "more" button, so you'll continually load the last page of your data set.
Fixed by updating jQuery version or use empty().html('...') instead of replaceWith.

Rails render partial with block

I'm trying to re-use an html component that i've written that provides panel styling. Something like:
<div class="v-panel">
<div class="v-panel-tr"></div>
<h3>Some Title</h3>
<div class="v-panel-c">
.. content goes here
</div>
<div class="v-panel-b"><div class="v-panel-br"></div><div class="v-panel-bl"></div></div>
</div>
So I see that render takes a block. I figured then I could do something like this:
# /shared/_panel.html.erb
<div class="v-panel">
<div class="v-panel-tr"></div>
<h3><%= title %></h3>
<div class="v-panel-c">
<%= yield %>
</div>
<div class="v-panel-b"><div class="v-panel-br"></div><div class="v-panel-bl"></div></div>
</div>
And I want to do something like:
#some html view
<%= render :partial => '/shared/panel', :locals =>{:title => "Some Title"} do %>
<p>Here is some content to be rendered inside the panel</p>
<% end %>
Unfortunately this doesn't work with this error:
ActionView::TemplateError (/Users/bradrobertson/Repos/VeloUltralite/source/trunk/app/views/sessions/new.html.erb:1: , unexpected tRPAREN
old_output_buffer = output_buffer;;#output_buffer = ''; __in_erb_template=true ; #output_buffer.concat(( render :partial => '/shared/panel', :locals => {:title => "Welcome"} do ).to_s)
on line #1 of app/views/sessions/new.html.erb:
1: <%= render :partial => '/shared/panel', :locals => {:title => "Welcome"} do -%>
...
So it doesn't like the = obviously with a block, but if I remove it, then it just doesn't output anything.
Does anyone know how to do what I'm trying to achieve here? I'd like to re-use this panel html in many places on my site.
While both of those answers above work (well the example that tony links to anyway) I ended up finding the most succinct answer in that above post (comment by Kornelis Sietsma)
I guess render :layout does exactly what I was looking for:
# Some View
<%= render :layout => '/shared/panel', :locals => {:title => 'some title'} do %>
<p>Here is some content</p>
<% end %>
combined with:
# /shared/_panel.html.erb
<div class="v-panel">
<div class="v-panel-tr"></div>
<h3><%= title -%></h3>
<div class="v-panel-c">
<%= yield %>
</div>
</div>
Here's an alternative based on previous answers.
Create your partial on shared/_modal.html.erb:
<div class="ui modal form">
<i class="close icon"></i>
<div class="header">
<%= heading %>
</div>
<div class="content">
<%= capture(&block) %>
</div>
<div class="actions">
<div class="ui negative button">Cancel</div>
<div class="ui positive button">Ok</div>
</div>
</div>
Define your method on application_helper.rb:
def modal_for(heading, &block)
render(
partial: 'shared/modal',
locals: { heading: heading, block: block }
)
end
Call it from any view:
<%= modal_for('My Title') do |t| %>
<p>Here is some content to be rendered inside the partial</p>
<% end %>
You can use the capture helper, and even inline in the render call :
<%= render 'my_partial',
:locals => { :title => "Some Title" },
:captured => capture { %>
<p>Here is some content to be rendered inside the partial</p>
<% } %>
and in shared/panel:
<h3><%= title %></h3>
<div class="my-outer-wrapper">
<%= captured %>
</div>
which will produce:
<h3>Some Title</h3>
<div class="my-outer-wrapper">
<p>Here is some content to be rendered inside the partial</p>
</div>
See http://api.rubyonrails.org/classes/ActionView/Helpers/CaptureHelper.html
Based on the accepted answer this is what worked well for me using Rails 4.
We can render a panel as such:
= render_panel('Non Compliance Reports', type: 'primary') do
%p your content goes here!
This requires a helper method and a shared view:
helper method (ui_helper.rb)
def render_panel(heading, options = {}, &block)
options.reverse_merge!(type: 'default')
options[:panel_classes] = ["panel-#{options[:type]}"]
render layout: '/ui/panel', locals: { heading: heading, options: options } do
capture(&block)
end
end
View (/ui/panel.html.haml)
.panel{ class: options[:panel_classes] }
.panel-heading= heading
.panel-body
= yield
I think it will work (just did quick dirty test) if you assign it to a variable first and then output it.
<% foo = render :partial => '/shared/panel', :locals =>{:title => "Some Title"} do %>
<p>Here is some content to be rendered inside the panel</p>
<% end %>
<%= foo %>

Resources