5

In my Rails application I have flash messages and I would like it so that each time there is a flash message, it scrolls down from the top (all the content goes lower) stays for a few seconds and the slides back up.

How can I do this with jQuery?

Do I toggle the height?

Update

Sometimes the message will be injected into the HTML which means that the slideDown won't work since the DOM has already loaded, how can I have it so jQuery looks for .message and then applies the slideDown and slideUp?

Community
  • 1
  • 1
user1919937
  • 455
  • 4
  • 9
  • 15

5 Answers5

11

You can make it slide down, wait for couple of seconds and slide back again with this:

$(selector for your message).slideDown(function() {
    setTimeout(function() {
        $(selector for your message).slideUp();
    }, 5000);
});

Change the 5000 to the time you want the message to stay visible in milliseconds.

And remember to set display: none; in CSS for your message, so that it does not appear until jQuery goes in.

Eleeist
  • 6,891
  • 10
  • 50
  • 77
  • How can I do it so it slides up when there is a message inside? – user1919937 Dec 22 '12 at 20:59
  • I guess you would have to check this on server-side and add appropriate class or `data` argument so the jQuery would know whether it should animate or not. Or check with jQuery if it's empty... – Eleeist Dec 22 '12 at 21:00
  • How can I check if it's empty with jQuery? – user1919937 Dec 22 '12 at 21:07
  • `if (!$(your message).html()) { is empty }` – Eleeist Dec 22 '12 at 21:19
  • Ah, ok. Also, see the update I made. It might be why it's not working – user1919937 Dec 22 '12 at 21:23
  • It is good that DOM has already loaded. Just set `display: none` in CSS for your message. It will be hidden until jQuery shows it with `slideDown`. – Eleeist Dec 22 '12 at 21:27
  • Sorry for the confusion. What I mean is that I use Ajax so when the user hits the save button, it injects a div with the class message into the header so slideDown isn't working – user1919937 Dec 22 '12 at 21:30
  • It should work. How do you inject the div into the DOM? For example this should work: `$(".header").append(message).slideDown();`. – Eleeist Dec 22 '12 at 21:36
  • Some messages are injected using erb tags and the one where I save with Ajax, I have a update.js.erb file that contains `$('.header').append('
    Saved
    ');`
    – user1919937 Dec 22 '12 at 21:44
  • Look at this fiddle: http://jsfiddle.net/RPSwV/. Dynamically appending content to page does not prevent animations from working correctly. – Eleeist Dec 22 '12 at 22:03
  • Just click the run button again - the animation begins the moment you load the page. – Eleeist Dec 22 '12 at 22:12
  • I have no idea how else to help you. It ought to work. Sorry. – Eleeist Dec 22 '12 at 22:18
  • It's not your fault. For some reason the append is not actually injecting the code – user1919937 Dec 22 '12 at 22:18
1

I'll assume your flash message is contained in some element that is (or can be) identified by class. You want to find the first one, then adjust the scroll position to the top of that element (or some offset from it), then wait and scroll back to the top.

$(function() {
    var $flashMsg = $('.flash-message:first');
    if ($flashMsg.length) { // we've got one
       var top = $flashMsg.offset().top;
       $('html,body').animate({ scrollTop: top })
                     .delay(3000)
                     .animate({ scrollTop: 0 });
    }
});
tvanfosson
  • 524,688
  • 99
  • 697
  • 795
  • Where do I enter the class name? – user1919937 Dec 22 '12 at 21:04
  • That would be in the HTML surrounding your flash message. Been awhile since I've done any Ruby, but something like `
    @flash[:error]
    `
    – tvanfosson Dec 22 '12 at 21:09
  • I may have misunderstood your actual requirements. This will scroll the window to the error message, not slide open an error message at the top. That's actually much easier. – tvanfosson Dec 22 '12 at 21:11
0

use JQuery's slideDown() and call slideUp() in the callback coupled with a timer:

$("#message").slideDown(500, function(){
    setTimeout(function(){
$("#message").slideUp(500);  
},5000);
});
Matanya
  • 6,233
  • 9
  • 47
  • 80
0
function flashRed(sel, blinks){  //using jQuery
    blinks = blinks||3
    var x = $(sel),
        bg = x.css('background-color'),
        fg = x.css('color'),
        counter = 0,
        f, b;

    for(var i = 0; i < blinks * 2; i++){  

       setTimeout(function(){
           if(counter%2){
             f=fg; b=bg
           }
           else{
             f='white'; b='red'
           }
           counter++

           x.css({'color':f, 'background-color':b})
       },i*400)
    } 

 }
Lewiss
  • 17
  • 2
0

You can do it like this. here duration is in milliseconds.

$.fn.flash_msg=function(duration){
  this.fadeIn().delay(duration).fadeOut(function(){
    this.remove();
  })
}

$("#message").flash_msg(1500);
Kaleem Nalband
  • 687
  • 7
  • 21