We're using BeautyTips as a the mechanism for creating various kinds of bubbles for communicating with the user. For example, we have a help icon that shows a bubble with more information. We also use BT to display error and warning messages.
Here's what this looks like in practice.
You can see that the error messages are stacked one on top of the other and wither their parent message.
In the form_validator I have a function for the errorPlacement argument:
errorPlacement: function (er, el) {
if (el && el.length > 0) {
if (el.attr('id') == 'ContractOpenEnded') {
createErrorBubble($('#contractDuration'), er.text())
}
else {
createErrorBubble($(el), er.text());
}
}
}
Here are the functions that do the heavy lifting to create these bubbles.
function createErrorBubble(element, text) {
// In a conversation with pcobar the spec was changed for the bubbles to be to the right of the element
createBubble(element, text, 2, "none", "right", "#fe0000", "#b2cedc", "#ffffff", true);
element.btOn();
}
Here the createBubble function.
function createBubble(element, content, messageType, trigger, positions, fillColor, strokeColor, foreColor, useShadow) {
var btInstance = element.bt(
content,
{
trigger: trigger,
positions: positions,
shrinkToFit: true,
spikeLength: 12,
showTip: function (box) {
$(box).fadeIn(100);
},
hideTip: function (box, callback) {
$(box).animate({ opacity: 0 }, 100, callback);
},
fill: fillColor,
strokeStyle: strokeColor,
shadow: useShadow,
clickAnywhereToClose: false,
closeWhenOthersOpen: false, // Closing when others open hides page validation errors. This should be false.
preShow: function (box) {
if (messageType != 1) return;
var whiteboard = $($(box).children()[0]);
var content = whiteboard.html();
if (content.substr(0, 5).toLowerCase() == "<div>") {
content = content.substr(5, content.length -11);
}
whiteboard.html('<div><span class="helpWarningPrefix">Warning:</span> ' + content + "</div>");
},
cssStyles: { color: foreColor },
textzIndex: 3602, // z-index for the text
boxzIndex: 3601, // z-index for the "talk" box (should always be less than textzIndex)
wrapperzIndex: 3600
});
}
The answer to this quesytion is elluding me.
Update:
This actually looks like it might be more of an issue of trying to create the bubble for something that isn't in the viewable area of the page.
Edit: Updated the title to more clearly reflect the name of the problem.
With the realization from the update from earlier (the problem lying in elements off screen) I came up with a hack that "fixes" the problem but is inelegant and far from being the best thing since my cat got into the craft glitter and had no idea what had happened.
Here's the hack:
errorPlacement: function (er, el) {
if (el && el.length > 0) {
if (el.attr('id') == 'ContractOpenEnded') {
$('#contractDuration').focus();
createErrorBubble($('#contractDuration'), er.text())
}
else {
$(el).focus();
createErrorBubble($(el), er.text());
}
}
},
The magic here is the .focus() calls to bring the elements back into the view port.