I want to do load data with load more button. I have implemented like this in posts/index.html.erb:
<div id="posts">
<h1>Posts</h1>
<%= render #posts %>
</div>
<div class="load-more-container">
<%= link_to "Load More", posts_index_path, class: "load-more" %>
</div>
Then _post.html.erb:
<div class="post">
<h2><%= post.title %></h2>
<p><%= post.body %></p>
</div>
Then index.js.erb:
$('#posts').append('<%= escape_javascript render(#posts) %>');
In posts_controller I wrote like this:
##count=2
def index
if params[:id]
#posts = Post.where('id < ?', params[:id])
else
#posts = Post.limit(##count)
end
##count+=2
respond_to do |format|
format.html
format.js
end
end
Then in application.js:
$(document).ready(function () {
$('a.load-more').click(function (e) {
e.preventDefault();
$.ajax({
type: "GET",
url: $(this).attr('href'),
dataType: "script",
success: function () {
$('.load-more').show();
}
});
});
});
I am getting first 2 data:
Post1
Post2
load more
when clicking on load more I am getting like this:
Post1
Post2
Post1
Post2
Post3
Post4
but I want only:
Post1
Post2
Post3
Post4
Could anyone please help me. Thanks in advance.
Since you are fetching all records everytime click on loadmore button, Dont append result and overwrite with html
$('#posts').html('<%= escape_javascript render(#posts) %>');
In your controller, you replace
#posts = Post.limit(##count) => #posts = Post.limit(2).offset(##count - 2)
if you want load more 2 artices.
Related
I am looking for solution for infinite scroll with Kaminari in my project, but it still does not work as expected.
In my home page have view for render post:
<div class="home_post_tab_content">
<%if #posts.present?%>
<div id="home_post_infinite_scroll">
<%= render #posts %>
</div>
<%if #posts.total_count > 10%>
<div class="home_post_pagination_button" id="home_post_pagination">
<%= link_to_next_page(#posts, 'Xem thêm', :remote => true) %>
</div>
<%end%>
<%end%>
</div>
Controller:
respond_to do |format|
format.html {}
format.js
end
Script file:
// Append new data
$("<%=j render #posts %>").appendTo($("#home_post_infinite_scroll"));
// Update pagination link
<% if #posts.last_page? %>
$('#home_post_pagination').remove();
<% else %>
$('#home_post_pagination').html("<%=j link_to_next_page(#posts, 'See more', :remote => true) %>");
<% end %>
Q: How can I trigger the next button when user scrolls in end of page (jquery or JS...)?
Or, If any one has another solution for infinite scroll please let me know. Thanks so much!
I found the solution for resolve it:
<script>
$(document).on('turbolinks:load', function() {
$(window).scroll(function() {
var next_url = $("#home_post_pagination a[rel='next']").attr('href');
if (next_url && ($(window).scrollTop() > ($(document).height() - $(window).height() - 5000))) {
$('#home_post_pagination').show();
$('#home_post_pagination').html('<a>Loading...</a>');
$.getScript(next_url);
return;
}
});
return $(window).scroll();
});
</script>
The $.getScript(next_url) will be trigger next button on scroll
I want to get the save function in the Mercury editor working but to no avail.
I have a model to save the page, title and content.
mercury.js:
$(window).bind('mercury:ready', function() {
var link = $('#mercury_iframe').contents().find('#edit_link');
Mercury.saveURL = link.data('save-url');
link.hide();
});
$(window).bind('mercury:saved', function() {
window.location = window.location.href.replace(/\/editor\//i, '/');
});
static_pages_controller.rb:
def update
#static_page = StaticPage.find(params[:id])
#static_page.page = params[:page]
#static_page.title = params[:content][:aboutContainer][:value][:about_title][:value]
#static_page.content = params[:content][:aboutContainer][:value][:about_content][:value]
#static_page.save!
render plain: ''
end
about.html.erb:
<% provide(:title, 'About') %>
<div class="container" id="aboutContainer" data-mercury="full">
<h1 id="about_title"><%= raw #static_page.title %></h1>
<div class="col-sm-12">
<p id="description about_content"><%= raw #static_page.content %></p>
</div>
<p><%= link_to "Edit Page", "/editor" + request.path, id: "edit_link",
data: {save_url: static_page_update_path(#static_page)} %></p>
</div>
Ok, so i basically realised that I needed a show action so I can grab records from the model and save to the #static_page object
I was following this guide: http://railscasts.com/episodes/296-mercury-editor?autoplay=true
Please note I had to change my routes to using those in the link (or similar routes to them) and had to place them before the default mercury routes and had to change:
#static_page.title = params[:content][:aboutContainer][:value][:about_title][:value]
#static_page.content = params[:content][:aboutContainer][:value][:about_content][:value]
to:
#static_page.title = params[:content][:about_title][:value]
#static_page.content = params[:content][:about_content][:value]
I then removed the class 'container' div in about.html.erb and moved all the code to show.html.erb not needing about.html.erb.
I'm currently learning rails and working on what I'm sure is everyone's first rails app, a simple todo list. I need to implement a checkbox next to the items to indicate whether they are complete or not. Each item has a boolean attribute called "completed" in their model. I have found a couple checkbox questions while searching but none explain the syntax very easily in the context of the index view.
Also, I really want the checkbox to work without a submit button. I know I could accomplish something like this using AngularJS's ng-model but I don't think it would be practical to implement angular for such a small thing and I don't know how angular works with rails.
If anyone could give me a pointer in the right direction, it would be greatly appreciated. Here's my index.html.erb for reference.
<h1>
To Do List
</h1>
<table>
<tr>
<% #todo_items.each do |item| %>
<!-- Checkbox here -->
<tc style="<%= 'text-decoration: line-through' if item.completed %>">
<%= link_to item.title, item %>
</tc>
<tc>
<%= item.description %>
</tc>
<tc>
<%= link_to "Edit", edit_todo_item_path(item) %>
</tc>
<tc>
<%= link_to "Delete",item, data:{:confirm => "Are you sure you want to delete this item?"}, :method => :delete %>
</tc>
<hr/>
<% end %>
</tr>
</table>
<p>
<%= link_to "Add Item", new_todo_item_path %>
</p>
This is my way, I don't know this way is right direction or not but this works for me (also different case but same of concept).
views for checkbox
You could put an id item or something into attribute of checkbox for find an object in controller if you send data to controller for get record of object, and you could define if attribute completed of record is true or false:
<%= check_box_tag :completed_item, 1, item.completed? ? true : false, { class: 'name-of-class', data: { id: item.id} } %>
controller
You need two action call set_completed and remove_completed, and also you don't need templates for them, just use format as json:
before_action :set_item, only [:set_completed, :remove_completed, :other_action]
def set_completed
#item.set_completed!
respond_to do |format|
format.json { render :json => { :success => true } }
end
end
def remove_completed
#item.remove_completed!
respond_to do |format|
format.json { render :json => { :success => true } }
end
end
private
def set_item
#item = Item.find params[:id]
end
Model
For set_completed! and remove_completed! you could define in your model
def set_default!
self.update_attributes(:completed => true)
end
def remove_default!
self.update_attributes(:completed => false)
end
routes
resources :address do
collection do
post 'set_completed'
post 'remove_completed'
end
end
Also, you need help JavaScript for handle send request from view to controller event click of checkbox:
jQuery
$(".completed_item").click(function(){
var check = $(this).is(":checked");
if (check == true){
set_completed($(this).attr('data-id'));
} else{
remove_completed($(this).attr('data-id'));
}
});
function set_completed(data_id) {
$.ajax({
type: 'POST',
url: "/items/set_completed",
data: { id: data_id},
dataType: 'json',
success: function(response){
if(response){
}else{
alert('error');
}
}
})
}
function remove_compelted(data_id) {
$.ajax({
type: 'POST',
url: "/items/set_completed",
data: { id: data_id},
dataType: 'json',
success: function(response){
if(response){
}else{
alert('error');
}
}
})
}
In Category view I have:
<ul>
<% #category.subcategories.each do |subcategory| %>
<li>
<h6>
<%if subcategory.has_topic_headings? %>
<%= link_to subcategory.name, { controller: 'subcategories',
action: 'show_topic_headings',
category_id: subcategory.category_id,
id: subcategory.id
}, data: 'topic_heading_link',
remote: true %>
<% else %>
<%= link_to subcategory.name, subcategory %>
<% end %>
</h6>
<hr>
</li>
<% end %>
</ul>
In application.js:
/* slides in the subcategory menu or the content */
$('.category-menu a').on(
'click',
function(e) {
if ($(this).attr('data')) {
/* make submenu visible */
$('.stretched.nav.row > .slider').animate({left:'-62.5em'});
e.preventDefault();
}
else {
/* make content visible */
$('.stretched.main.row > .slider').animate({left:'-62.5em'});
e.preventDefault();
}
}
);
In subcategories_controller.rb
def show_topic_headings
respond_to :js
#subcategory = Subcategory.find(params[:id])
end
And in subcategories/show_topic_heading I have:
$('.subcategory-menu').html( "<%= escape_javascript( render( partial: "layouts/topic_headings", locals: { subcategory: #subcategory} ) ) %>" );
Clicking on the active link, .subcategory-menu should be populated with the correct content and the div containing should slide in. But the content only appears if it's static (for example, if I put a string instead of a reference to #subcategory). Please note that the view in which I am inserting the subcategory partial is a category view.
The problem lies in the subcategories_controller:
respond_to, not the function itself, generates the partial. Therefore the instance variable needs to be declared before calling respond_to
def show_topic_headings
#subcategory = Subcategory.find(params[:id])
respond_to :js
end
In background, I want it to reload and shows the number how many unread messages are there.
I want that without refreshing page. I mean using ajax.
If I had this in menu, how can I refresh only this section every 30 secs?
<li><%= link_to sanitize('<i class="icon-envelope"></i> ') + "received messages" + sanitize(' <span class="badge badge-info">'+current_user.mailbox.inbox(:read => false).count(:id, :distinct => true).to_s+'</span>'), messages_received_path %></li>
messages_controller.rb
def received
if params[:search]
#messages = current_user.mailbox.inbox.search_messages(#search).page(params[:page]).per(10)
else
#messages = current_user.mailbox.inbox.page(params[:page]).per(10)
end
add_crumb 'Messages Received', messages_received_path
#box = 'inbox'
render :index
end
UPDATE:_______________________________
assets/javascript/refresh_messages_count.js
$(document).ready(function () {
// will call refreshPartial every 3 seconds
setInterval(refreshPartial, 3000)
});
function refreshPartial() {
$.ajax({
url: "messages/refresh_part";
})
}
messages_controller.rb
def refresh_part
#message_count = current_user.mailbox.inbox(:read => false).count(:id, :distinct => true)
# get whatever data you need to a variable named #data
respond_to do |format|
format.js {render :action=>"refresh_part.js"}
end
end
views/layouts/_menu.html.erb
<span id="message_received_count"><%= render :partial => "layouts/message_received_count" %></span>
views/layouts/_message_received_count.html.erb
<% if user_signed_in? && current_user.mailbox.inbox(:read => false).count(:id, :distinct => true) > 0 %>
<li><%= link_to sanitize('<i class="icon-envelope"></i> ') + "Received" + sanitize(' <span class="badge badge-info">'+#message_count.to_s+'</span>'), messages_received_path %></li>
<% else %>
<li><%= link_to sanitize('<i class="icon-envelope"></i> ') + "Received", messages_received_path %></li>
<% end %>
views/messages/refresh_part.js.erb
$('#message_received_count').html("#{escape_javascript(render 'layouts/messages_received_count', data: #message_count)}");
You will use setInterval to send the ajax request:
$(document).ready(function () {
// will call refreshPartial every 3 seconds
setInterval(refreshPartial, 3000)
});
// calls action refreshing the partial
function refreshPartial() {
$.ajax({
url: "whatever_controller/refresh_part"
})
}
Then you make an action in a controller like this:
def refresh_part
# get whatever data you need to a variable named #data
respond_to do |format|
format.js
end
end
then you will write a js file named refresh_part.js.haml (you could erb instead of haml).
refresh_part.js.haml would look like this:
$('#part_you_want_to_refresh').html("#{escape_javascript(render 'name_of_partial', data: #data)}");
make sure you set the correct routes in routes.rb.
FYI, refresh_part.js.erb would look like this:
$("#part").html("<%= escape_javascript(render 'partial', data: #data) %>");
instead of:
$('#part').html("#{escape_javascript(render 'partial', data: #data)}");
also, we can use the alias of "escape_javascript" to simplify this:
$("#part").html("<%= j(render 'partial', data: #data) %>");
Yes you can
<html>
<head>
<script type="text/JavaScript">
<!--
function timedRefresh(timeoutPeriod) {
setTimeout("location.reload(true);",timeoutPeriod);
}
// -->
</script>
</head>
<body onload="JavaScript:timedRefresh(5000);">
<p>This page will refresh every 5 seconds. This is because we're using the 'onload' event to call our function. We are passing in the value '5000', which equals 5 seconds.</p>
<p>But hey, try not to annoy your users too much with unnecessary page refreshes every few seconds!</p>
</body>
</html>
Source: http://www.quackit.com/javascript/javascript_refresh_page.cfm