How can I add content dynamically in rails? - ruby-on-rails

I have controller with a page named list.html.erb
when a user clicks a link I want to append content dynamically to the page and execute javascript afterwards.
is it possible to have a method which renders a js.erb file and I put into this file the variables containing the content?
best phil

As described there: http://api.rubyonrails.org/classes/ActionView/Helpers/UrlHelper.html#method-i-link_to you need to use
link_to 'Something', 'somewhere', remote: true

Yes, of course. It may not be the best course of action, though.
If you're enhancing the functionality of the view through Javascript, it's probably better to keep the code in Javascript rather than Ruby-generated Javascript.
Make a simple HTML link that GETs the new content from a controller in the JSON format or even as an HTML snippet. Use something like $.ajax and its success callback function to append said response to the element in the page.
$.ajax({
url: "whatever/here",
type: "GET",
data_type: "json",
success: function(response) {
$("#element_in_question").append(response); //if HTML; if JSON, parse and build the HTML
},
error: function(xhr, status, message) {
//indicate failure somehow
}
});

You can include a partial in your list.html.erb and display the partial on changing some content on the page list.html.erb. For example considering your list.html.erb file, you can include the following in your page
<form_for :something, :remote => true, :method => get :url => {:action => "partial"} do |f| %>
//write your code here
<%=f.submit%> //here you can have :onchange in the form_for tag if you do not want a submit button
write a division for partial in your list page as below
<div id="partial">
</div>
write a partial.js.erb file like this:
$('#partial').html("<%=j render "partial" %>");
create a _partial.html.erb file with the content you want to add the list.html.erb dynamically.
in the controller, add the following code:
def partial
//write your code here
respond_to do |format|
format.js
end
This will display the added content in the div tag of your list page with div id "partial"

Related

Rails is rendering an empty partial from js.erb

I'm trying to render a partial from a js.erb file but nothing is shown in the view.
There is an AJAX call that triggers the report_announcement action in the announcements_controller when a button is pressed.
reports.js
$.ajax({
type: "POST",
contentType: "application/json",
url: "/announcements/report_announcement.js",
data: json_data
});
reports/_report_content.html.erb
<div id="report_announcements_container"></div>
announcements_controller.rb
def report_announcement
#announcement = Announcement.new(announcement_params)
respond_to do |format|
if #announcement.save
format.js {}
end
end
end
announcements/report_announcement.js.erb
I know that announcements/report_announcement.js.erb is rendering ok because I can see the logging statement in the console and also in the development.log as well as the report_announcement object being logged to the console.
<% announcement_json = #announcement.to_json.html_safe %>
var report_announcement = <%= announcement_json %>;
console.log('report_announcement');
console.log(report_announcement);
// this is where something is not right I think
$("#report_announcements_container").html("<%= escape_javascript(render partial: 'announcements/report_announcements', locals: { announcement: #announcement }) %>");
console.log('inside announcements....');
announcements/report_announcements.html.erb
This is where I'm having an issue because the logging statement for the partial is shown however nothing from the partial is shown on the page. I see in the development.log that the page rendered but nothing is actually shown in the view. The partial is not showing on the page in the report_announcements_container div.
<h1>test</h1>
<%= announcement %>
<script>
console.log('inside partial...');
</script>
You're using the wrong content-type in your ajax call. Rails recognizes both application/javascript and text/javascript as the :js format.
Also when you request a js format you actually have to execute the returned javascript for anything to happen in the client.
$.ajax({
type: "POST",
contentType: "application/javascript",
url: "/announcements/report_announcement.js",
data: json_data
}).done(function(data){
jQuery.globalEval(data); // Yeah eval is evil.
});
If you have done any "real" ajax calls before this will seem completely backwards - thats because it is. js.erb is a poor mans ajax framework for the javascript impaired which consists of a bunch of routes and views that mutate the DOM in the client.
Manually creating calls for a js.erb template is just a silly excerise in masocism. If you really want to use it create a form and use it send the request instead so that you can just leverage the javascript handlers that rails provide:
<%= form_with(url: "/announcements/report_announcement", remote: true) do |f| %>
# ...
<% end %>

how to send remote form params

I have a form which is using several input fields being ajaxified with remote: true and custom controller actions. This way UJS driver sends only given form input as params. What I want to accomplish is an ajaxified input field which will send value of a field outside of it's "scope" as params. What do you suggest?
Let me explain the whole flow of the ajax-rails and remote=> true and you can do this with that following way and you can get all the params in your method.
first when you used the remote=> true then the form will submit or call the action which you have define in form like here is an example:
<%= form_tag({:controller => 'my', :action => 'my_data'},:id => 'filter_form', :remote => true) do %>
#code here
<%= submit_tag 'save', :name => 'commit'%>
<%end%>
now above code will go to my_data action in my controller,
here you can define the respone type with
def my_data
#actions on data here
respond_to do |format|
format.js
end
now you have to made a .js file with named as action name....
my_data.js.erb
here the whole affect of form you can write and update document element through jquery and javascript.
For every input you just assign a class and write a method that call when the input box will change.One more thing that when you wants to do in a single method the every input have a unique ID, send that also in params and do task what ever you wants to do.
Rails' JQuery UJS is just a dependency which Rails uses to call ajax requests on your behalf. This means your question is not particularly to do with JQuery UJS, but with how to handle it with ajax overall
You'll typically handle any extra data by appending it to the Ajax request:
<%= link_to "Link", new_post_path(params: "here"), remote: true %>
If you want to create an "ajaxified" field, you'll probably have to use a manual ajax call to capture the change event, allowing you to send the data to your event:
#app/assets/javascripts/application.js
$('input[name="element"]').on("change", function(){
$.ajax({
url: "url",
data: $(this).serialize()
});
});
Then, as mentioned by #baharat Soni, you'll be able to handle the request on the server using respond_to

Pass js variable to server code

I have a form with 2 inputs and button. An user put feed url in the first input and press the button:
<%= link_to "get name", { :controller => 'Feeds', :action => "get_title" },
:remote => true, :class=>'btn btn-mini' %>
Here is controller method
def get_title
respond_to do | format |
format.js {render :layout => false}
end
end
And here is a get_title.js.erb:
var url = $( "#feed_url" ).val();
console.log(url);
$( "#feed_name" ).val("<%= #proxy.title(url) %>");
I get value of the first input and want to pass it as parameter to Ruby class. But in this case I get the error:
ActionView::Template::Error (undefined local variable or method `url' for #<#<Class:0x41ec170>:0x41ef968>):
1: var url = $( "#feed_url" ).val();
2: console.log(url);
3: $( "#feed_name" ).val("<%= #proxy.title(url) %>");
Rails this that 'url' is a Ruby variable, but not JS one.
How can I pass JS variable to Ruby code ?
Thanks in advance.
Remember that any ERB (ruby) code is executed server side, while Javascript is, of course, rendered client side. As a result, your line <%= #proxy.title(url) %> is rendered WAY before that url value is ever evaluated. The solution to your situation is more along the lines of passing data to Rails, and rendering the response. Three things to facilitate this (bearing in mind that this is only one approach, and I'm sure there are plenty of others, and possibly better ways of doing this):
1- Your link_to won't post the user-input URL value because it is not POSTing the form. Instead, change the surrounding form to use :remote=true, and use a typical form.submit button rather than this link. Your form with the URL value will be submitted (and it will be asynchronous).
2- In your controller, render your title like you were trying to do, doing something along these lines:
def get_title
render :text=>#proxy.title(params[:url])
end
3- Bind to the ajax:success event, something along these lines:
$("form#myForm").bind("ajax:success", function(event, data, status, xhr){
$( "#feed_name" ).val(data) // data, in this case, is the rendered `#proxy.title(url)` we did in step 2.
})
Hope that makes sense. Let me know if it does not.

embed ruby in coffeescript? to render a partial on ajax success and append to body

My view has a link (remote: true) to the "new" action in the controller (HTTP "GET"), which responds with some data in JSON format...
I want to use AJAX and have my coffeescript file append a rendered partial on AJAX success...
here is the code:
$ ->
$('a').click (e) ->
e.preventDefault()
url = $(this).attr('href')
$.ajax
type: 'get'
url: url
dataType: 'json'
success: (json) ->
# I want to do something like this:
$('body').append(render :partial => "questionForm", :locals => {:q_id => json.q_id})
This is obviously not the correct syntax... is it possible to embed ruby into my js.coffee somehow? I've checked through everything else, and if I just do something like :
$('body').append(json.q_id)
it works - so the AJAX call and "new" action etc. all seem to be working.. Any ideas? Is it possible to do something like this?
If you're returning data from the server, then you probably want to use a client-side tempting system (handlebars, jquery-templates, eco) to take the json data and turn it into HTML.
If you want the server to render the HTML for you, then you can have the server render the HTML and use jquery to append it.
Something like:
<%= link_to "New Model", new_models_path, remote: true, id: "batman" %>
Then in your app/models/new.js.erb, you'd:
$("#batman").html("<%= escape_javascript(render partial: "models/form", locals: {model: #model})%>");

Search with AJAX working, good! How to display results correctly?

I followed this tutorial to add AJAX to my Rails3.1 search box(everything works fine). This search box in in a side bar, and I want to display the results in the main column. The problem I encounter is that I don't know how to this properly.
Before AJAX I had a search.html.haml with the code to display the results. However, if I add the render partial call here nothing get displayed(I guess is because the search.html.haml does not get called)
search.html.haml
=#events.count
#search=render 'search'
On the other hand, if I place the render partial call in the application.html.haml. It does display the results, but underneath the actual content of the main column.
application.html.haml
#central
%p#notice= notice
= yield
#search=render 'search'
I guess it is a simple fix, but not sure how to do it.
Thanks in advance!!!
_search.html.haml
-#events.each do |event|
#user_block
#user_block_pic
= image_tag(event.pic.url(:medium), class: 'event_block_image', :alt =>'Event Picture')
....more stuff
search.js.erb
$('#search').html("<%= escape_javascript( render(:partial => 'search') ) %>");
How can I do to get rid of what is on the main column(#central) and display the results in there?
FIXED!!!! NOW WORKING!!!! (since I have to wait hours to be allowed to post an answer I do it here)
I am not sure this is correct coding but worked for me. What I did is to get rid of the middle file search.html.haml(see above)
And now the configuration is this:
application.html.haml
#central
%p#notice= notice
= yield
_search.html.haml
#search
=#events.count
-#events.each do |event|
...stuff
assets/javascript/search.js
$(function(){
$("#search .pagination a").live("click", function(){ #this is for pagination
$.getScript(this.href);
return false;
});
$('#events_search').submit(function () { #this is for the search form
$.get(this.action, $(this).serialize(), null, 'script');
return false;
});
});
views/events/search.js.erb
$('#central').html("<%= escape_javascript( render(:partial => 'search') ) %>");
It works fine for me. Hope this can help others.
Thanks
When you search method gets called from the ajax call it wants to render search.js.erb or haml I guess, but I don't use haml, only erb.
So then you create a search.js.erb, here is an example of my search.js.erb:
$("#user-browser").replaceWith("<%= escape_javascript render(:partial => 'list') %>");
$("#tabs-interval").replaceWith("<%= escape_javascript render(:partial => 'tabs-interval') %>");
So all my erb does is use jquery to find the div's I want to update the html in, using the rendered partials and replaces the html in them.
My partials look like so in erb:
file: list.html.erb:
<div id="user-browser">
<span>more html stuff</span>
</div>
file: tabs-interval.html.erb:
<div id="tabs-interval">
<span>more html stuff</span>
</div>

Resources