Jquery: please help explain this code because I need to tweak it - javascript

Can someone explain this to me? I'm trying to understand exactly why drop down lists inside a li tag work okay but when using a form the menu disappears when clicked anywhere.
menu.find('ul li > a').bind('click', function (event) {
event.stopPropagation();
}
It works in combo with:
$("html").click(function() {
menu.find('.active').removeClass('active');
});
Full code with menu example:
http://jsfiddle.net/e4yy4/

This bit of code
$("html").click(function() {
menu.find('.active').removeClass('active');
});
would remove the active class of the menu and so hide it when ever a click is detected anywhere on the page.
But
menu.find('ul li > a').bind('click', function (event) {
event.stopPropagation();});
Would override the first piece of code when the click is detected in the drop down list.
So you can add the below code to override the first piece of code so it also cancel the hiding when clicking in the form.
menu.find('ul > form').bind('click', function (event) {
event.stopPropagation();});
Just like this
http://jsfiddle.net/Quincy/e4yy4/3/

You also want to stop form events propagating to html (should probably be document).
Change the selector to select descendent form elements too.
jsFiddle.

If you change the first check to menu.find('ul li>*') then it seem to work.
I think that line was only handling clicks on links, and your form elements aren't links.

<form> is an element just like any other, as such, it should be eligible for selection using the CSS selectors (which are called by the find() function).
You need to change your selector to include the <form> tag and possibly change the selector to pickup on <input> elements instead of <a>.
For more information on jQuery selectors, please see: http://api.jquery.com/category/selectors/

Related

Switch <li> active element

Here is a link for a fiddle project I am working on right now. What I am trying to do is to switch active menu element depending on what section is displayed right now on screen. So if it is Kontakti on screen, then Kontakti in menu (<!--NAV BAR-->) has to display as active item. I am not familiar with jS
Add data-role=navigate attribute to ul element where navigation is housed,
In the javascript section of this fiddle,
please try with the following code,
$(function()
{
$("[data-role=navigate]").find("li > a").click(function()
{
$(this).parents("ul").find("li.active").removeClass("active");
$(this).parent().addClass("active");
})
})
I will explain in brief what the code does...
1) Binds a click event handler to <a> inside <li> which is inside <ul> with attribute data-role=navigate
2) When the click happens, it removes the active class for the current element.
3) Assigns the active class to the immediate parent of the <a>
It is a good practice to target specific needs in JS by placing attribute in the DOM elements and hooking up event listeners using that attribute.
Hope it helps!
Bootstrap's Affix might be something that could be useful in this case. It highlights what part of the page is displayed on the screen on a separate sub-navigation part of the page.
Btw, if you have Bootstrap code you can display it on Bootply quite easily. It provides Bootstrap's CSS and JavaScript files by default.
You say you're not familiar with JavaScript but you're asking for functionality that needs JavaScript. I'd recommend trying to use a plugin if it's not something you can write yourself.
Waypoints would do exactly what you're looking for:
http://imakewebthings.com/waypoints/guides/getting-started/

Wordpress Mobile Menu JQuery Selector Trouble

I’m having trouble with a small mechanics difference between a full-view menu and a mobile-view menu (using the same ul>li>a structure). In the mobile view, the menu hides until the .showMe class is added to its parent div. No problem there, but when I try to select the submenus by using .showMe in the selector chain (in order to perform jQuery actions only when in mobile mode), the script breaks and the dependent actions never occur.
The chunk of selecting code in question is here:
$('.showMe .menu-item-has-children > a').click(function(event){
// prevent default link behavior
if (!($(this).siblings('.sub-menu').hasClass('expanded'))) {
event.preventDefault();
}
// close down any open submenus
$('.sub-menu').removeClass('expanded');
// expand the clicked link’s child ul
$(this).siblings('.sub-menu').toggleClass('expanded');
});
If I remove the .showMe selector from the top line, the effect works great.
See the live site for testing here: http://www.wwva.org.php53-14.ord1-1.websitetestlink.com/students
I feel like I’m going crazy here—what am I missing?
Thanks in advance.
Answered in comments—thanks adeneo!
"The event handler is only added to the elements that match the selector at the time it's bound. Adding a class later means the event handler won't work for those elements, as they didn't match the selector when the event handler was bound. ... You can check for the class inside the event handler."

Run jQuery function onclick

so i implemented a bit of jQuery that basically toggles content via a slider that was activated by an <a> tag. now thinking about it id rather have the DIV thats holding the link be the link its self.
the jQuery that i am using is sitting in my head looks like this:
<script type="text/javascript">
function slideonlyone(thechosenone) {
$('.systems_detail').each(function(index) {
if ($(this).attr("id") == thechosenone) {
$(this).slideDown(200);
}
else {
$(this).slideUp(600);
}
});
}
</script>
i was using this as a index type box so there are several products when you click on the <a> tag that used to be an image* it would render a bit of content beneath it describing the products details:
<div class="system_box">
<h2>BEE Scorecard database</h2>
<p>________________</p>
</div>
the products details are wrapped in this div.
<div class="systems_detail" id="sms_box">
</div>
so when you click on what used to be a image* it would run the slideonlyone('div_id_name') function. the function above then first closes all the other divs with the class name 'system details' and then opens/slides the div with the id that was passed into the slideonlyone function. that way you can toggle products details and not have them all showing at once.
note i only kept the <a> tag to show you what was in there i will be getting rid of it.
note: i had an idea of just wrapping the whole div in an <a> tag but is that good practice?
So now what i am wondering is since you need JavaScript to run onclick on a div tag how do you write it so that it still runs my slideonlyone function?
Using obtrusive JavaScript (i.e. inline code) as in your example, you can attach the click event handler to the div element with the onclick attribute like so:
<div id="some-id" class="some-class" onclick="slideonlyone('sms_box');">
...
</div>
However, the best practice is unobtrusive JavaScript which you can easily achieve by using jQuery's on() method or its shorthand click(). For example:
$(document).ready( function() {
$('.some-class').on('click', slideonlyone('sms_box'));
// OR //
$('.some-class').click(slideonlyone('sms_box'));
});
Inside your handler function (e.g. slideonlyone() in this case) you can reference the element that triggered the event (e.g. the div in this case) with the $(this) object. For example, if you need its ID, you can access it with $(this).attr('id').
EDIT
After reading your comment to #fmsf below, I see you also need to dynamically reference the target element to be toggled. As #fmsf suggests, you can add this information to the div with a data-attribute like so:
<div id="some-id" class="some-class" data-target="sms_box">
...
</div>
To access the element's data-attribute you can use the attr() method as in #fmsf's example, but the best practice is to use jQuery's data() method like so:
function slideonlyone() {
var trigger_id = $(this).attr('id'); // This would be 'some-id' in our example
var target_id = $(this).data('target'); // This would be 'sms_box'
...
}
Note how data-target is accessed with data('target'), without the data- prefix. Using data-attributes you can attach all sorts of information to an element and jQuery would automatically add them to the element's data object.
Why do you need to attach it to the HTML? Just bind the function with hover
$("div.system_box").hover(function(){ mousin },
function() { mouseout });
If you do insist to have JS references inside the html, which is usualy a bad idea you can use:
onmouseover="yourJavaScriptCode()"
after topic edit:
<div class="system_box" data-target="sms_box">
...
$("div.system_box").click(function(){ slideonlyone($(this).attr("data-target")); });
You can bind the mouseenter and mouseleave events and jQuery will emulate those where they are not native.
$("div.system_box").on('mouseenter', function(){
//enter
})
.on('mouseleave', function(){
//leave
});
fiddle
note: do not use hover as that is deprecated
There's several things you can improve upon here. To start, there's no reason to use an <a> (anchor) tag since you don't have a link.
Every element can be bound to click and hover events... divs, spans, labels, inputs, etc.
I can't really identify what it is you're trying to do, though. You're mixing the goal with your own implementation and, from what I've seen so far, you're not really sure how to do it. Could you better illustrate what it is you're trying to accomplish?
== EDIT ==
The requirements are still very vague. I've implemented a very quick version of what I'm imagining you're saying ... or something close that illustrates how you might be able to do it. Left me know if I'm on the right track.
http://jsfiddle.net/THEtheChad/j9Ump/

How do I hide an element with the same markup via jquery?

I have two custom dropdown lists that have the same markup. I need to have only one show at a time. Right now, I'm able to open both at the same time. Both should also close when I click off the list.
The same markup for both lists is required, so I can't use unique ID's or additional classes to make this happen.
Here is a link to my fiddle example: http://jsfiddle.net/dg7Lc/29/
Any help would be greatly appreciated, thanks!
-D
Consider adding a data attribute such as 'active' via jquery when you click on one of them, then hide all those that have that attribute.
$('.custom-select').eq(0).hide() will hide the first one.
Use .show() instead of .hide() to show (obviously) and change the index to (1) to get the second one.
First thought would be if you could wrap a span or div around either or both and use that to get around the "same markup" limitation. Other than that, though, I'd suggest using order in page - use .next() and .prev() to get between them, and something like
$("div.custom-select").get(0)
or
$("div.custom-select").get(1)
to select them from outside.
edit: if you can run them off of something like an onmouseover, onchange, or whatnot, it's even easier - the one that's changing will be passed into the function as the "this" parameter. Just hide both, and show this, or show both and hide this.
edit2: similarly, once you have one of them hidden properly - well, that one will be hidden, and respond to the ":hidden" selector. Use that to distinguish between them (and save the distinction as a jquery variable) before you go showing or hiding anything else
Hide the first:
$('.custom-select').first().hide();
Hide the second:
$('.custom-select').last().hide();
And then put these lines of code where needed.
http://jsfiddle.net/dg7Lc/31/
Basically, closing the others:
$('.custom-select').not(this).find('ul').slideUp('fast');
And for closing when clicking outside the box, I used this piece of code but it's a bit dirty:
$("body").click(function(e) {
var should = true;
for($e = $(e.target); should && $e.length; $e = $e.parent()) {
should = !$e.is(".custom-select");
}
if(should) {
$('.custom-select').find('ul').slideUp('fast');
}
});
You can bind a click to the document, that looks to see if they clicked on the custom-select or the document outside it and hides any open lists as it should:
$(document).click(function(ev){
if(!$(ev.target).is('.custom-select span')){ $('.custom-select').find('ul').slideUp('fast'); }
});
Updated JSFiddle

jQuery change css of an element when another element becomes active

I am trying to change the background colour of a label adjacent to an input element when the input becomes 'active'.
This will need to work for both clicking to the input and tabbing between input elements.
I was able to get this to work if the user clicked the input, but my solution didn't work if the user tabbed into an input element. I was also having to repeat the code for each input element. Considering I am likely to have quite a few input elements, I figured there must be a more graceful way?
Here is a link with the basic HTML + CSS.
http://jsfiddle.net/xXqhH/
Assuming I've understood what you're trying to do correctly, just bind event handlers to the focusin and focusout events. You can use prev to find the immediately preceding sibling, and css to set a CSS property:
$("input").focusin(function() {
$(this).prev("label").css("background-color", "red");
}).focusout(function() {
$(this).prev("label").css("background-color", "gray");
});
Here's an updated fiddle.
I lied in my comment - I am going to write this from scratch. I assume the problem you had where it was working with clicking, but not with tabbing, was due to using the .click() jQuery function. Using .focus() instead, along with a CSS class, should provide the desired result:
jQuery code:
$('input:text').focus(function(e) {
$('label').removeClass('active');
$(this).prev('label').addClass('active');
});
Extra CSS:
label.active {
background: red !important;
}
Working Demo

Categories

Resources