Rails: Ajax: Changes Onload - ruby-on-rails

I have a web layout of a for that looks something like this
<html>
<head>
</head>
<body>
<div id="posts">
<div id="post1" class="post" >
<!--stuff 1-->
</div>
<div id="post2" class="post" >
<!--stuff 1-->
</div>
<!-- 96 more posts -->
<div id="post99" class="post" >
<!--stuff 1-->
</div>
</div>
</body>
</html>
I would like to be able to load and render the page with a blank , and then have a function called when the page is loaded which goes in and load up the posts and updates the page dynamically.
In Rails, I tried using "link_to_remote" to update with all of the elements. I also tweaked the posts controller to render the collection of posts if it was an ajax request (request.xhr?). It worked fine and very fast. However the update of the blank div is triggered by clicking the link. I would like the same action to happen when the page is loaded so that I don't have to put in a link.
Is there a Rails Ajax helper or RJS function or something in Rails that I could use to trigger the loading of the "posts" after the page has loaded and rendered (without the posts)?
(If putsch comes to shove, I will just copy the generated JS code from the link_to_remote call and have it called from the onload handler on the body).

Sure there is, it's Rails, after all :)
Something like that will do:
<% javascript_tag do %>
$(document).ready(function() {
<%= remote_function(:update => "posts", :url => posts_partial_path) %>
});
<% end %>
remote_function will give you the same javascript that gets executed when you use rails ajax helpers.

Do this using jQuery unobtrusively like so:
$(document).ready(function(){
$.ajax({url: 'posts_partial_path',
success: function(data) {
$('#posts').html(data);
}
});
});
putting this code in a JavaScript file included by your page. You need to replace 'posts_partial_path' above with the actual URL string, Rails helpers are not available in the JavaScript code. Read about making AJAX calls with jQuery here: http://api.jquery.com/jQuery.ajax/ . Works like a champ.
Walter Gillett

Related

What does “yield” do?

What does yield do in ruby on rails?
<body data-spy="scroll" data-target=".sidebar">
<!-- Your timezone is <%= Time.zone %> -->
<!-- <%= "Ruby Version is #{RUBY_VERSION}" if Rails.env =~ /test|development/ %> -->
<%= render partial:'shared/account_status' %>
<%= render partial:"shared/session_timeout" %>
<div class="container">
<%= render partial:"shared/branding" %>
<%= render partial:"shared/nav", locals:{icons:icons, actionable_urls:actionable_urls, top_level_items:MenuItem.top_level_items_with_access_rights_for_user(current_user).sort{|a, b| a.sequence <=> b.sequence}, current_item:current_navigation_item} %>
<div style="clear:both"></div>
<div id="content">
<%= render partial:"shared/flash", object:flash %>
<%= yield %>
</div>
</div>
<%= render partial:"shared/ldap_user_menu" if signed_in_as_ldap_user? %>
</body>
It tells Rails to put your view content to this block (which is called by yield) at that place in the layout file.
Checkout the rails guide to learn more about the ActionView.
https://guides.rubyonrails.org/action_view_overview.html
As pointed out by #Aleksei Matiushkin, yield is pure ruby, so you should also learn more about that in your own time.
Here's a (my) visual presentation to explain what happened on that line:
view.html.erb:
<p>Hello there!</p>
<p>I'm a content from view</p>
layout.html.erb:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<%= yield %>
</body>
</html>
Now the results will be like this:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<p>Hello there!</p>
<p>I'm a content from view</p>
</body>
</html>
Your question is not specific enough. In Rails, as with ordinary Ruby, yield used within a method definition represents the block that is passed to a method.
However, judging from the code block that you gave, you seem to particularly want to ask about yield used in layouts of a view in Rails. In such case, it represents the main content described in the view file that is to be rendered in the context. For example, when the controller is Foo, and the action is bar, then, yield used within a layout to be used in such context will be replaced by the content of /app/views/foo/bar.html (or whatever corresponding view file in other format).
It must be simple in your concept: yield is where put content block (html) from action view to layout template
example: action index render index.html, the result will be put/filled in the yield
I haven't seen render mentioned in the other answers, so I'd like to add to #vipibano's answer, that if you want to understand how this yield business works in Rails (and more specifically in the application.html.erb), you'll benefit from:
understanding how blocks work in Ruby (as mentioned by others)
understanding what Rails' render method does
The render method is called at the end of a controller action and orchestrates what block is passed to the method that is actually rendering the application.html.erb.
I've tried to visualize this a bit and there a few examples if you want to dig deeper in the according post:
https://richstone.io/debunk/

Trying to understand Rails ajax js code

Ive been trying to work out how to prepend a comment once its been created via Ajax, I added remote true to the form. Inserted the block in the controller but then it got the js file where i prepended the new comment. I couldn't figure it out. I came across this code on SO and quickly gave it a shot and it worked. But i cant work out why/how?
This is the code: JS file,
$("<%= escape_javascript(render #message) %>").prependTo(".view-messages");
Here is the div to which it is prepended
<div class="view-messages">
<%= nested_messages #messages.arrange(:order => :created_at) %>
</div>
Its this line here $("<%= escape_javascript(render #message) %>") Ive tried debugging it but cant,
What is that printing out, is it one of these rails magic things or am i being stupid?
Although it works i like to know why and how so if anyone can help me out me id be grateful.
Thanks
EDIT:
$("<div class=\"body body-144\">\n <span class=\"tip tip-left\"><\/span>\n <div class=\"message font-medium\">\n ellll <br />\n <\/div>\n <div class=\"flerowspb\">\n <span class=\"font-small\">\n <a href=\"/profiles/122\">Nyall2911(28)<\/a>\n <\/span>\n <span class=\"font-small\">\n <a href=\"/messages/new?entry_id=344&parent_id=144\">Reply<\/a>\n <a rel=\"nofollow\" data-method=\"delete\" href=\"/messages/144\">| Delete<\/a>\n <\/span>\n <\/div>\n<\/div>\n")
This is what its rendering, So i suppose my question is, how is rails getting all of the HTML from my comment partial by just calling (render #message)
Here's the escape_javascript method: https://github.com/rails/rails/blob/55f9b8129a50206513264824abb44088230793c2/actionview/lib/action_view/helpers/javascript_helper.rb#L25
Per the comment below the method, it looks like it replaces a few unsafe characters and returns raw HTML using the html_safe method. jQuery then prepends that raw HTML to your div.

AngularJS ng-change does not work when get request with Ruby on Rails 5

I'm using ...
Ruby on Rails 5
AngularJS 1.3.20
Chrome or FireFox Browser
It seems ng-change event does not work, when I request get method like link from other page. But when I user POST request to next page, it works.
When I change select box value, onchange event is not happen. I expect ng-change
should reach changeHandler function in sample.js and console.log("ChangeHandler!!!") show up.
In addition, I use Ruby on Rails application template. So ng-app and ng-controller is same as index1.html and index2.html.
** Additional Info
I tried Chrome ng-inspector for AngularJS Tool. But There is no angular panel shown up. But once reload same page, it shows up. What happend?
index1.html.erb
<html lang="ja" ng-app="MyApp">
<body ng-controller="MyController">
<!-- For GET Method Request -->
<div>
<%= link_to 'Index2', sample_index2_path %>
</div>
<!-- For POST Method Request -->
<div>
<%= form_tag sample_index2_path do %>
<%= button_tag "Click" %>
<% end %>
</div>
</body>
</html>
index2.html.erb
<html lang="ja" ng-app="MyApp">
<body ng-controller="MyController">
<div>
<form>
<select id="eventTest" ng-model="eventTest" ng-change="changeHandler()">
<option value="1">AAA</option>
<option value="2">BBB</option>
<option value="3">CCC</option>
</select>
</form>
</div>
</body>
</html>
sample.js
angular.module('MyApp',[])
.controller("MyController", ['$scope', function($scope) {
$scope.eventTest;
$scope.changeHandler = function () {
console.log("ChangeHandler!!!");
};
}]);
This works only POST, or Get and reload Browser.
There are any difference between output HTML source code GET and POST.
I'm stack over 3 days.
Please let me know and advice for me.
The reason why Angular Module does not work properly was JavaScript lib turbolinks.
I fixed this by modifying default setting reload -> false, or erasing data-turbolinks-track.
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
                                  ↓↓↓↓
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'false' %>

Dynamically add tabs content in mobile page

I use $('#tab-content').load('/embed_tab.html'); to load below page, the output is in bullet point instead of tabs? This is the page I load when I click something on parent page. How can I solve the problem.
Script
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.2/jquery.mobile-1.4.2.min.css">
is loaded from the head.
<div data-role="tabs" id="detail-tabs">
<div data-role="navbar">
<ul>
<li>Selling Point</li>
<li>Terms of Use</li>
</ul>
</div>
<div id="sellpoint" class="ui-body-d ui-content">
<h1>Selling Point</h1>
</div>
<div id="terms">
<h1>Terms of Use</h1>
</div>
</div>
I assume you are also loading the jQM javascript as well as the css.
After the $('#tab-content').load('/embed_tab.html'); is finished, you have to initialize the tabs widget to cause it to be enhanced. So once the load is complete, try calling something like:
$('#tab-content').enhanceWithin();
or
$('#tab-content [data-role="tabs"]').tabs();
EDIT: to call these after the load is complete, use the complete callback function of the load method:
$('#tab-content').load('/embed_tab.html', function() {
$('#tab-content').enhanceWithin();
});
API DOC: http://api.jquery.com/load/

Remove Rails partial from view

My Rails app uses partials to load different pieces of the site into view. I'd like to add a close icon that removes the partial from view when clicked. Example: The user opens a folder in the app, and clicks an icon to "close" the folder. Is this possible?
Ok quick solution with jquery:
_partial.html.erb
<div id="unique">
<p>Html code here</p>
</div>
View.html.erb
<%= render :partial => 'partial' %>
<script type="text/javascript">
window.onload = function () {
$('#unique').remove()
}
</script>
removing the DOM node with jquery .remove()
http://api.jquery.com/remove/

Resources