Janko is UI designer, software engineer, blogger, speaker and artist. Janko has posted 20 posts at DZone. You can read more from them at their website. View Full User Profile

Why and how to create Microsoft Office Minibar with jQuery and CSS3

05.25.2010
| 2907 views |
  • submit to reddit

Although many will argue that Microsoft products are an example of a good design, Minibar was one of design refreshments that came out with the Office 2007. It is a variation of a toolbar that exposes context-related functionality. In case of MS Word, context is a text selection. Since Minibar always pops up near the mouse pointer it enables users to quickly perform actions related to a selection.

Check out demo

So how it works? When user makes a selection in input field Minibar pops up, semi-transparent, above the selection. When user hovers the Minibar it fades out. It disappears when user clicks anywhere in the input field or performs an action by clicking on a Minibar button.

Quite simple Minibar will be shown in this tutorial - it has only bold, underline, italic, and link buttons.

<textarea id="description" rows="8" cols="50"></textarea>
<div id="menu">
<a href="#" id="bold">b</a>
<a href="#" id="italic">i</a>
<a href="#" id="underline">u</a>
<a href="#" id="link">Link</a>
</div>

We need to make Minibar semi-transparent initially, and solid-color on hover.

#menu {padding:5px; background-color:#f5f5f5;
background-color:rgba(245, 245, 245, 0.6);
display:none; position:absolute; top:0px; left:0px; overflow:hidden;
border:solid 1px #929292; border-radius:3px; -moz-border-radius:3px;
-webit-border-radius:3px; box-shadow: 5px 5px 5px #888;
-moz-box-shadow: 1px 1px 3px #555; -webkit-box-shadow: 5px 5px 5px #888;}
#menu:hover {background-color:rgba(245, 245, 245, 1);}

 

Fade it in and out

To be able to control Minibar position we will need to track the mouse position and use x an y coordinate to set top and left properties of its container. To show Minibar upon selection we will use .select() event, where its container will be faded in at the specific location. We also need to handle .mousedown() event in order to fade the Minibar out when user click somewhere else.

$(document).ready(function() {
var mouseX = 0;
var mouseY = 0;

$("#description").mousemove(function(e) {
// track mouse position
mouseX = e.pageX;
mouseY = e.pageY;
});

// Fade out the menu on any click
$("#description").mousedown(function() {
$("#menu").fadeOut("1000");
});

$("#description").select(function() {
// get the mouse position an show the menu
$("#menu").css("top", mouseY - 30)
.css("left", mouseX + 10).fadeIn("1000");
});
});

 

Handling clicks

Now when we know how to handle fading in and out, we can add some functionality. If we want to make a selection bold, we can wrap it with <strong> and </strong> tags (of course, it can be done with span element and some CSS but for the purpose of this tutorial I will wrap selection with tags).

function wrapText(startText, endText){
// Get the text before the selection
var before = $("#description").val().substring(0, $("#description").caret().start);

// Get the text after the selection
var after = $("#description").val().substring($("#description").caret().end, $("#description").val().length);

// merge text before the selection, a selection wrapped with inserted text and a text after the selection
$("#description").val(before + startText + $("#description").caret().text + endText + after);
}


This function, which relies on jCaret plugin wraps the selection with tags and merge it with text before and after the selection. Quite simple, when you have useful plugin such as jCaret. We only need to handle click events for each Minibar button.

$("#bold").click(function() {
wrapText("<strong>", "</strong>");
$("#menu").fadeOut("1000");
});

$("#italic").click(function() {
wrapText("<em>", "</em>");
$("#menu").fadeOut("1000");
});

$("#underline").click(function() {
wrapText("<u>", "</u>");
$("#menu").fadeOut("1000");
});

$("#link").click(function() {
var url = prompt("Enter URL", "http://");
if (url != null)
wrapText("<a href='" + url + "'>", "</a>");
$("#menu").fadeOut("1000");
});

Handling click events for bold, italic and underline actions is more than simple. We just call wrapText() function, pass it appropriate start and end tags and fade Minibar out. Handling click for link button is a bit different - we first need to prompt users to enter URL and then pass the URL inside opening tag.

Check out demo

Conclusion

As a regular Word user I am so used to this small toolbar and I am missing it on the web. I would really like to see it as a feature in WYSIWYG editors such as TinyMCE. It can also be a part of comment/contact forms. In order to play around with it more I will add it to my comment form as a part of the current blog realign.

Although it works in all major browsers, the code is everything but perfect - it can be optimized and more features can be seen here. Feel free to play with it and if you find any bug, please drop me a line.

References
Published at DZone with permission of its author, Janko Jovanovic. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)