Closing css dropdown using jquery - javascript

Sorry for the vague project title but I'm not having a great idea about how to explain this.
So, let's dive in to it. I was in need of a dropdown list with multiple select options to select recipients from.
I've started my search on Codepen and came across this: https://codepen.io/MaartenTe/pen/mXYLXj
I've forked it so I could tweak it myself. The snippets works perfect. The only thing missing is the ability of closing the dropdownlist when clicking outside of it.
So I started to approach it using javascript. So far I got following code:
$(document).click(function(e) {
var target = e.target; //target div recorded
if (!$(target).is('.multi-select ') ) {
$('.multi-select-options span').css('display', 'none');
$('.multi-select-options label').css('display', 'none');
}
});
Although this isn't working the way I want, I think it's the right approach?

Looking at how that works, its a checkbox that causes the toggle so you need to clear that when you click out the box.
$('.multi-select').on('click', function(e){
e.stopPropagation()
});
$(window).on('click', function(e) {
$('#toggle-open').attr({checked: false})
});
The stopPropagation will stop the window click even firing. https://codepen.io/anon/pen/rdwrya?editors=1111

What works in the given codepen:
var toggle = document.getElementById('toggle-open');
document.addEventListener('click', function(event) {
if (['INPUT', 'LABEL', 'SPAN'].indexOf(event.target.nodeName) + 1) return;
if (toggle.checked) toggle.checked = false;
});
Just handle click, exclude the relevant elements and uncheck if needed.

Related

Handle tab press for any HTML element in jQuery/JavaScript

I'm building a Screen Reader and I'm wanting to navigate through HTML elements on the page using Tab and Shift+Tab presses.
So far, I've got the following code, which works fine:
$('a, input, button').keyup(function(e) {
// code
});
However, the problem I have is the above code will only work for a tags, inputs, and buttons. If I want to add code for a span, or a summary tag, I would have to change the code to:
$('a, input, button, span, summary').keyup(function(e) {
// code
});
I was wondering if its possible to re-write this so that it handles every HTML element. I tried something like:
$('*').keyup(function(e) {
// code
});
But that didn't work. Any help would be appreciated!
Please first read about event propagation. Your event (if not stopped by e.stopPropagation() or e.stopImmediatePropagation()) will be spread to all parents, so it's absolutely enough to do the following.
$(document).keyup(function(e) {
// code
});
Of course you can catch the event on any other level if you need to handle the event on some area but not on whole document. Here's an example of that case when just A1 and A2 buttons wrapped in .containerA div will be handled.
$(function(){
$('.containerA').keyup(function(e) {
if (e.key == 'Tab') {
console.log($(e.target).text());
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="containerA">
<button>A1</button>
<button>A2</button>
</div>
<div class="containerB">
<button>B1</button>
<button>B2</button>
</div>
Talking about the tabbing, you probably need to capture on focus event, but that's not clear so I will stop with this immediate answer of your question.
Thanks to #Reflective for their contribution. Using parts of their answer, I've formed the below, which works:
$(document).keyup(function(e) {
if (e.key == 'Tab') {
console.log($(e.target).text());
}
});
You can then use the $(e.target) to access what you want from the current element.

Detecting a click outside either of two elements?

I've got a little autocomplete dropdown which I want to hide when someone clicks outside the textbox. I've been using this so far
$("#input-group_ids").on("blur", function () {
$(".input-dropdown").hide();
});
However my autocomplete dropdown has an overflow and a scroll bar if there are more than 10 options. When using the above code, clicking on the scroll bar closes the dropdown.
I need the dropdown to close only if the click is outside the textbox AND the dropdown itself. How do I do that?
Not yet tested hope this will work
$("html").click (function () {
$(".input-dropdown").hide();
});
$("#input-group_ids, .input-dropdown").click (function (e) {
e.stopPropagation;
}
In case you won't get clear with the blur event, try to register the click event to an element that is surrounding both the textbox and the dropdown. It may even be the body.
Then in the click event check the event.target element. If it is neither the textbox nor the dropdown, close it.
It feels clumsy, I know, but it is one of several working options.
Try this :
$("*:not(#input-group_ids)").on("click", function () {
$(".input-dropdown").hide();
});
Not tested because you didn't gave any jsfiddle
Have you tried the not selector the name explains it all and might work if you have a container on the dropdown and textbox
a little hackish but might work.
$(elementContainingTheDropDownContent).on('mouseleave', function(e){
$(window).on('click', function(e){
//close dropdown
})
}).on('mouseenter', function(){
$(window).off('click');
})
I found another answer to this which is actually the best version I think
$(document).click(function(e) {
if (!$('#input-group_ids').is(e.target) && !$('.input-dropdown').is(e.target))
$('.input-dropdown').hide();
});
This is slightly better than Benjamin's answer as it doesn't stop propagation of any clicks on $("#input-group_ids"), which may have unintended consequences. However I'm accepting Ben's answer as it worked and solved my problem, and he deserves the credit. =)
EDIT: Actually my version is pretty similar to #singe31's version, so I upvoted that one too

Dropdown Box disappear on click away

This is my first post on here and I'm just learning Jquery so please be kind! :)
I have just created a website - www.wayfairertravel.com and I have some dropdown boxes on my homepage, where users can search 'By Style' etc...
At the moment once those boxes are opened you have to close them manually... I'm just wondering if there is a way to change the code there currently so that when a user clicks elsewhere on the page it disappears.
Any help greatly appreciated. If you you could be as precises in your answer that would be great - I.e where to change the code and what to change to.
Cheers,
Harry
Usually, you add events on body and on the desired dropdown:
$(document.body).on('click', function() {
dropdown.close(); // .hide(); whatever
});
dropdown.on('click', function(event) {
event.stopPropagation(); // prevents dropdown from getting closed when clicking on it
});
However, I think there are jQuery plugins for clickOutisde events that you could use too (they probably work like mentioned above, but you don't have to write it yourself).
I took Jakub Michálek advice and applied it your code. I prepared fiddle so you can test it out: http://jsfiddle.net/tmuuS/
This is your javascript you want to have on your page:
$(document).ready(function () {
$("#expslider").hide();
$("#expshower").show();
$('#expshower').click(function () {
$("#expslider").slideToggle();
});
$(document.body).on('click', function () {
$("#expslider").slideUp();
});
$("#expslider").on('click', function (event) {
event.stopPropagation(); // prevents dropdown from getting closed when clicking on it
});
$("#expshower").on('click', function (event) {
event.stopPropagation(); // prevents dropdown from getting closed when clicking on it
});
});
Although remember that it's better to have javascript in head tag, not right beside the place where you use it. (hard to look for it later when you need changes)

How to trigger a function if ANY link is clicked, by using jQuery?

I'm a jQuery newbie and I've spent hours trying to find the answer to this and the documentations didn't help me much.
I simply want to change the style of:
#footer_menu{bottom:0;}
to
#footer_menu{bottom:-48px;}
once ANY link on the page is clicked. No IDs whatsoever, I just want to be able to trigger that function whenever ANY link is clicked.
I'm starting to wonder this is not at all possible and it should be done by adding IDs to the A tags. is this true and what's the best way to achieve this?
Try like this, Demo on JsFiddle
$('a').click(function() {
$('#footer_menu').css('bottom', '-48px');
});
$('a').on('click', function(e) {
$('#footer_menu').css('bottom', '-48px');
e.preventDefault();
}
$('a').on('click', function(event) {
$('#footer_menu').css('bottom', '-48px');
event.preventDefault(); // only if links should not navigate afterwards
});
You just basically select all anchors with $('a').

Preventing select menu from opening

Possibly a silly question, but how do I prevent a select element in a form from showing its drop down menu when it's clicked on? I tried the following:
$('select').click (function (e) {
console.log (e);
return false;
});
and
$('select').click (function (e) {
e.preventDefault ();
console.log (e);
});
But neither worked.
What am I doing wrong?
EDIT: The reason I need to know is for a jquery enhanced select element that needs to degrade gracefully. The idea is the select, when clicked, opens a jquery UI dialog with a nicely maked up list that the user makes their selection from (clicking a list item causes the select's value to update). If JS is disabled then the select should just operate as normally.
The problem is that as well as the dialog opening, the dropdown also appears, which is not what I want. I can't just disable the control, as its value needs to be submitted along with the rest of the form.
This should work:-
$('#select').on('mousedown', function(e) {
e.preventDefault();
this.blur();
window.focus();
});
The problem is that you're using the wrong event.
<select onmousedown="(function(e){ e.preventDefault(); })(event, this)">
<option>Some Option</option>
</select>
JsFiddle
From my experience, if i need to disable something, the easiest way to have another invisible element on it (use absolute positioning). When you want to allow default behavior again, you just hide absolute element.
I believe the best solution would be to replace the select element with something else to click on (a button or a link).
BTW, you may want to look into the CSS 3 property appearance, which theoretically allows you to let that replacement element look like a dropdown. Support is however currently very limited:
http://css-infos.net/property/-webkit-appearance
https://developer.mozilla.org/en/CSS/-moz-appearance
You can, the trick is to cancel the mousedown event, not the click. The event chain is made in such a way that click and mouseup cannot occur if mousedown was cancelled:
function cancelDropDown(ev) {
ev.preventDefault();
}
document.getElementById("selectElement").addEventListener("mousedown", cancelDropDown, false);
Hide the select options on page load (if Javascript enabled). They will not display when the select box is clicked, but the text of the first option ("Select an option", or whatever) will still appear in the select field.
$(document).ready(function() {
$('#idOfSelect option').css('display', 'none');
});
Updated Solution:
$(document).ready(function() {
$('#idOfSelect').focusin(function() {
$(this).css('display', 'none');
$('body').click(function(event) {
$(this).unbind(event);
$('#idOfSelect').css('display', 'block');
});
});
});
I just solved this exact problem, by manipulating the 'size' attribute of select. Not very elegant, but worked. Hope its of some help to you.
<!-- Example select dropdown -->
<select id="select" onclick="tackleDropdown()">
</select>
<!-- The JS function -->
<script>
function tackleDropdown(){
document.getElementById('select').setAttribute('size', 0);
// your code for displaying the jQuery UI dialog (is it colorbox???)
// re-enabling the drop down
document.getElementById('select').setAttribute('size', document.getElementById('select').options.length);
}
</script>
Use disabled
$(this).attr("disabled","disabled");
Some good answers here. But still I had to make some additions.
$(document).on('keydown mousedown touchstart', 'select.disabled', function (e) {
e.preventDefault();
})
A simple solution based on CSS is this small fragment:
select:read-only * {
display: none;
}
This will make the options not available when the select is selected. This action mimics the behavior of the "readonly" attribute of the input.

Categories