Limiting iterations on smaller screens - javascript

I'm iterating over few user objects and printing their profile avatar url as an image:
<% #users.each do |user| %>
<%= image_tag(user.profile.avatar.url, class: 'circle') %>
<% end %>
Nice. If I have 100+, I need to limit the image based on the end-user screen size, ie iPad:
<% #users.take(8).each do |user| %>
<%= image_tag(user.profile.avatar.url, class: 'circle') %>
<% end %>
I need to know how you pros do it. I have a javascript that listens for css changes:
// run test on initial page load
checkSize();
// run test on resize of the window
$(window).resize(checkSize);
function checkSize(){
if ($("#demo").css("display") == "none" ){
// ajax to get A (users.take(8).each ...)
} else {
// ajax to get B (initial view)
}
});
In the place that I call the ajax, I wanted to use render but render cant be used:
$("#some-id").html("<%= escape_javascript(render partial: 'foo/a') %>"); // or foo/b
I have omitted displaying the router and controller. The ajax calls an .js.erb file.
This feels like this is a matter of UI/UX decision on how to display those avatar images: should they be shown at all on smaller screens or not. But if I had to, how to limit the iteration on smaller screens?

Related

Rails - customizing the flash message for specific use case

I'm completely new to ruby on rails. Please help me out with the below use case.
By default flash messages are configured to timeout and fade in few seconds in application.html.erb
<div id="message" class="modal alert alert-error fade clear" data-alert="alert">
<%= flash[:notice] %>
</div>
Javascript code to set the timeout for the flash:
var showFlashMsg = function(){
<%if flash[:notice].nil?%>
return false;
<%else%>
return true;
<%end%>}
if(showFlashMsg()){
window.setTimeout(function () {
showMsg();
}, 100);
window.setTimeout(function () {
closeMsg();
}, 500);
}
showMsg() and closeMsg() holds #message.show() and #message.hide() functions.
But i'm trying to override that above mentioned behavior by making specific flash alert messages user dismissable (ie., adding the close button to the flash alert.) - in case the flash message is triggered when i submit the particular form.
So in this case, i need to override the default behavior set for the flash by adding the close button and removing the closeMsg() timeout for those flash. Except the flash messages which are displaying the form submission response, all the other flash messages triggered by same controller and the same action should follow above mentioned behavior of fading out within few seconds.
Please give me some suggestions on how to customize the flash messages only for the particular form submission response using javascript and rails?
Thanks in advance !!!
I'd rewrite the first bit of code as:
var showFlashMsg = <%= !flash[:notice].nil? %>
Then assuming you know what string you're looking out for in your notice:
<% special_string = "This is the special flash notice" %>
var showFlashMsg = <%= !flash[:notice].nil? %>
var setTimeout = <%= flash[:notice] && flash[:notice] != special_string %>
if(showFlashMsg){
window.setTimeout(function () {
showMsg();
}, 100)
}
if (setTimeout){
window.setTimeout(function () {
closeMsg();
}, 500);
}
This will set showFlashMsg to true if flash[:notice] is not nil, and setTimeout to true if it's not nil, and also doesn't equal the special string.

Rails call specific js.rb manually

I have this bit of code refreshing the event when I update it.
event/update.js.erb
$('#calendar').fullCalendar('removeEvents', [<%= #event.id %>]);
$('#calendar').fullCalendar(
'renderEvent',
$.parseJSON("<%=j render(#event, format: :json).html_safe %>"),
true
);
Lot of my events are related and I would like to be able to call this manually on every event every time as one of them is updated.
I'm trying to do something like this but I've no idea how to make the javascript call and it doesn't feel right either.
def update
#event.update(event_params)
Event.all.each do |event|
# call event's javascript
end
end
Any suggestions on this ?
If you want to do it every time, just do it in the view.
# controller
def update
#event.update(event_params)
#events = Event.all
end
# update.js.erb
<% #events.each do |event| %>
$('#calendar').fullCalendar('removeEvents', [<%= event.id %>]);
$('#calendar').fullCalendar(
'renderEvent',
$.parseJSON("<%=j render(event, format: :json).html_safe %>"),
true
);
<% end %>

Scroll bar jumps back to the top when the hide link is clicked

Actually I have got a more number of records in my index page with respective "hide"link on each record. Then problem is when I click the respective link it hides the record but moves to the top of the page, how do I stop this?
_rak361.html.erb
<%= link_to "Hide", hide_rak361_path(rak361), method: :put, class: 'stopper', style: "color:#ccc;" %>
ample.js
$( document ).ready(function() {
$(".stopper").click(function(event) {
event.preventDefault();
});
});
rak361s_controller.rb
def hide
#rak361 = Rak361.find(params[:id])
#rak361.hide
flash[:notice] = 'Rak361 was successfully hidden.'
redirect_to rak361s_url
end
I have tried but it is not working for me.
Any suggestions are most welcome.
Thank you in advance.
Thats because its a full page reload, first thing you need to to do is to use path helpers instead of mentioning controller and action in link_to, and the second thing is you should use remote: true option to ajaxify the request. Here's an example
= link_to "Hide", example_hide_path(id), method: :put, remote: true, class: 'stopper', style: "color:#ccc;"
Either you can use remote: true, or you can send an ajax request using jQuery's $.ajax().
Hope that helps!

Link not working after render partial js

So what I want is to re-render a table after updating an event.
I do it like this:
## My Controller:
respond_to do |format|
if schedule_child.save
sql = "schedules.doctor_id = ? AND schedules.location_id = ? AND schedule_children.start_time >= ? AND schedule_children.start_time <= ?"
#schedules = ScheduleChild.joins(:schedule).where(sql, current_doctor.id, session[:location_id], Time.now, Time.now + 7.days).order(start_time: :asc).page(params[:page]).per(7)
format.js {render :layout => false}
end
end
My js.erb:
$('#schedules').html( "<%= escape_javascript( render "schedules" ) %>" );
My view:
%a.status_link.btn.btn-success.btn-sm{"data-href" => set_schedule_status_path(location_id: session[:location_id] ,id: schedule.id), :style => "#{schedule.is_away ? 'display: none' : '' }", :id => "#{schedule.id}", :remote => "true"}
%i.fa.fa-check-square-o
%span Available
The table was successfully rendered but I cannot click the link in my view. What did I do wrong? Thanks for your help :)
The use of "data-href" as the link instead of "href" requires additional javascript to make the link available. Probably you have that javascript in place and are calling it on document.ready and apply your javascript logic on every link with the data property "data-href".
If this is the case you have four options (just guesses as I don't know what logic for data-href you are using):
Use href instead of data-href
Call the logic that enables the link in your js.erb (after you replaced the table)
Call the logic that enables the link on document.ready and ajaxStop
Define the logic on a parent node that exists always like $('body').on('click', 'a[data-href]', ...

Rails 4 Turbolinks make form submit multiple times

I use some code working nicely on Rails 3 but not on Rails 4, I guess it is caused by Turbolinks but I don't know much about it, can't dig more deep to solve my problem, here is the code:
view:
a/v/m/_new_comment.slim
.new-comment
- if current_user
= render "editor_toolbar"
= form_for(Comment.new, :remote => true, :url => mission_comments_path(#mission)) do |f|
= f.text_area :content, :class => "span10",
:rows => "4", :tabindex => "1"
#preview.hidden
= "Loading..."
= f.submit t("missions.submit_comment"),
"data-disable-with" => t("missions.submitting"),
:class => "btn btn-primary", :tabindex => "2"
- else
= render "need_login_to_comment"
controller:
def create
#mission = Mission.find(params[:mission_id])
#comment = #mission.comments.build(comment_params)
#comment.user = current_user
if #comment.save
#mission.events.create(user: current_user, action: "comment")
render layout: false
end
and js:
<% if #comment.errors.any? %>
$(".new-comment textarea").focus();
<% else %>
$(".comments").append("<%= j (render #comment, :index => #mission.comments.count-1) %>");
$(".new-comment #preview").addClass("hidden").html('');
$(".new-comment textarea").css("display", "block").val('');
$(".editor-toolbar .preview").removeClass("active");
$(".editor-toolbar .edit").addClass("active");
<% end %>
I have two question about this code, first: the controller code like this isn't work
the js code is transfer to client but not run, I have to add render layout: false at bottom of that action, no need this on Rails 3
second question: when I first visit this page, reload the page, comment function works, but if I click a link from other pages to jump to this page, I submit this form will cause ajax request call multiple times, multiple comments will be created
thanks in advs
Solved this by moving = javascript_include_tag "application", "data-turbolinks-track" => true from body to head, thanks all your help
You can leave it in the body, you just need to add to your script tag:
"data-turbolinks-eval" => false
In general, with turbolinks, it's best to make sure your code is "idempotent", so if it runs more than once, bindings won't get setup more than once.
The best way to do this is instead of $('blah').bind(), call unbind first:
$('blah').unbind('click').bind('click', function() {
One possible reason you could be running into issues is if you are including the js on every page. It's my understanding it will append the js to the head and if you have included it on multiple pages you could find yourself binding the ajax multiple times. That being said it's not apparent how you are including the js from what I saw. You could possibly solve this by only including the js file in your application.js

Categories

Resources