Angular ui-bootstrap-datepicker change color on click - angular-ui-bootstrap

I'm using ui.bootstrap.datepicker. How can I change the color of a date when I press a button? The styles for 'full' and 'partially' are applied at the beginning, but when I change 'events', I see no change.
$scope.events = [
{
date: new Date(),
status: 'full'
},
{
date: new Date(),
status: 'partially'
}
];
vm.open = function () {
$scope.events[0].date = new Date(2018, 0, 1);
return $scope.events[0].status;
}

What I've done is I've added an ng-change to the element and I'm calling a function every time the model changes (when you click a datepicker button).
Then I filter the events and remove the one with the matching date
HTML
<div style="display:inline-block; min-height:290px;">
<div uib-datepicker ng-model="dt" ng-change="clickOnDate(dt)"
class="well well-sm" datepicker-options="options"></div>
</div>
JS
$scope.clickOnDate = function(dt) {
$scope.events = $scope.events.filter(function(d) {
return (
!(d.date.getFullYear() === dt.getFullYear() &&
d.date.getMonth() === dt.getMonth() &&
d.date.getDate() === dt.getDate())
);
})
}
I'm using the Array.prototype.filter method above.
Demo plunker

Not sure what your intent is, but you can push new items to the $scope.events array quite easily:
$scope.events.push({
date: new Date(2018, 0, 1),
status: 'my-event'
});
The status property corresponds to a CSS class that you can define as desired, to style the event however you want. For example you can highlight the event like this:
.my-event button span {
background-color: red;
border-radius: 32px;
color: black;
}
This will leave you with a small red dot on the specific date, just as the example in the angular-ui documentation showcases. If you'd like to highlight the entire button, try this instead:
.my-event button span {
background-color: red;
color: white;
}
To remove or change the highlighting of events, you might want to clear the $scope.events array sometimes (or remove single items):
$scope.events = [];

Related

How do I insert a link in the editor?

I'd like to add a hyperlink in a editor, like vscode does:
I'd like to add this formatted document and when you click into it, some operation happens, open a file dialog, for example.
I have no code to show yet because I didn't find anything like that yet, only for regular text that goes like this:
const line = editor.getPosition();
if(!line) {
throw new Error('line is null');
}
const range = new monaco.Range(line.lineNumber, 1,
line.lineNumber, 1);
const text = "empty tab";
const op: monaco.editor.IIdentifiedSingleEditOperation = {
range: range,
text: text,
forceMoveMarkers: true
};
editor.executeEdits('my-source', [op]);
but I didn't see how add a format it.
You can use an overlay element and define the placeholder content in HTML, with links that will perform actions (e.g. change the editor theme, change the language etc).
The HTML for the placeholder would look something like this:
<div class="monaco-placeholder">
This is a test placeholder that will disappear when you click into the editor.
Click
here
first if you want to change the editor language from HTML to JavaScript, or click
here
if you want to change the editor theme
</div>
Along with the following CSS:
.monaco-placeholder {
color: darkturquoise;
display: none;
position: absolute;
top: 0;
left: 65px;
pointer-events: all;
z-index: 1;
opacity: 0.7;
}
You can then wire this up in JavaScript as follows:
Functions to hide and show the placeholder:
function showPlaceholder() {
document.querySelector(".monaco-placeholder").style.display = "initial";
}
function hidePlaceholder() {
document.querySelector(".monaco-placeholder").style.display = "none";
}
Create the editor and show the placeholder:
const instance = monaco.editor.create(document.getElementById('container'), {
value: "",
language: 'html'
});
showPlaceholder();
Add event handlers for any links in the placeholder that you want to perform actions when clicked:
document.getElementsByClassName('change-language')[0].addEventListener('click', (e) => {
e.stopPropagation();
var model = instance.getModel();
monaco.editor.setModelLanguage(model, "javascript")
console.log('language successfully changed to JavaScript')
});
document.getElementsByClassName('change-theme')[0].addEventListener('click', (e) => {
e.stopPropagation();
monaco.editor.setTheme('vs-dark')
console.log('theme successfully changed')
});
Event handler to clear the placeholder and focus into the editor when the user clicks on any part of the placeholder apart from the links:
document.getElementsByClassName('monaco-placeholder')[0].addEventListener('click', () => {
hidePlaceholder();
instance.focus();
});
If you copy the HTML, CSS and JavaScript below into the Monaco Playground, you will see this working:
HTML
<div id="container" style="height: 100%"></div>
<div class="monaco-placeholder">
This is a test placeholder that will disappear when you click into the editor.
Click
here
first if you want to change the editor language from HTML to JavaScript, or click
here
if you want to change the editor theme
</div>
CSS
.monaco-placeholder {
color: darkturquoise;
display: none;
position: absolute;
top: 0;
left: 65px;
pointer-events: all;
z-index: 1;
opacity: 0.7;
}
JavaScript
const instance = monaco.editor.create(document.getElementById('container'), {
value: "",
language: 'html'
});
showPlaceholder();
function showPlaceholder() {
document.querySelector(".monaco-placeholder").style.display = "initial";
}
function hidePlaceholder() {
document.querySelector(".monaco-placeholder").style.display = "none";
}
document.getElementsByClassName('monaco-placeholder')[0].addEventListener('click', () => {
hidePlaceholder();
instance.focus();
});
document.getElementsByClassName('change-language')[0].addEventListener('click', (e) => {
e.stopPropagation();
var model = instance.getModel();
monaco.editor.setModelLanguage(model, "javascript")
console.log('language successfully changed to JavaScript')
});
document.getElementsByClassName('change-theme')[0].addEventListener('click', (e) => {
e.stopPropagation();
monaco.editor.setTheme('vs-dark')
console.log('theme successfully changed')
});

removeEventListener from another array-prototype forEach

Hello, friends!
I'm new to Javascript. Using native JS.
I need when I click on the red button the blue button becomes disabled using removeEventListener. And vice versa - clicking on the blue button will add removeEventListener to the red button.
But my method does not work because the first array does not see the other array.
Thanks for the help. And, please, add comments to your code))
Here is the code and example https://jsfiddle.net/of83ycmx/
<body>
<button class="red">Red</button>
<button class="blue">Blue</button>
<div class="box">BOX</div>
<button class="red">Red</button>
<button class="blue">Blue</button>
<div class="box">BOX</div>
<script>
const box = document.querySelectorAll('.box');
const red = document.querySelectorAll('.red');
const blue = document.querySelectorAll('.blue');
red.forEach((item, i) => {
item.addEventListener('click', function redListener() {
box[i].classList.add('redBox');
//removeEventListener doesnt work because blueListener is not defined
//item.removeEventListener('click', blueListener);
});
});
blue.forEach((item, i) => {
item.addEventListener('click', function blueListener() {
box[i].classList.add('blueBox');
// item.removeEventListener('click', redListener)
});
});
</script>
made some changes that made sense to me. I am quite a beginner, so anyone who sees anything no-no or bad practice go ahead and call me out.
What should happen:
My interpretation of your explanation is this: When a user clicks on 1 of 2 buttons, the button that was NOT clicked should have its event listener removed.
Solution:
Making the functions accessible was your main problem-named functions inside of event listeners are limited to that listener (I assume). So instead move the function outside of the listener and simply call the function:
function blueListener () {
// Do stuff here
}
item.addEventListener('click', blueListener)
Now the function is accessible to the other function, so when you remove the event listener you wont get blueListener is not defined.
By wrapping the buttons and the box in a div allows you to select the button you need. Using .querySelectorAll() on the parent div allows you to select the button with the respective class (i. e the selecting the blue button when you click the red button).
The functions don't need any other info; they use this to access the clicked element. Then you can find the parent element, and select the box to change the background color, and select the respective button to remove the event listener.
DEMO:
const box = document.querySelectorAll('.box');
const red = document.querySelectorAll('.red');
const blue = document.querySelectorAll('.blue');
function redListener() {
var parent = this.parentElement;
var box = parent.querySelectorAll('.box')[0]
var blueButton = parent.querySelectorAll('.blue')[0]
box.classList.add('redBox');
blueButton.removeEventListener('click', blueListener)
}
function blueListener() {
var parent = this.parentElement;
var box = parent.querySelectorAll('.box')[0]
var redButton = parent.querySelectorAll('.red')[0]
box.classList.add('blueBox');
redButton.removeEventListener('click', redListener)
}
red.forEach((item, i) => {
item.addEventListener('click', redListener)
})
blue.forEach((item, i) => {
item.addEventListener('click', blueListener)
});
body {
font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji;
}
.box {
width: 100px;
height: 100px;
background-color: rgb(172, 172, 172);
margin: 0px 0px 40px 0px;
display: flex;
justify-content: center;
align-items: center;
}
.redBox {
background-color: rgb(156, 56, 56);
}
.blueBox {
background-color: rgb(66, 56, 156);
}
<div class="buttons">
<button class="red">Red</button>
<button class="blue">Blue</button>
<div class="box">BOX</div>
</div>
<div class="buttons">
<button class="red">Red</button>
<button class="blue">Blue</button>
<div class="box">BOX</div>
</div>

Styling ionic 2 toast

Is there any way to style the text message within an ionic 2 toast?
I have tried this:
let toast = Toast.create({
message: "Some text on one line. <br /><br /> Some text on another line.",
duration: 15000,
showCloseButton: true,
closeButtonText: 'Got it!',
dismissOnPageChange: true
});
toast.onDismiss(() => {
console.log('Dismissed toast');
});
this.nav.present(toast);
}
But clearly you can't use html in the text so I am guessing the answer to my question is no?
You must add 'cssClass: "yourCssClassName"' in your toastCtrl function.
let toast = Toast.create({
message: "Some text on one line. <br /><br /> Some text on another line.",
duration: 15000,
showCloseButton: true,
closeButtonText: 'Got it!',
dismissOnPageChange: true,
cssClass: "yourCssClassName",
});
than you can add any feature to the your css class. But your css feature went outside the default page'css. Exmp:
page-your.page.scss.name {
//bla bla
}
.yourCssClassName {
text-align:center;
}
I was able to achieve a toaster color change by adding a custom class on the toaster create
let toast = this.toastCtrl.create({
message: 'Foobar was successfully added.',
duration: 5000,
cssClass: "toast-success"
});
toast.present();
}
In that pages scss file i then went outside the default nested page name ( because the toaster is NOT inside the root of ion page name thing). And all though this is a bit hacky i just explicitly targeted the next div element after the custom class that i added
.toast-success {
> div{
background-color:#32db64!important;
}
}
I say its hacky because you have to use the !important on it. You can avoid the !important by wrapping the .toast-success with .md,.ios,.wp{...
You can override the style default by overriding the main toaster variables in the theme/variables.scss file.
$toast-ios-background:(#32db64);
$toast-md-background:(#32db64);
$toast-wp-background:(#32db64);
This will only override the default value though and not a custom value. there are a few more variables that can be styled as well.
First, import toast controller from ionic-angular and make object of that in constructor.
import { ToastController } from "ionic-angular";
constructor(private _tc: ToastController) {
}
After that wherever you want to show your toast message write that.
let options = {
message: "Your toast message show here",
duration: 3000,
cssClass: "toast.scss"
};
this._tc.create(options).present();
Here is my scss:
.toast-message {
text-align: center;
}
Or you can check best example from this link. I think it will help you. :)
Or else check the answer on this link.
If you define your own css class in app.scss (not in page.scss)
you can style it with .toast-wrapper and .toast.message
No need to use > div{
Example:
.yourtoastclass {
.toast-wrapper {
background: blue;
opacity: 0.8;
border-radius: 5px;
text-align: center;
}
.toast-message {
font-size: 3.0rem;
color: white;
}
}
in theme/variables.scss you can make a default
Example (red and little transparent):
$toast-width: 75%; /* default 100% */
$toast-ios-background: rgba(153, 0, 0, .8);
$toast-md-background: rgba(153, 0, 0, 0.8);
Ionic 2 provide a very useful way to override their component style you can override the toaster SASS variable in src/theme/variables.scss by adding
$toast-ios-title-color: #f00 ;
$toast-md-title-color:#f00;
this will override the default style please refer to this Overriding Ionic Sass variable
You can accomplish, however you need to modify the toast component template itself.
Via explorer:
\node_modules\ionic-angular\components\toast\toast.js
Change line 194 (template):
{{d.message}} to <div [innerHTML]='d.message'></div>
You should be able to change any of the message styling in the css using .toast-message selector:
.toast-message {
font-family: Helvetica,
color: red
}
Or, if you look at the docs (http://ionicframework.com/docs/v2/api/components/toast/Toast/) there is a cssClass property you can use to assign your toast a specific class and then style that.
Change toast background color and opacity:
let toast = this.toastCtrl.create({
message: msg,
duration: 3000,
position: 'bottom',
cssClass: 'changeToast'
});
and add app.scss:
.changeToast{.toast-wrapper {opacity: 0.6; border-radius: 5px !important; text-align: center; background: color($colors, primary);}};
It's used with .toast-message
I tried all above, still didn't work, therefore I come across a new solution, you need cssClass outside of page css declaration:
let toast = this.toastCtrl.create({
message: msg,
duration: 3000,
position: 'bottom',
cssClass: 'toastcolor'
});
post-list.scss like this
page-post-list {
}
.toastcolor .toast-message {
background-color:skyblue;
}
Not sure about old Ionic versions, but in Ionic 5 you can't directly change inner CSS since it's encapsulated in the shadow
<ion-select>
#shadow-root
<div class="toast-container" part="container">
...
</div>
</ion-select>
so, to change .toast-container (for example) in your cssClass you should use:
.my-custom-class::part(container) {
flex-direction: column;
}
.my-custom-class {
.toast-container {
flex-direction: column; // will not work
}
}
I'm using ionic v5 with angular and
according to: https://ionicframework.com/docs/api/toast#css-shadow-parts
you can do something like this:
::ng-deep{
ion-toast::part(container) {
...
}
ion-toast::part(message) {
...
}
}

jQuery Mobile - Slide In Alert Bar CSS over Header

I am trying to make an alert bar slide in over my header bar in jQuery mobile. So far I have got the slide in down, but I am having trouble with the CSS. I originally tried make the outer most div with position: absolute; top 0px: which makes it slide over the header from the top, but then inside Safari on the iPhone, the close button is cut off and you have to scroll to the right. How do I fix that?
Here is the HTML code for the alert bar:
<div class="ui-bar ui-bar-b error" style="position: absolute; top: 0px;">
<h3>
Form Validation Errors
</h3>
<div style="display:inline-block; width:8%; margin-top:0px; float: right;">
Dismiss
</div>
<ul class="validation_errors_list"></ul>
</div>
I ended up finally use this CSS. The alert bar slides directly over the header.
//you only really need this just to get it to slide over the header nicely and make sure you use top:0 if you always want it to be at the top. The plugin I made shows in/out the error message at position you are scrolled to in the document
.alert{
position: absolute;
z-index: 9998;
width: 100%;
height: 30px;
display: none;
color: #ffffff;
text-shadow: none;
font-family: Helvetica,Arial,sans-serif;
}
//This CSS is only used if you have an X button to close the alert. See the plugin below.
.alert-button-container{
display:inline-block;
margin-top:-10px;
margin-right: 15px;
float: right;
}
Here is my HTML Code (note the ui-bar class is a jQuery mobile class that you need to add so you don't have to mess around some of the width and sizing stuff).
<div class="ui-bar alert">
<div class="alert-message"></div>
</div>
Here is a custom plugin I made from jQuery to do this alert bar.
Features + Use Cases
Features: Fades In/Out gracefully, can inject custom HTML error messages, can render a list of messages, slides over header, has a close X button for error messages, works on all browsers that I have tested so far (IE, iOS, Firefox), error messages appear at the position you are scrolled to in the document. No more have to scroll up to see the error :)
Form Validation Errors. You can pass in an array of error messages and it will parse it into a list.
var messages = new Array();
messages[0] = 'My Message';
//prevent from showing accidentally
if(messages.length > 0)
{
$(".alert").alertBar('error', "<h2>Form Validation Errors</h2>", {
'errorMessages': messages
});
}
Success or action messages:
$(".alert").alertBar('success', 'Removed From Your Itinerary');
////////////plugin code
(
function($) {
$.fn.alertBar = function(alertType, alertMessage, userOptions) { //Add the function
var options = $.extend({}, $.fn.alertBar.defaultOptions, userOptions);
var $this = $(this);
$this.addClass(options.cssClass)
.empty()
.html(alertMessage)
.css('top', $(document).scrollTop());
if(alertType == 'success')
{
$this
.fadeIn()
.addClass('alert-success')
.delay(options.animationDelay)
.fadeOut();
}
if(alertType == 'error')
{
var button = $('<div>')
.addClass('alert-button-container')
.append(
$('<a>').attr({
'href': '#',
'data-role': 'button',
'data-icon': 'delete',
'data-iconpos': 'notext',
'class': 'dismiss-error'
})
.append('Dismiss')
);
//build error container
$this
.addClass('alert-error')
.append(button);
//add optional items to error container
if(options.errorMessages)
{
var $messageList = $('<ul>').addClass('error-message-list');
for ( var i=0, len=options.errorMessages.length; i<len; ++i ){
$messageList.append(
$('<li>')
.append(options.errorMessages[i])
);
}
$this.append($messageList);
}
//show alert bar
$this
.trigger('create')
.fadeIn();
$(".dismiss-error").live('click', function(){
$this.fadeOut();
});
}
if(alertType == 'informational')
{
$this
.addClass('alert-informational')
.fadeIn()
.delay(options.animationDelay)
.fadeOut();
}
return $this;
};
$.fn.alertBar.defaultOptions = {
cssClass : 'alert',
alertBarType: '',
animationDelay: 1500
};
})(jQuery);
additional CSS classes if you use this. It just changes the color of the bar.
.alert-success{
background-color: #8cc63f;
}
.alert-error{
background-color: #ed1c24;
height: auto;
}
.alert-informational{
background-color: #0071bc;
}
Example picture:

Notify panel similar to stackoverflow's

Remember the little div that shows up at the top of the page to notify us of things (like new badges)?
I would like to implement something like that as well and am looking for some best practices or patterns.
My site is an ASP.NET MVC app as well. Ideally the answers would include specifics like "put this in the master page" and "do this in the controllers".
Just to save you from having to look yourself, this is the code I see from the welcome message you get when not logged in at stackoverflow.
<div class="notify" style="">
<span>
First time at Stack Overflow? Check out the
FAQ!
</span>
<a class="close-notify" onclick="notify.close(true)" title="dismiss this notification">×</a>
</div>
<script type="text/javascript">
$().ready(function() {
notify.show();
});
</script>
I'd like to add that I understand this perfectly and also understand the jquery involvement. I'm just interested in who puts the code into the markup and when ("who" as in which entities within an ASP.NET MVC app).
Thanks!
This answer has a complete solution.
Copy-pasting:
This is the markup, initially hidden so we can fade it in:
<div id='message' style="display: none;">
<span>Hey, This is my Message.</span>
X
</div>
Here are the styles applied:
#message {
font-family:Arial,Helvetica,sans-serif;
position:fixed;
top:0px;
left:0px;
width:100%;
z-index:105;
text-align:center;
font-weight:bold;
font-size:100%;
color:white;
padding:10px 0px 10px 0px;
background-color:#8E1609;
}
#message span {
text-align: center;
width: 95%;
float:left;
}
.close-notify {
white-space: nowrap;
float:right;
margin-right:10px;
color:#fff;
text-decoration:none;
border:2px #fff solid;
padding-left:3px;
padding-right:3px
}
.close-notify a {
color: #fff;
}
And this is javascript (using jQuery):
$(document).ready(function() {
$("#message").fadeIn("slow");
$("#message a.close-notify").click(function() {
$("#message").fadeOut("slow");
return false;
});
});
And voila. Depending on your page setup you might also want to edit the body margin-top on display.
Here is a demo of it in action.
After snooping around the code a bit, here's a guess:
The following notification container is always in the view markup:
<div id="notify-container"> </div>
That notification container is hidden by default, and is populated by javascript given certain circumstances. It can contain any number of messages.
If the user is not logged in
Persistence: Cookies are used to keep track of whether a message is shown or not.
Server side generated code in the view:
I think stackoverflow only shows one message if you aren't logged in. The following code is injected into the view:
<script type="text/javascript">
$(function() { notify.showFirstTime(); });
</script>
The showFirstTime() javascript method just determines whether to show the "Is this your first time here?" message based on whether a cookie has been set or not. If there is no cookie, the message is shown. If the user takes action, the cookie is set, and the message won't be show in the future. The nofity.showFirstTime() function handles checking for the cookie.
If the user is logged in
Persistence: The database is used to keep track of whether a message has been shown or not.
Server side generated code in the view:
When a page is requested, the server side code checks the database to see what messages need to be displayed. The server side code then injects messages in json format into the view and puts a javascript call to showMessages().
For example, if I am logged into a view, I see the following in the markup at SO:
<script type="text/javascript">
1
2 var msgArray = [{"id":49611,"messageTypeId":8,"text":"Welcome to Super User! Visit your \u003ca href=\"/users/00000?tab=accounts\"\u003eaccounts tab\u003c/a\u003e to associate with our other websites!","userId":00000,"showProfile":false}];
3 $(function() { notify.showMessages(msgArray); });
4
</script>
So the server side code either injects code to call the "showFirstTime" method if the user is not logged in or it injects messages and calls "showMessages" for a logged in user.
More about the client side code
The other key component is the "notify" JavaScript module Picflight has de-minified (you can do the same using yslow for firebug). The notify module handles the populating of the notification div based on the server side generated javascript.
Not logged in, client side
If the user is not logged in, then the module handles events when the user X's out the notification or goes to the FAQ by creating a cookie. It also determines whether to display the first time message by checking for a cookie.
Logged in, client side
If the user is logged in, the notify module adds all the messages generated by the server into the notification div. It also most likely uses ajax to update the database when a user dismisses a message.
Though these are by no means official, the common practices that I follow would result in something like this:
Create the element that will act as the notification container in the markup, but hide it by default (this can be done numerous ways - JavaScript, external CSS, or inline styles).
Keep the scripts responsible for the behavior of the notification outside of the markup. In the example above, you can see there is an onclick as well as another function that fires on page load contained in the markup. Though it works, I see this as mixing presentation and behavior.
Keep the notification message's presentation contained in an external stylesheet.
Again, these are just my common practices stated in the context of your question. The thing with web development, as the nature of your question already shows, is that there are so many ways to do the same thing with the same results.
I see the following jQuery function? I beleive that injects the html into the div with id notify-container.
I don't understand how this JS is used and called based on certain events, perhaps someone can explain.
var notify = function() {
var d = false;
var e = 0;
var c = -1;
var f = "m";
var a = function(h) {
if (!d) {
$("#notify-container").append('<table id="notify-table"></table>');
d = true
}
var g = "<tr" + (h.messageTypeId ? ' id="notify-' + h.messageTypeId + '"' : "");
g += ' class="notify" style="display:none"><td class="notify">' + h.text;
if (h.showProfile) {
var i = escape("/users/" + h.userId);
g += ' See your profile.'
}
g += '</td><td class="notify-close"><a title="dismiss this notification" onclick="notify.close(';
g += (h.messageTypeId ? h.messageTypeId : "") + ')">×</a></td></tr>';
$("#notify-table").append(g)
};
var b = function() {
$.cookie("m", "-1", {
expires: 90,
path: "/"
})
};
return {
showFirstTime: function() {
if ($.cookie("new")) {
$.cookie("new", "0", {
expires: -1,
path: "/"
});
b()
}
if ($.cookie("m")) {
return
}
$("body").css("margin-top", "2.5em");
a({
messageTypeId: c,
text: 'First time here? Check out the <a onclick="notify.closeFirstTime()">FAQ</a>!'
});
$(".notify").fadeIn("slow")
},
showMessages: function(g) {
for (var h = 0; h < g.length; h++) {
a(g[h])
}
$(".notify").fadeIn("slow");
e = g.length
},
show: function(g) {
$("body").css("margin-top", "2.5em");
a({
text: g
});
$(".notify").fadeIn("slow")
},
close: function(g) {
var i;
var h = 0;
if (g && g != c) {
$.post("/messages/mark-as-read", {
messagetypeid: g
});
i = $("#notify-" + g);
if (e > 1) {
h = parseInt($("body").css("margin-top").match(/\d+/));
h = h - (h / e)
}
} else {
if (g && g == c) {
b()
}
i = $(".notify")
}
i.children("td").css("border-bottom", "none").end().fadeOut("fast", function() {
$("body").css("margin-top", h + "px");
i.remove()
})
},
closeFirstTime: function() {
b();
document.location = "/faq"
}
}
} ();
StackOverflow uses jQuery - the JS code you posted from SO is a jQuery call. It'll do exactly what you want with almost no code. Highly recommended.
I wrote this piece of Javascript that does just that including stacking, staying with you as you scroll like Stack Overflow's does and pushing the whole page down whenever a new bar is added. The bars also expire. The bars also slide into existence.
// Show a message bar at the top of the screen to tell the user that something is going on.
// hideAfterMS - Optional argument. When supplied it hides the bar after a set number of milliseconds.
function AdvancedMessageBar(hideAfterMS) {
// Add an element to the top of the page to hold all of these bars.
if ($('#barNotificationContainer').length == 0)
{
var barContainer = $('<div id="barNotificationContainer" style="width: 100%; margin: 0px; padding: 0px;"></div>');
barContainer.prependTo('body');
var barContainerFixed = $('<div id="barNotificationContainerFixed" style="width: 100%; position: fixed; top: 0; left: 0;"></div>');
barContainerFixed.prependTo('body');
}
this.barTopOfPage = $('<div style="margin: 0px; background: orange; width: 100%; text-align: center; display: none; font-size: 15px; font-weight: bold; border-bottom-style: solid; border-bottom-color: darkorange;"><table style="width: 100%; padding: 5px;" cellpadding="0" cellspacing="0"><tr><td style="width: 20%; font-size: 10px; font-weight: normal;" class="leftMessage" ></td><td style="width: 60%; text-align: center;" class="messageCell"></td><td class="rightMessage" style="width: 20%; font-size: 10px; font-weight: normal;"></td></tr></table></div>');
this.barTopOfScreen = this.barTopOfPage.clone();
this.barTopOfPage.css("background", "transparent");
this.barTopOfPage.css("border-bottom-color", "transparent");
this.barTopOfPage.css("color", "transparent");
this.barTopOfPage.prependTo('#barNotificationContainer');
this.barTopOfScreen.appendTo('#barNotificationContainerFixed');
this.setBarColor = function (backgroundColor, borderColor) {
this.barTopOfScreen.css("background", backgroundColor);
this.barTopOfScreen.css("border-bottom-color", borderColor);
};
// Sets the message in the center of the screen.
// leftMesage - optional
// rightMessage - optional
this.setMessage = function (message, leftMessage, rightMessage) {
this.barTopOfPage.find('.messageCell').html(message);
this.barTopOfPage.find('.leftMessage').html(leftMessage);
this.barTopOfPage.find('.rightMessage').html(rightMessage);
this.barTopOfScreen.find('.messageCell').html(message);
this.barTopOfScreen.find('.leftMessage').html(leftMessage);
this.barTopOfScreen.find('.rightMessage').html(rightMessage);
};
this.show = function() {
this.barTopOfPage.slideDown(1000);
this.barTopOfScreen.slideDown(1000);
};
this.hide = function () {
this.barTopOfPage.slideUp(1000);
this.barTopOfScreen.slideUp(1000);
};
var self = this;
if (hideAfterMS != undefined) {
setTimeout(function () { self.hide(); }, hideAfterMS);
}
}
To use it you must use jQuery and ensure there are no margins or padding on the body of your page.
The parameter that the AdvancedMessageBar takes is optional. If provided it will cause the bar to disappear after a certain amount of time in milliseconds.
var mBar = new AdvancedMessageBar(10000);
mBar.setMessage('This is my message', 'Left Message', 'Right Message');
mBar.show();
If you want to stack these then just create more AdvancedMessageBar objects and they'll automatically stack.

Resources