I have a Rails 3.2 app that manages students. It has a fairly typical nav bar across the top (Foundation 5) which contains a quick search field. The nav bar is displayed on every page of the site.
If you enter a valid (numeric) student ID into the search field, you simply jump to that student's page. If you enter text or other non-numeric input, you get a flash error asking for valid input. If you enter an id that's not found, you get a flash notice saying it wasn't found. In either of the latter two cases, the controller should just drop you back to whatever page you came from and display the appropriate flash message.
For starters, here's the search field in the view:
<%= form_tag search_students_path, method: 'get' do %>
<div id="nav-search" class="row collapse">
<div id="nav-search-field" class="small-21 columns">
<%= text_field_tag :search, nil, autocomplete: 'off' %>
</div>
<div id="nav-search-icon" class="small-3 columns">
<%= submit_tag ''.html_safe, class: 'button fa fa-search spin', name: 'submit' %>
</div>
</div>
<% end %>
And here's the controller action:
def search
session[:return_to] ||= request.referer
if params[:search].to_i.zero?
flash[:error] = %Q[<i class="fa fa-times fa-fw"></i> Please enter a numeric student ID.].html_safe
redirect_to session.delete(:return_to)
else
id = params[:search].to_i.abs
#student = Student.search(id).first
if #student
redirect_to #student
else
flash[:caution] = %Q[<i class="fa fa-warning fa-fw"></i> Sorry, we couldn't find a student with ID #{id}.].html_safe
redirect_to session.delete(:return_to)
end
end
end
Lastly, here's the code for rendering flash messages in application.html.erb:
<% flash.each do |key, value| %>
<div data-alert class="alert-box cbc-<%= key %>">
<%= value %>
×
</div>
<% end %>
In Chrome and FireFox this works exactly as expected. The flash appears for one request, then disappears. However, in Safari, once the flash comes up it never goes away for that page. So if you get the error flash on the home page, for example, you can refresh all you want. It stays put. You can go to another page, and then come back, and it's still there. The same is true for other pages. Once the flash message has appeared on a given page, it doesn't go away.
Thus my question: how can I get Safari to clear the flash after the first request?
I'm aware of the whole "flash vs. flash.now" issue when rendering pages. But even then, the flash will disappear if you simply refresh. I actually tried flash.now in this case, but then the flash isn't displayed at all in any browser.
Since this appears to be a browser-specific problem, here are some further stats on my system:
Mac OS X 10.9
Safari 7.0
Rails 3.2.16
One final observation. After playing around with this issue in Safari, I noticed that if I clicked my bookmark for http://localhost:3000/, that would clear the flash. Of course, all the navigation links in my site layout contain relative paths, whereas the bookmark is calling a full url.
Anyway, hope that made sense. Thanks in advance for your help!
Related
I am using Devise to handle user authentication. When a user signs up, I am seeing 2 flash messages displaying the same text.
The blue well I believe is rendered through my application.html.erb:
<!-- Notice -->
<% if notice %>
<div class="alert alert-primary" role="alert">
<center><%= notice %></center>
</div>
<% end %>
However, I am unable to figure out where the 2nd message comes from. Any advice on where I should ook?
you may be using simple_form_for. That gem takes care of the error notice.
I have and index page showing a list of users. What I want is for when I click on a link_to show a certain user in that #users.each form, that shows up the modal (pop ups fine) but gives the data of that user in it as well.
users/index.html.erb
<div class="container">
<% #users.each do |user| %>
<%= link_to user.name, user, { remote: true, "data-target": "#modal-full" } %>
<% end %>
</div>
<%= render 'layouts/modalfull' %>
layouts/_modalfull.html.erb
<div id="modal-full">
<h1 class="name"></h1>
</div>
UsersController
def show
#user = User.find(params[:id])
redirect_to do |format|
format.js // because that would be where the js code would be to push the data to the modal, right?
end
end
Now how it should go in the in the show.js.erb, I have no idea, I'm really not familiar with those stuffs, still new with Rails.
So right now, what I did, will pop-up the modal but wouldn't send the data from the user I clicked on. And I believe that's on the JavaScript side > show.js.erb.
Continued trying different things and came up with this, which made it work.
Which is partially an answer, you'll know why bellow.
users/show.js.erb
$("#modal-full .name").html("<%= #user.name %>");
But if there is any cleaner way to do this, please share.
Because right now, the thing works, it replaces the name but, we see the change being made. So if I clicked on a John, modal would pop up with "John" written on it. Then I close it and click on "Jennifer", modal will pop up with "John" and takes a second to change it to "Jennifer".
I have a small CMS-like program that has multiple pages that act like blog posts. Each page has content, and a position integer that identifies in what order they will appear on the page.
On my admin side, I have a draggable list of pages that I can reorder similar to how wordpress orders plugins. The page works as functions, and assigns the value of the dragged position to each page correctly. However, since all sortable pages have their own form, I cannot submit them all at once - only one at a time.
As an example, my code looks like this currently:
<div class="sortable">
<% #pages.each do |page| %>
<div class="dragBox">
<%= form_for(page) do |f| %>
<%= f.number_field :position, class: 'inPosition' %>
<% end %>
</div>
<% end %>
</div>
Because I can get every page_id tied to its new position, is it possible to submit those values in a new hash to get updated all at once in the controller? How would I go about doing this? Is there a better or easier way to do this? Thanks.
I am using the following code in my layout to display two types of flash messages:
<% if !flash[:notice].nil? %>
<div class="row">
<div class="flash notice col-xs-12">
<%= flash[:notice] %>
</div>
</div>
<% end %>
<% if !flash[:error].nil? %>
<div class="row">
<div class="flash error col-xs-12">
<%= flash[:error] %>
</div>
</div>
<% end %>
<%= debug(flash[:notice]) %>
<%= debug(flash[:error]) %>
They both work fine, but whenever one is triggered, it will still appear for one additional page view. I'm not using any caching gems.
Why is this happening? And how do I fix it?
Use flash.now instead of flash.
The flash variable is intended to be used before a redirect, and it persists on the resulting page for one request. This means that if we do not redirect, and instead simply render a page, the flash message will persist for two requests: it appears on the rendered page but is still waiting for a redirect (i.e., a second request), and thus the message will appear again if you click a link.
To avoid this weird behavior, when rendering rather than redirecting we use flash.now instead of flash.
The flash.now object is used for displaying flash messages on a rendered page. As per my assumption, if you ever find a random flash message where you do not expect it, you can resolve it by replacing flash with flash.now.
i was wondering if it was possible to only affect one tab when clicking through pagination? im using the will_paginate gem
i have something that looks like...
<div class="tab-content">
<div class="tab-pane active span8" id="received">
<h3>Received Messages</h3>
<%= render 'received_message_feed'%>
</div>
<div class="tab-pane span8" id="sent">
<h3>Sent Messages</h3>
<%= render 'sent_message_feed'%>
</div>
</div>
which renders...
<% if #sent_message_items.any? %>
<ol class="microposts">
<%= render partial: 'shared/message_item', collection: #sent_message_items %>
</ol>
<%= will_paginate #sent_message_items %>
<% end %>
i have an equivalent received_message partial as well.
in my first block of code, i have 2 tabs, one for my received messages and one for my sent messages. lets say i click on my sent tab and then click on page 2. two problems arise from this.
the page refreshes and goes to my received messages tab, which is at first active tab. is there a way to make it go back to sent?
the bigger problem, when i click on page 2 while in sent tab, it will also load page 2 on my received tab. is there a way to prevent this?
im not sure how to fix this... help would be appreciated. thank you!
UPDATE.
i winded up using ajax pagination, so then the page doesn't ever reload and problem 1 is circumvented. however problem 2 is still an issue...
i fixed it.
i winded up using ajax pagination, so then the page doesn't ever reload and problem 1 is circumvented.
and as for problem 2, this saved the day
http://blog.devinterface.com/2011/08/tips-multiple-pagination-with-will_paginate/