jQuery - Is it possible to have separate onHover and onClick events? - javascript

I am currently building a website that uses alot of jQuery, it involves having an interactive map.
There will be points on the map, but what I need is, when you hover over the map point, a small description is shown (perhaps in a div called .mapitem-smalldescription) and then when you CLICK on the map point, a much larger full description with pictures would be shown (in another div called, for example .mapitem-fulldescription)
I know how to do onclick and onhover events on SEPERATE map points, but I have not been able to successfuly combine them together onto a single map points.
How can I do this please?
Zach

Assuming that each map point will have the class mappoint:
$('.mappoint').hover(function() {
//do something on mouseover...
}, function() {
//do something on mouseout...
}).click(function() {
//do something on click...
});

If each one of your map points had the class point this might work:
Try this: http://jsfiddle.net/nrwyz/8/ .
Code:
HTML
<div class="point">
</div>
Javascript
$(".point").live("mouseover", function() {
//code to show description
$(this).append('<div class="mapitem-smalldescription">Small description</div>');
});
$(".point").live("mouseout", function() {
//code to show description
$(".mapitem-smalldescription").fadeOut(200);
});
$(".point").live("click", function() {
//code to full description
$(this).append('<div class="mapitem-fulldescription">Full description</div>');
});
CSS
.point {
width: 40px;
height: 40px;
border-radius: 100px;
background-color: #550000;
}
.mapitem-smalldescription {
width: 100px;
height: 100px;
background-color: #00FF00;
}
.mapitem-fulldescription {
width: 100px;
height: 100px;
background-color: #FF0000;
}
EDIT: Here is a version which behaves more closely to the way you described: http://jsfiddle.net/nrwyz/23/ .
Let me know if there is anything else you need modified or added.
I hope that helps!

Related

Click Propagation failing in Jquery

For part of the site I'm working on, I have a set of sidebars that can pull out. To have them hide when the users are done with them, I've set up a div with a click event (see below) so that whenever the user clicks somewhere outside of the sidebar, the sidebar closes. The problem that I'm running into, however, is that the click event handler is grabbing the event, running its method, and then the click event seems to stop. I've tried using return true and a few other things I've found around here and the internet, but the click event just seems to die.
$('.clickaway').click(function() {
$('body').removeClass(drawerClasses.join(' '));
return true;
});
EDIT: Here is a fiddle with an example: https://jsfiddle.net/2g7zehtn/1/
The goal is to have the drawer out and still be able to click the button to change the color of the text.
The issue is your .clickaway layer is sitting above everything that's interactive, such as your button. So clicking the button, you're actually clicking the layer.
One thing you could do is apply a higher stacking order for elements you want to interact with, above the .clickaway layer. For example, if we apply position: relative, like this:
.show-drawerHotkey .ColorButton {
position: relative;
}
The element will now be in a higher stacking order (since it comes after the clickaway, and we've applied no z-index to clickaway)
Here's a fiddle that demonstrates: https://jsfiddle.net/2g7zehtn/5/
Using this somewhat famous SO answer as a guide, you can bind to the $(document).mouseup(); event and determine whether certain "toggling" conditions apply:
[EDIT] - Example updated to illustrate clicking a link outside of the containing div.
// Resource: https://stackoverflow.com/questions/1403615/use-jquery-to-hide-a-div-when-the-user-clicks-outside-of-it
var m = $('#menu');
var c = $('#menuContainer');
var i = $('#menuIcon');
i.click(function() {
m.toggle("slow");
});
$(document).mouseup(function(e) {
console.log(e.target); // <-- see what the target is...
if (!c.is(e.target) && c.has(e.target).length === 0) {
m.hide("slow");
}
});
#menuIcon {
height: 15px;
width: 15px;
background-color: steelblue;
cursor: pointer;
}
#menuContainer {
height: 600px;
width: 250px;
}
#menu {
display: none;
height: 600px;
width: 250px;
border: dashed 2px teal;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
I'm a link outside of the container
<div id="menuContainer">
<div id="menuIcon"></div>
<div id="menu"></div>
</div>

Unable to override click events to anchor tag from a user created function

I don't know how to explain my situation, please edit my question if you can explain it more clearly.
I am able to override click events of anchor tag from window.load or document.ready but the problem comes when I am trying it from a user created function.
My JavaScript code is:
$('#up').click(function(){
$('#Vote').html("<div id=\"aniDiv\" style=\"background:green;height:25px;width:80px;position:absolute;float:left\" class=\"base\"></div><div class=\"overlay\"><a style=\"text-decoration:none;color:black\" id='unvote' href=\"#\">You upvoted. Click to take vote back.</a></div>");
$("#aniDiv").animate({width:"10px"});
$("#Vote").width("350px");
attachUnvote();
});
$('#down').click(function(){
$('#Vote').html("<div id=\"aniDiv\" style=\"background:red;height:25px;width:50px;position:absolute;float:left\" class=\"base\"></div><div class=\"overlay\"><a style=\"text-decoration:none;color:black\" id='unvote' href=\"#\">You downvoted. Click to take vote back.</a></div>");
$("#aniDiv").animate({width:"10px"});
$("#Vote").width("350px");
attachUnvote()
});
function attachUnvote()
{
$('#unvote').click(function(){
$('#Vote').html("<a style='text-decoration:none;background-color:green;padding:3px;color:white;' id='up' href='#'>Up</a><a style='text-decoration:none;background-color:red;padding:3px;color:white' id='down' href='#'>Down</a>");
});
}
My objective is that after attachUnvote() function sets the HTML of #Vote element, then it should call the code just above attachUnvote() function. I tried to enclose the code above it in another function and called that function in attachUnvote() but its not working.
You can find Live Demo, HTML and CSS here: http://jsfiddle.net/aishwaryashivapareek/xV3x8/
You can avoid having to attach and unattach these event handlers by using a delegated event handler on the #Vote wrapper.
Your updated code would look like this:
$('#Vote').on('click','#up',function(){
$('#Vote').html("<div id=\"aniDiv\" style=\"background:green;height:25px;width:80px;position:absolute;float:left\" class=\"base\"></div><div class=\"overlay\"><a style=\"text-decoration:none;color:black\" id='unvote' href=\"#\">You upvoted. Click to take vote back.</a></div>");
$("#aniDiv").animate({width:"10px"});
$("#Vote").width("350px");
});
$('#Vote').on('click','#down',function(){
$('#Vote').html("<div id=\"aniDiv\" style=\"background:red;height:25px;width:50px;position:absolute;float:left\" class=\"base\"></div><div class=\"overlay\"><a style=\"text-decoration:none;color:black\" id='unvote' href=\"#\">You downvoted. Click to take vote back.</a></div>");
$("#aniDiv").animate({width:"10px"});
$("#Vote").width("350px");
});
$('#Vote').on('click','#unvote',function(){
$('#Vote').html("<a style='text-decoration:none;background-color:green;padding:3px;color:white;' id='up' href='#'>Up</a><a style='text-decoration:none;background-color:red;padding:3px;color:white' id='down' href='#'>Down</a>");
});
Event delegation is the way to go.
I might be nitpicking here but this also makes coding fun instead of falling into a spaghetti mess. Have some pointers which would make your life easier.
Avoid inline styles. use classes instead. (Would help in separation of concerns)
Use functions to avoid repetitive code.
HTML
<div id='Vote' style="margin:0">
<a class="p-small bg-green" id='up' href="#">Up</a>
<a class="p-small bg-red" id='down' href="#">Down</a>
</div>
CSS
body {
font-family:'segoe ui'
}
.overlay {
width: 100%;
height: 100%;
position: absolute;
left: 10px;
z-index: 10;
}
.base {
width: 100%;
height: 100%;
position: absolute;
left: 0px;
}
/* Default styling for anchors */
a {
text-decoration:none;
color: white;
}
.p-small {
padding: 3px;
}
.bg-red {
background-color:red;
}
.bg-green {
background-color:green;
}
.black {
color: black;
}
#aniDiv {
height: 25px;
width: 80px;
}
JAVASCRIPT
var $defaultDiv = "<a class='p-small bg-green' id='up' href='#'>Up</a>"
+ "<a class='p-small bg-red' id='down' href='#'>Down</a>",
$animatedDiv = "<div id='aniDiv' class='base {{bg}}'></div>"
+ "<div class='overlay'>"
+ "<a class='black' id='unvote' href='#'>You {{vote}}. Click to take vote back.</a></div>";
$('#Vote').on('click', '#up', function() {
animateDiv("bg-green", true);
});
$('#Vote').on('click', '#down', function() {
animateDiv("bg-red", false);
});
$('#Vote').on('click', '#unvote', function() {
$('#Vote').html($defaultDiv);
});
function animateDiv(bgColor, upVoted) {
$('#Vote').html($animatedDiv.replace("{{bg}}", bgColor)
.replace("{{vote}}", upVoted ? "upvoted" : "downvoted"));
$("#aniDiv").animate({
width: "10px"
});
$("#Vote").width("350px");
Working Fiddle

Toggleable on click tooltip from dynamic HTML

I am trying to get a tooltip to open or close (toggle) based when clicked on.
The HTML is generated dynamically from javascript but here is an example of one of the elements that I want to have a tooltip when clicked:
<label class="passiveText smallText" title="Name: Smith, John , Occupation Code: BA81, Occupation
Description: BUSINESS SYSTEMS M" rel="tooltip" style="margin-top:10px; width:80%; text-decoration:underline;
color:#009245;" containeridx="0" id="lblBadge_7022_0">7022</label>
On the page show I am trying to add the following code so when clicked
$(document).on("pageshow", "#DailyFrm", function () {
$('[id*="lblBadge"]').on('click', function (e) {
$(this).tooltip('open');
});
}
This isn't even getting the the tooltip to open in the first place. What am I doing wrong?
Edited
Styleless implementation of the tooltip (jsfiddle) for your html:
$('[id*="lblBadge"]').on('click', function (e) {
var $this = $(this);
var $tooltip = $this.children('.tooltip');
if ($tooltip.length > 0) {
$tooltip.remove();
return true;
}
$tooltip = $('<div>');
$tooltip.addClass('tooltip');
$tooltip.text( $this.attr('title') );
$this.append($tooltip);
});
And styles:
label { // choose appropriate selector
position: relative; // required for positioning
overflow: visible; // required for guaranteed tooltip visibility
}
.tooltip {
position: absolute; // required for positioning
// Relative to the parent label
top: 35px;
left: 20px;
// Not necessary but recommended for the good look
width: 250px;
// optional
background: lightgray;
color: black;
}
I'm recommend to use beautiful solution provided by Osvaldas Valutis: http://osvaldas.info/elegant-css-and-jquery-tooltip-responsive-mobile-friendly
Check live demo from mobile.

Jquery text toggle

I am trying to make a jquery text toggle. If you rollover the element, the text appears next to it and vice versa, it dissappears when you leave the element area.
My code does not work yet. Also, i would like to include different texts for different links. If there is a simpler way please suggest.
HTML
<div id="container"></div>
clickclickclick
JS
$("#ovr").mouseenter(function() {
$(#container).html("wazaap");
}).mouseleave(function() {
$(#container).html();
});
You are forgetting the quotes in the jQuery selector:
$("#ovr").mouseenter(function() {
$("#container").html("wazaap");
}).mouseleave(function() {
$("#container").html("");
});
Edit
If you want different sentences, you can do this:
JS
var description=new Array();
description["one"]="Here comes the first";
description["two"]="And here the second";
description["three"]="Now let's have the third";
description["four"]="Finally the last one, fourth";
$("a.link").mouseenter(function(){
$("span#description").text(description[$(this).attr("id")]);
}).mouseleave(function(){
$("span#description").text("");
})​
HTML
one
two
three
four
<span id="description"></span>​
Check working here
http://jsfiddle.net/Wpe2B/
Try to do it with hover() function. Code will be cleaner.
Basic example:
jQuery:
$("#container").hover(
function() {
$('.cText').text("click");
},
function() {
$('.cText').text("");
});
CSS:
#container {
position: relative;
background-color: #EEEEEE;
width: 100px;
height: 100px;
position: relative;
display: block;
}
HTML:
div id="container"></div><span class="cText"></span>
Regards
Update
Base on OP's comments wanting to use several links to show text I tried this:
http://jsfiddle.net/cZCRh/4/
It doesn't quite work with a class because all links get the same text
This works http://jsfiddle.net/cZCRh/1/
<div id="container"></div>
clickclickclick
$("#ovr").mouseenter(function() {
$('#container").html("wazaap");
}).mouseleave(function() {
$("#container").html("");
});
​
The problem was the mouseleave was in the wrong place as well as missing quotes around the element IDs

Stacking notification bars

I like the notification bars used in stackoverflow. I have found a jQuery plugin which makes the notification bar possible with just a few lines, but this plugin does not seem to stack multiple notifications bars when required.
Does anyone know of a better plugin or how to get the plugin below to stack bars as more notifications become available?
http://www.dmitri.me/blog/notify-bar/
...
<body>
<div id="notificationArea"></div>
<!-- rest of your website -->
</body>
</html>
Then to create notifications just do this in jquery:
$('#notificationArea').prepend('<div class="notification">This is my notification</div>');
its a bit basic, but this should do the trick, and because you are "prepending" you will get the stacking you are looking for. You can use append() too, but I was assuming you'd want the most recent notifications on the top.
To get the "X" (close) button just have a link in the notification with a class of notifcationClose and do:
$('.notificationClose').click(function(){ $('this').parents('.notification').remove(); })
I know that you are looking only for bar plugin, but I write my opinion. Imagine that you have more than 2 notifications in this bar. It grows and it could fill more space than you would like to. Instead of viewing results of action, user will see only notifications to half display of monitor :)
Try to consider using bar notifications, if you know that you will have more than one notification in time often.
I recommend jGrowl which is similar to the way that in OS X works. It is simple, good-looking and ready for many notifications in time.
good luck.
I wrote this piece of Javascript that does just that.
// 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.

Categories

Resources