I have a mess of js right now and there are too many things across a bunch of different files (inherited) and I'm having trouble with one last piece.
I have a modal containing a form and everything works fine except the selectboxes. Once the user clicks the select box it fires the close function. I've tried everything I can remember but I can't remember the proper terms for what I'm trying to do so I can't google it.
Here's a quick fiddle
Code:
<div class="modal">
<select>
<option>Select an option</option>
<option>1</option>
<option>2</option>
</select>
</div>
And js:
$(document).click(function(){
if(!$(event.target).is(".modal")){
$(".modal").hide();
};
});
This works normally for anything I put in there except selectboxes.
UPDATE: Ok so I was completely wrong with this question and made a few incorrect assumptions in my testing. This is not related to selectboxes but specifically to jQuery datepicker-ui selects. So this question is a duplicate of a few others on Stackoverflow and it can be closed as duplicate. One of the duplicate questions I found was: Implementing jQuery DatePicker in Bootstrap modal
The event.target refers to the element from where the event originated, so when you click on the select element e.target is the select element then the $(event.target).is(".modal") test will fail.
So the solution is to check whether the event's target is inside a .modal element for which you can use .closest() as below
$(document).click(function(){
if(!$(event.target).closest(".modal").length){
$(".modal").hide();
};
});
Demo: Fiddle
Related
I am having an issue with a couple of my pages.
Essentially I am using JQuery to display followup questions using SlideDown. In addition to this, after clicking the Q2 radio button, we make a JSON request to get the drop down values for Q3.
However if you select the drop down value before the page has completed loading, on selecting the radio on Q2, Q1 dropdown clears back to empty.
I have tried moving all the javascript code to the top to no avail. This is not a problem if the page has completed loading however.
Is there a way to disable or hide the dropdown until the page has fully loaded?
Cheers
Ryan
Working DEMO
Initially set disabled property in HTML:
<select id="dropdown" style="width:200px;" disabled>
<option value="feedback" name="aft_qst">After Quest</option>
<option value="feedback" name="aft_exm">After Exam</option>
</select>
on dom ready use following to remove disabled property.
$(document).ready(function(){
$("#dropdown").prop("disabled", false);
});
You should use the ready function of jQuery, what you put inside will be executed when the DOM is fullly loaded
$(function() {
// Enable your dropdown
});
more info:
http://api.jquery.com/ready/
TL;DR how can I get this self-explanatory JSFiddle to work?
From the W3C:
The blur event occurs when an element loses focus either via the pointing device or by tabbing navigation. This event is valid for the following elements: LABEL, INPUT, SELECT, TEXTAREA, and BUTTON.
The basic idea, HTML:
<form>
<label>
<input type="text" />
after focusing in input, there should be no blur when clicking here
</label>
</form>
but blur should fire when clicking here
And JS:
$("form, label").on("blur", function() {
alert("you're not going to see this");
});
It doesn't work. A more illustrative example is in this JSFiddle.
I also tried focusout, with this JSFiddle, but (presumably because it bubbles up from the input), it always fires.
I could probably rig up what I need with a hack like this: https://stackoverflow.com/a/5049387/458614 but I'd rather not have to.
Edit: There are lots of related questions and I have read all that I could find, none of which help. Some talk about setting tabindex=0 on the form or label elements. I have tried this in various permutations but it doesn't help. JSFiddle here. If you put it on the form, blur events do fire when you click outside the form. However, it doesn't apply to any of it's children: it won't pick up anything if you click on the input and then outside the form.
Edit 2: I don't really understand some of the answers posted so far and none seem to really... work. Anyway, to clarify, here is what I am trying to accomplish:
In my app, you can add tags to documents. When you click the "add tag" button, a previously-hidden text input field pops up and is focused. And then...
Clicking outside (on blur) should close the text input field again
Pressing enter should add the tag and close the input field
Clicking the "add tag" button should also add the tag and close the input field
The problem is that #1 and #3 are incompatible. The "add tag" button needs to perform a different action based on whether the text field is open or closed, but because I can only achieve #1 with an onblur event on the text field, the text field is closed by the time any action happens on the "add tag" button for #3.
Here is a JSFiddle with my best attempt so far.
The thing I think you are looking for is
e.stopPropagation();
This Fiddle here shows a little different way to handle it ... it put the hide on a window click (which would blur the input anyways) except on the label, which it would allow the click event to stop inside the label.
Happy coding!
use the below code to achieve the desired
$(document).on("blur", "label",function() {
$("div").append("form or label blurred<br>");
});
Here is the demo Fiddle
Try this it should work
.focus {
border-color:red;
}
$(document).ready(function() {
$('input').blur(function(){
$('input').removeClass("focus");
})
.focus(function() {
$(this).addClass("focus")
});
});
Add this piece of js in your Fiddle. you added listener for label but blur happens on anchor tag.
$("form a").on("blur", function() {
$("div").append("form or label blurred<br>");
});
according to your explanation i have create a demo
$("form > label >a").on("blur", function() {
return false
});
$("#outsideform > a").on("blur", function() {
alert("but blur should fire when clicking here");
});
Check the Demo here
For a while, I am posting an intermediate development. But this definitely will help you where exactly you should look for. The jquery implementation but not your javascript.
This is the real concern.
I have added 3 lines at different places. no big changes.
Added an || $("input").css("visibility") == "visible" to the if
condition
Added $("input").css("visibility","hidden"); to the inner else condition
$("input").css("visibility","visible"); to the outer (and last) else condition.
Please note this is intermediate, you need to click twice after a submit of non-empty text.
If I get time, I would post the correct working thing.
This is the fiddle.
tobek, your JSFiddle with my best attempt so far is almost there. The problem is your selector at the bottom in this section of code:
$("input").on("blur", function(){
$("input").hide();
});
You stated the problem correctly in your comments when you said: "THE PROBLEM: we never get in here because it's already been hidden because the input blurred".
Change the above section to this and I think you'll have what you're looking for.
$("input-blur label").on("blur", function(){
$("input").hide();
});
Because the "Add tag" link is inside the label clicking it doesn't trigger your "blur" function.
This question has been asked tons of times, however I don't see any answer for the 'multiple' variety:
http://jsfiddle.net/queZ6/107/
When you tab INTO the box, i want to display an alert and capture the focus event. I'm basically wanting to change the highlighting for an element that surrounds each input, that follows along as you fill out the form. It's basically a signal to the user to easily see what field their on.
I can't for the life of me figure out how to capture the focus event though tabbing into the box (or also clicking on it obviously).
I dont see why this is difficult, considering you're typing INTO an input. Cant javascript see the newly created input (that youre typing into) and bind to that? JS is so confusing to me sometimes :S
Because the element is created dynamically, you will need to use event delegation, using jquery's on. This will allow you to attach a handler before the element exists.
$('.chzn-choices').focus(function(e){
would instead be
$("container").on("focus", '.chzn-choices',function(e){
where container is a selector for some static ancestor element which is not dynamically loaded. If no such container exists, document can be used, though this is to be avoided where possible.
Update:
While the old answer stated that you cannot bind into dynamically created elements(and this is still true to a degree), updates to the plugin in question have made this no longer a problem.
While the plugin in question still has a problem of triggering the handler multiple times, in the case of an alert message being used, it is now possible to bind to those dynamically created elements thanks to the updates.
All one must do in order to do this is bind, via .on(), to the chosen:showing_dropdown event on the original targeted select list.
To solve the problem of the continuously created alert boxes, however, I decided to use underscore.js's .debounce() method, so it is only triggered once immediately every 1 second.
The underscore library is by no means required, however you will need to have some sort of debounce function in order to get around that small quirk.
var debouncedAlert = _.debounce(window.alert, 1000, true);
$('#select').chosen();
$('#select').on('chosen:showing_dropdown', function(e){
e.preventDefault();
e.stopPropagation();
debouncedAlert('focused');
});
Working example:
$(document).ready(function() {
var debouncedAlert = _.debounce(window.alert, 1000, true);
$('#select').chosen();
$('#select').on('chosen:showing_dropdown', function(e){
e.preventDefault();
e.stopPropagation();
debouncedAlert('focused');
});
$('button').click(function() {
$('#select').trigger('chosen:open');
});
});
body {
margin: 10px;
}
select {
width: 200px;
}
<link href="https://harvesthq.github.io/chosen/chosen.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><script src="https://harvesthq.github.io/chosen/chosen.jquery.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<input type="text" value="Put your cursor here then Press Tab. Chosen will be focused!" style="width:100%">
<br>
<select id="select" multiple>
<option value="1">abc</option>
<option value="2">def</option>
<option value="3">ghi</option>
</select>
<br>
<button>Press this button. Now chosen <b>will</b> be focused! :)</button>
Old answer:
No, it can't. Jquery's regular method of binding will not work with dynamically-created elements. In order to bind to those types of elements, you need .on().
$('.chzn-choices').focus(function(e){
e.preventDefault();
alert('focused!');
});
Would be changed to:
$('#select_chzn').on('focus', '.chzn-choices', function(e){
e.preventDefault();
alert('focused!');
});
In this case, you are delegating the event to the container elemen, and then pointing it to your specific element.
Working example
When user clicks on select box , I want to hide the options menu which I do by firing blur event on select box . Following code works on firefox but not on chrome .
<select id="myselect" name="city">
<option value="default" id="first">Default value</option>
</select>
<script type="text/javascript">
$('#myselect').click(function(){
$(this).blur();
});
</script>
In chrome options menu stays as it is.
I suspect that this is related to user modal state (although I couldn't find any documentation to support it, I might add). I suspect that any event listeners are ignored until the user has made a selection from the options.
To support this, you can see that $(this).blur() fires exactly as expected when we hook it up to the onchange event of the <select>:
http://jsfiddle.net/TkfPN/
It would be far better to simply disable the <select> element. Blurring a focused element is extremely bad HCI and frustrating to the user.
Here is my hack for my problem
var is_chrome = navigator.userAgent.toLowerCase().indexOf('chrome') > -1;
if(is_chrome) $(".option").hide();
where class "option" represent all the option of select box.
I found a solution to this. Just delete the select box's node then add it back in! Make sure you're using delegated event handlers. Seems to work in all browsers. Here's my solution in jQuery, but if someone wants to write a pure JS solution, that would be good also.
jQuery('.sortSelect').appendTo('.sortParent');
If it wasn't appearant, the markup in this example works if sortSelect is the last direct child of sortParent. $.insertAfter()/$.insertBefore() would work as well.
I have a page that has multiple select lists and when ever one of the select list changes using jQuery's .change() function I change the text in a span next to the select list. When the page loads there is already some text in every span (the text different for each span). The problem is that when the page loads the .change() function loops through all of the select lists changing the text in every span. I don't want the text in the span to change until a user selects a different item in the list. I can't just check to see if there is text in the span because if a user does change the selected item it doesn't matter if there is any text or not, I just don't want to to replace the text when the page loads. So, how can I get the .change() function to stop firing when the page is loaded? The code:
JS/jQuery
$(document).ready(function() {
$("select").change(function () {
var txt = $(this).val();
$(this).next('span').text(txt);
}).trigger('change');
});
HTML (repeated many times)
<select name="animal[]">
<option value="dog" selected="selected">dog</option>
<option value="cat">cat</option>
<option value="bird">bird</option>
<option value="snake">snake</option>
</select>
<span class="out">text that shouldn't be replaced until user changes selected item</span>
Thanks for your help!
You just need to remove this call:
.trigger('change')
It's what's invoking the $("select").change(function () { ... }) handler that you just bound. The default behavior is to wait for the change event to occur...a .trigger('change') or .change() (no parameters) will simulate the change event, making that handler go to work.
The "change" is triggering because your code is telling it to! That call to .trigger("change") says, "run the 'change' event handler please". So, take that out.
Now, the thing is, the reason your code was written that way was probably to make sure that the settings of the <select> elements really reflects what the behavior is supposed to be when users manually make the same changes. For example, sometimes there are forms where part of the inputs are supposed to be disabled unless a <select> is set to a certain option. By triggering the "change" event on page load, the code could make sure that those rules are in force. If you just take out that trigger, things may not work right, is what I'm saying. That handler looks pretty simple, so maybe the problem is that this code was cut-and-pasted from somewhere else.