I have this code to focus a textarea when the user clicks on the "Reply" button:
$('#reply_msg').live('mousedown', function() {
$(this).hide();
$('#reply_holder').show();
$('#reply_message').focus();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script>
<div id="reply_msg">
<div class="replybox">
<span>Click here to <span class="link">Reply</span></span>
</div>
</div>
<div id="reply_holder" style="display: none;">
<div id="reply_tab"><img src="images/blank.gif" /> Reply</div>
<label class="label" for="reply_subject" style="padding-top: 7px; width: 64px; color: #999; font-weight: bold; font-size: 13px;">Subject</label>
<input type="text" id="reply_subject" class="input" style="width: 799px;" value="Re: <?php echo $info['subject']; ?>" />
<br /><br />
<textarea name="reply" id="reply_message" class="input" spellcheck="false"></textarea>
<br />
<div id="reply_buttons">
<button type="button" class="button" id="send_reply">Send</button>
<button type="button" class="button" id="cancel_reply_msg">Cancel</button>
<!--<button type="button" class="button" id="save_draft_reply">Save Draft</button>-->
</div>
</div>
It shows the reply form, but the textarea won't focus. I'm adding the textarea via AJAX which is why I am using .live(). The box that I add shows (I even add #reply_msg via AJAX and stuff happens when I mouse down on it) but it won't focus on the textarea.
A mouse-click on a focusable element raises events in the following order:
mousedown
focus
mouseup
click
So, here's what's happening:
mousedown is raised by <a>
your event handler attempts to focus the <textarea>
the default event behavior of mousedown tries to focus <a> (which takes focus from the <textarea>)
Here's a demo illustrating this behavior:
$("a,textarea").on("mousedown mouseup click focus blur", function(e) {
console.log("%s: %s", this.tagName, e.type);
})
$("a").mousedown(function(e) {
$("textarea").focus();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
reply
<textarea></textarea>
So, how do we get around this?
Use event.preventDefault() to suppress mousedown's default behavior:
$(document).on("mousedown", "#reply_msg", function(e) {
e.preventDefault();
$(this).hide();
$("#reply_message").show().focus();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
reply
<textarea id="reply_message"></textarea>
Focusing on something from an event handler that, itself, grants focus, is always problematic. The general solution is to set focus after a timeout:
setTimeout(function() {
$('#reply_message').focus();
}, 0);
That lets the browser do its thing, and then you come back and yank focus over to where you want it.
Could it be the same issue as this? jQuery Textarea focus
Try calling .focus() after .show() has completed.
$('#reply_msg').live('mousedown', function() {
$(this).hide();
$('#reply_holder').show("fast", function(){
$('#reply_message').focus();
});
});
I ran into this issue today and in my case, it was caused by a bug in jQuery UI (v1.11.4) which causes textarea elements inside of draggable/droppable elements to stop default click behavior before the textarea receives the focus click.
The solution was to rework the UI so that the textarea no longer appears inside the draggable element.
This was a particularly difficult issue to debug, so I am leaving an answer here in case others find it helpful.
It might also come from the browser. I'm doing a project in Vue, and el.focus() on textarea works in Chrome (v101), but not in Firefox (v100.0).
Related
I have a script that enables the disabled text box when clicking on a button. But, I just don't know how to re-disable the text box again.
The coding is below.
HTML:
<div class="input-group">
<label for="some-tbox" class="input-group-addon">Label:</label>
<input id="some-tbox" type="text" class="input-box" value="some value" disabled>
<span class="input-group-btn">
<button class="enable" type="button">button</button>
</span>
</div>
JS:
$(".enable").click(function(){
$(this).parent().parent().children(".input-box").removeAttr("disabled");
$(this).toggleClass("disable");
$(this).toggleClass("enable");
});
$(".disable").click(function(){
$(this).toggleClass("enable");
$(this).toggleClass("disable");
$(this).parent().parent().children(".input-box").attr("disabled", "disabled");
});
And I have made a fiddle out of it. But, It's not working. Here is the link.
Instead of messing with adding and removing classes, just toggle the disabled property with:
$(".enable").click(function() {
$(this).closest('.input-group').find('input').prop('disabled', !$(this).closest('.input-group').find('input').prop('disabled'))
});
jsFiddle example
The problem is this line $(".disable").click(function(){ ...})
You are binding a click event handler to a class named disabled which was not available initially during page load, it appears dynamically later.
You need to delegate the event handler to some parent which always exist and then handle the event there, in this case you can do this:
$(".input-group").on('click', '.disable', function(){
$(this).toggleClass("enable");
$(this).toggleClass("disable");
$(this).parent().parent().children(".input-box").attr("disabled", "disabled");
});
jQuery's on function
You cann't bind an element ".disable" that don't exist , In that case you can rebind it when you changed it's class. Code behind may help you:
$(".enable").on("click",enabledClick)
function enabledClick (argument) {
$(".enable").parent().parent().children(".input-box").removeAttr("disabled");
$(".enable").toggleClass("disable");
$(".enable").toggleClass("enable");
$(".disable").on("click",disabledClick)
}
function disabledClick (argument) {
$(".disable").parent().parent().children(".input-box").attr("disabled", "");
$(".disable").toggleClass("enable");
$(".disable").toggleClass("disable");
$(".enable").on("click",enabledClick)
}
Consider that I have a page with multiple lines of text.
When then user clicks on it, it turns into multiple text inputs so he can modify it.
When he clicks outside the text input, its is saved and the input is replaced by the text.
But if he clicks on another text input, I don't want to save it for now, so he doesn't have to click multiple times on a line to modify it.
I was able to that using the 'focusout' event. I detect that the user clicks ont another input using jQuery's e.relatedTarget.
It works great with Chrome but Firefox doesn't support well focusout. e.relatedTargetis always null
How can I achieve something similar with firefox ?
$('input').on('focusout', function(e) {
if (e.relatedTarget != null) {
$('#display').html("don't save for now")
} else {
$('#display').html("save the inputs");
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<div>
<input type="text" />
</div>
<div>
<input type="text" />
</div>
</div>
<div id="display"></div>
You are correct that relatedTarget is not very useful in Firefox.
The workaround is to explicitly check what element recieves the focus. This is not available during the focusout event (as the new element has not received focus yet), but it will be directly thereafter. Using a timeout of 0 to move the request to the end of the current execution queue will reliable allow you to get the newly focused element, and check if it is one of the inputs or not.
$('input').on('focusout', function(e) {
setTimeout(function() {
if ($(document.activeElement).is('input')) {
$('#display').html("don't save for now")
} else {
$('#display').html("save the inputs");
}
}, 0);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<div>
<input type="text" />
</div>
<div>
<input type="text" />
</div>
</div>
<div id="display"></div>
When using Redactor in a jQueryUI dialog which also contains an input element it exhibits some strange behavior.
Selecting the text and clicking the “Bold”, “Italics” or “Strike-through” buttons for the first time will not perform the expected action, it will instead transfer focus to the input element.
A second click of the same button (after selecting the text again) will work as expected.
Removing the input also seems to work.
Fiddle: http://jsfiddle.net/Shikiju/sgvdvoL2/1/
Browser used: Chrome Version 40.0.2214.115 m
<div id="dialog">
<textarea id="editor" value=""></textarea>
<input type="text" value="" onfocus="console.log('Focus on this input')" />
</div>
$(function(){
$('#dialog').dialog({
open: function(){
$('#editor').redactor();
}
});
});
Apperantly it was a issue in Jquery UI that caused the problem. Solved by
https://stackoverflow.com/a/4814001/611547
Hi,
A button which is adjacent to an input. The button is hidden by default and will be visible when the input gets focus and it will be hidden again if the input loses focus.
I wrote a code to achieve that. But the problem is button's event is not being triggered since it is hidden the moment the input loses focus.
I am not getting any idea to achieve that.Can somebody help me.
Here is the code
<html>
<head>
<style>
.icon{
visibility:hidden;
}
</style>
</head>
<body>
<input type="text" onFocus="onOver('f4_1')" onBlur="onOut('f4_1')"/>
<input type="button" class="icon" value="?" id="f4_1" onClick="alert('hi..')"/>
<script>
function onOver(f4Id){
document.getElementById(f4Id).style.visibility = "visible";
}
function onOut(f4Id){
document.getElementById(f4Id).style.visibility="hidden";
}
</script>
</body>
</html>
Note: Use pure javascript to achieve. Don't use any jQuery.
Thanks.
Actually, the order of these events varies between browsers. If I remember correctly, Internet Explorer will trigger the button if you click on it, whereas Firefox will not.
Anyway, the problem can be fixed by adding a small delay. Change your onOut function to:
function onOut(f41d) {
setTimeout(function(){document.getElementById(f41d).style.visibllity="hidden";},25);
}
Now the button will hide almost instantly. It should be unnoticeable to the human eye, but the computer can tell the difference and allow you to click the button.
Event handling is very important and understanding when they are fired is utmost important
onmousedown event will override onBlur effect of textbox ,which is what is required.
check working Example Here
<input type="text" onFocus="onOver('f4_1')" onBlur="onOut('f4_1')"/>
<input type="button" class="icon" value="?" id="f4_1" onmousedown="alert('M Kicked')"/>
<html>
<head>
<style>
.icon{
visibility:hidden;
}
</style>
</head>
<body>
<input type="text" onFocus="onOver('f4_1')" onBlur="onOut('f4_1')"/>
<input type="button" class="icon" value="?" id="f4_1" onmousedown="alert('M Kicked')"/>
<script>
function onOver(f4Id){
document.getElementById(f4Id).style.visibility = "visible";
}
function onOut(f4Id){
document.getElementById(f4Id).style.visibility="hidden";
}
</script>
</body>
</html>
I have a text input and one button of type submit adjacent to the input. I have bound focusout event-handler to the input and click event-handler to the button. Now when I focus on the input and then press enter, the focusout event-handler gets triggered and the buttons-event handler gets triggered. I want to trigger focusout only when text box focus is lost. What should I do ?
Code :-
<div >
<span>Local Currency: </span>
<input type='text' id='txtFocusElement' />
<button id="btnClickElement" >
<span> Add new line</span>
</button>
</div>
I used selector as:
$("#txtFocusElement").bind("focusout", function() {
console.log('focusout');
})
$("#btnClickElement").bind("click", function() {
console.log('click');
})
and written above code in one function which I call at the time of loading document.
Its IE9 issue with the HTML button tag.
So we should try it with HTML input tag with attribute type as button.
above code can be rewritten as :
<div >
<span>Local Currency: </span>
<input type='text' id='txtFocusElement' />
<input id="btnClickElement" type="button" value="Add new line" />
</div>
Using this my problem gets solved .
You could try to change the selector to input[type=text].
This will only get triggered when you focus out on a text field.
Try to attach to a mouseup event instead of click, that is the only solution I see for now
You can also add a check for mouse button which was pressed, so it wouldn't fire if user would press a right button
var ClickElementEventHandler = function(e) {
if (e.which != 1) return;
//your code
};
$("#btnClickElement").bind("mouseup",ClickElementEventHandler)