Yet another endless page dilemma - javascript

I am trying to implement an endless page setup for my page. I've been trying a lot of different methods for two days now but can't seem to get it to work. I liked the proposed setup from this blogpost but I can't seem to get it to work: http://pedromtavares.wordpress.com/2011/05/08/endless-page-scrolling-with-rails-3-and-jquery/
I also tried Ryan Bates screencast but didn't manage to implement it...
I tried the following:
Installed plugin
rails plugin install git://github.com/pedromtavares/endless_scroll_example.git
Modified my controller home:
def index
last = params[:last].blank? ? Time.now + 1.second : Time.parse(params[:last])
#feeds = Feed.input(last)
end
Modified my "Feed-model" with the new method 'input':
def self.input(last)
self.where("created_at < ? ", last).order('created_at desc').limit(5)
end
Modified my index
<% content_for :scripts do %>
<%= javascript_include_tag 'endless' %>
<% end %>
<%unless #feeds.blank?%>
<ul class='list' last="<%=#feeds.to_a.last.created_at%>">
<%= render :partial => 'feeds', :collection => #feeds%>
<div id='infinite-scroll'></div>
</ul>
<%end%>
My partial _feeds.html.erb looks like this (just filling out text :):
<%=feeds.title%>
jfjh
</p>
<p>
jfjh
</p>
<p>
jfjh
</p>
<p>
jfjh
</p>
<p>
jfjh
</p>
<br>
<hr>
Added my new javascript (endless.js) courtesy of pedromtavares
$('ul').endlessScroll({
fireOnce: true,
fireDelay: 500,
ceaseFire: function(){
return $('#infinite-scroll').length ? false : true;
},
callback: function(){
$.ajax({
url: '/home',
data: {
last: $(this).attr('last')
},
dataType: 'script'
});
}
});
My final javascript file looks like this:
<% unless #feeds.blank? %>
$('.endless_scroll_inner_wrap').append("<%=escape_javascript(render :partial => 'feeds', :collection => #feeds)%>");
$('ul').attr('last', '<%=#feeds.to_a.last.created_at%>')
<% else %>
$('#infinite-scroll').detach();
<% end %>
I don't get any errors but no infinite scroll either. I get the first posts from the array but not the rest. Can't figure out what I am doing wrong and it feels like I've tried everything by now... Please help!

Had a similar problem myself. My issue was that my append in my javascript could not find the proper div. Might work for you -
In your javascript file, change:
$('.endless_scroll_inner_wrap').append...
to:
$('#infinite-scroll').append...
and see if that fixes it.

Related

how to make collection_select value as link_to variable

I have the ff:
app/views/reports/index.html.erb
<h1>Reports</h1>
<br>
<legend>Categories</legend>
<div class="row">
<div class="span5">
<ol>
<li><%= link_to 'COMMENDATION', commendations_path(format: 'pdf'), { id: 'commendations_click' } %></li>
<%= collection_select(nil,
:employee_id,
#employees,
:id,
:last_name,
{:prompt => "Select an Employee"},
{:id => 'employees_select'}) %>
<br>
<%= collection_select(nil,
:employee_movement_id,
#employeemovements,
:id,
:position,
{:prompt => "-"},
{:id => 'employee_movements_select'}) %>
<li><%= link_to 'REPORT2', '#' %></li>
<li><%= link_to 'REPORT3', '#' %></li>
</ol>
</div>
</div>
<script type="text/javascript">
$(document).ready(function() {
$('#employees_select').change(function() {
$.ajax({
url: "<%= update_employee_movements_path %>",
data: { employee_id : $('#employees_select').val() },
dataType: "script"
});
});
$('#commendations_click').click(function() {
$.ajax({
url: "<%= commendations_path %>",
data: {
employee_id : $('#employees_select').val(),
employee_movement_id : $('#employee_movements_select').val()
},
dataType: "script"
});
});
});
</script>
app/controllers/reports_controller
class ReportsController < ApplicationController
before_filter :authenticate_user!
# GET /reports
def index
#employees = Employee.all
#employeemovements = EmployeeMovement.distinct_positions
end
def update_employee_movements
if params[:employee_id]
#employeemovements = [].insert(0, "Select Employee Movement")
else
employee = Employee.find(params[:employee_id])
#employeemovements = employee.employee_movements.map{ |a| [a.position, a.id] }.insert(0, "Select Employee Movement")
end
end
def commendations
emdates = EmployeeMovement.last_2_dates_obtained(params[:employee_movement_id])
date_from = emdates[0].date_obtained
date_to = emdates.length == 1 ? nil : emdates[1].date_obtained
emp = Employee.find(params[:employee_id])
#commendations = case date_to.nil?
when true then emp.commendations.this_day_onwards(date_from)
else emp.commendations.within(date_from, date_to)
end
end
end
What I'm trying to do here is, I'm creating a page filled with links and drop down lists that will serve as a Reports center. The idea is, each link will be catered by a controller. Each controller will be responsible in showing my PDF in the browser (through ThinReports, if you're curious).
The #employees_select change event is used for changing the value of the #employee_movements_select collection_select.
Now my problem is, how can i capture the value of both #employees_select and #employee_movements_select and pass them to my commendations action?
I tested link_to by hardcoding values, and it works (code below)
<%= link_to 'COMMENDATION', commendations_path(employee_id: 1, employee_movement_id: 12, format: 'pdf') %>
However, If I use javascript to push the values to my commendations action through the 'click' event, my commendations action will be called twice, thus an error occurs because the params[:employee_id] in the action is now blank.
By the way, I need those values because my commendations action needs it so I can populate my PDF report template.
Please help. Thanks a lot in advance!
UPDATE 1
-> Updated link_to:
<%= link_to 'COMMENDATION', '#', { id: 'commendations_click' } %>
-> Removed dataType: "script" in #commendations_click event handler
-> Updated url: in #commendations_click event handler
url: <%= commendations_path(format: 'pdf') %>
UPDATE 2 (RESOLUTION)
I tweaked my javascript to look something like this:
$('#commendations_click').click(function() {
event.preventdefault();
window.location = "<%=j commendations_path(format: 'pdf') %>" + "?employee_id=" + $('#employees_select').val() + "&employee_movement_id=" + $('#employee_movements_select').val();
});
Works perfect now.
Two things come to mind. You can wrap the two select lists within a form element and just do a submit. Everything inside the form will be submitted to your server and you can process the request and handle the redirect on the server side. The other thing you can do is to handle the commendations click event on the client side using jquery or something. Just bind to the click event of that link, grab the values of the two select lists and do whatever you want with it. Remember, link_to just gets rendered as plain old html links on the view. For e.g.
link_to "Profile", profile_path(#profile) gets rendered as Profile

Issue with Ajax Appending

I have a comment model that is paginated and I would like the comments to load more comments on the same page whenever the next button is clicked. I have somewhat of an idea of how to go about doing this but can anyone advise how to go about doing this. I have some code already.
For the comment section instead of render I think it may have to be looking for the micropost and its id to find the right comments to append but I am unsure about how to go about tying this all together.
Pagination JS
$(function() {
$("#CommentPagin a").live("click", function() {
$.getScript(this.href);
return false;
});
});
Show JS
$("#cc").append('<%= escape_javascript(render :partial => "users/comments" )%>');
Comment Section
<div id='comments'>
<% comments = micropost.comments.paginate(:per_page => 5, :page => params[:page]) %>
<div id="CommentPagin">
<span class="CommentArrowIcon"></span>
<%= will_paginate comments, :page_links => false , :class =>"pagination" %>
</div>
<%= render 'users/comments' %>
</div>
Comment Rendering Section
<div id="cc">
<% comments = micropost.comments.paginate(:per_page => 5, :page => params[:page]) %>
<%= render comments %>
</div>
User Controller
def show
#user = User.find(params[:id])
#school = School.find(params[:id])
#comment = Comment.find(params[:id])
#micropost = Micropost.new
#comment = Comment.new
#comment = #micropost.comments.build(params[:comment])
#microposts = #user.microposts.order('created_at DESC').paginate(:per_page => 10, :page => params[:page])
respond_to do |format|
format.html
format.js
end
end
I´m a bit rusty with rails so this is somewhat generic answer.
I would load the next n comments from a route / action that renders just your Comment Rendering Section as HTML
Just think of it as you where requesting assets from your own API and using them to update the page.
Pagination JS
/**
* jQuery 1.7+
* use .delegate() for older versions.
**/
$("#CommentPagin").on('click', 'a', function(e){
// Get data from server - make sure url has params for per_page and page.
$.get($(this).attr('href'), function(data){
// refresh client with data
$("#cc").append(data);
});
});

How can I send an automatically generated ID for a form element to a javascript function?

I am trying to call a javascript function from my form page in a Rails 3 project. I need to send the function the ID of a particular element. Unfortunately I can't get the ID easily since it is automatically generated by a plugin.
I tried doing it this way:
<%= t.select :number_type, #id_types, {}, {:onchange => "has_other_field(' + the_value.id.to_s + "');"} %>
<% if (!the_value.nil?) && (!the_value.number_type.nil?) && !#id_types_sm.include? the_value.number_type) %>
<script type="text/javascript">
setup_other_field("<%= the_value.number_type %>", ###ID WOULD GO HERE###);
</script>
<% end %>
.. But since I don't know the ID of the element, I can't call it from the function.
So now I'm trying to do it this way, by calling the function from an "onload" when the input element loads:
<% if (!the_value.nil?) && (!the_value.number_type.nil?) && (!#id_types_sm.include? the_value.number_type) %>
<%# Call the function from the form helper only if the conditions are met %>
<%= t.select :number_type, #id_types, {}, {:onchange => "has_other_field(this.id);", :onload => "setup_other_field('" + the_value.number_type + "', this.id);"} %>
<% else %>
<%# Use the form helper without calling the function %>
<%= t.select :number_type, #id_types, {}, {:onchange => "has_other_field(this.id);"} %>
<% end %>
BUT I realize that onload does not work for this situation. Is there any workaround for this? How can I either
A) get the element ID from the field to the function in the first option, or
B) call this function from this input element whenever it loads?
... or C) an alternative way to do this?
Thanks in advance and let me know if more details would help.
If you have ID saved in the model, get it with <%= model.id %>
Exception to this rule is when you create object, and it is before it is written to database. If you go to edit or anywhere else it will be ok.
If you have it somewhere on the page :/ then you can use jQuery to get it for you.
< div id="id_of_the_element" attr_with_my_id="15" >ABC< /div >
$("#id_of_the_element").attr('attr_with_my_id')
< input id="id_of_the_element ... >< /input >
$("#id_of_the_element").value

JS and Rails site wide announcements

Tried doing http://davidwparker.com/2008/09/17/site-wide-announcements-in-rails-using-jquery-jgrowl/
Am really bad with JS. Think I am messing up on the last part where it says "This code goes in your application.js file (somewhere in $(function){ //here })"
Am I not suppose to do a link_to_function and create a function with this code that references that link?
Really lost on this one.
Updated -
application.js looks like
$(document).ready(function() {
$.jGrowl.defaults.closer = true;
$("#announcements_box").css("display", "none");
$("#announcements_box .announcement").each(function(){
$jQuery.jGrowl(this.textContent,{ sticky:true, close:function(e,m,o){hide_announcements();} });
});
});
function hide_announcements(){
$.get(
'/hide_announcements'
);
$("#announcements_box").fadeOut();
return false;
}
And my application.html.erb has
<% unless current_announcements.empty? %>
<div id="announcements_box">
<% for announcement in current_announcements %>
<div id="announcement_<%= announcement.id.to_s %>" class="jGrowl">
<%= announcement.message %>
<%= link_to "Hide Annoucements", hide_announcements_path, :id => 'hideAnn'%>
</div>
<% end %>
</div>
<% end %>
I'm not sure what $(function){ //here } notation means, that should give you error in the browser, but I think he just wants to execute code after page is loaded:
$(document).ready(function() {
// here
}
And the culprit was I only entered a div ID when I needed to have a div ID and class.

how to use ajax with json in ruby on rails

I am implemeting a facebook application in rails using facebooker plugin, therefore it is very important to use this architecture if i want to update multiple DOM in my page.
if my code works in a regular rails application it would work in my facebook application.
i am trying to use ajax to let the user know that the comment was sent, and update the comments bloc.
migration:
class CreateComments < ActiveRecord::Migration
def self.up
create_table :comments do |t|
t.string :body
t.timestamps
end
end
def self.down
drop_table :comments
end
end
controller:
class CommentsController < ApplicationController
def index
#comments=Comment.all
end
def create
#comment=Comment.create(params[:comment])
if request.xhr?
#comments=Comment.all
render :json=>{:ids_to_update=>[:all_comments,:form_message],
:all_comments=>render_to_string(:partial=>"comments" ),
:form_message=>"Your comment has been added." }
else
redirect_to comments_url
end
end
end
view:
<script>
function update_count(str,message_id) {
len=str.length;
if (len < 200) {
$(message_id).innerHTML="<span style='color: green'>"+
(200-len)+" remaining</span>";
} else {
$(message_id).innerHTML="<span style='color: red'>"+
"Comment too long. Only 200 characters allowed.</span>";
}
}
function update_multiple(json) {
for( var i=0; i<json["ids_to_update"].length; i++ ) {
id=json["ids_to_update"][i];
$(id).innerHTML=json[id];
}
}
</script>
<div id="all_comments" >
<%= render :partial=>"comments/comments" %>
</div>
Talk some trash: <br />
<% remote_form_for Comment.new,
:url=>comments_url,
:success=>"update_multiple(request)" do |f|%>
<%= f.text_area :body,
:onchange=>"update_count(this.getValue(),'remaining');" ,
:onkeyup=>"update_count(this.getValue(),'remaining');"
%> <br />
<%= f.submit 'Post'%>
<% end %>
<p id="remaining" > </p>
<p id="form_message" > </p>
<br><br>
<br>
if i try to do alert(json) in the first line of the update_multiple function , i got an [object Object].
if i try to do alert(json["ids_to_update"][0]) in the first line of the update_multiple function , there is no dialog box displayed.
however the comment got saved but nothing is updated.
it seems like the object sent by rails is nil or cant be parsed by JSON.parse(json).
questions:
1.how can javascript and rails know that i am dealing with json objects?deos ROR sent it a object format or a text format?how can it check that the json object has been sent
2.how can i see what is the returned json?do i have to parse it?how?
2.how can i debug this problem?
3.how can i get it to work?

Categories

Resources