Jquery - Differentiate between 'click' and 'focus' on same input when using both - javascript

I'm trying to trigger an event on an input if the input is clicked or if the input comes in to focus.
The issue i'm having is preventing the event from firing twice on the click as, obviously, clicking on the input also puts it in focus. I've put a very loose version of this on jfiddle to show you what I mean, code as below:
HTML:
<body>
<input type="textbox" name="tb1" class="input1"></input>
<label> box 1 </label>
<input type="textbox" name="tb2" class="input2"></input>
<label> box 2 </label>
</body>
JQuery
$(function () {
$('.input2').click(function() {
alert("click");
});
$('.input2').focus(function() {
alert("focus");
});
});
JSFiddle: http://jsfiddle.net/XALSn/2/
You'll see that when you tab to input2 you get one alert, but if you click you get two. Ideally for my scenario, it needs to be one alert and ignore the other. it also doesn't seem to actually focus.
Thanks in advance for any advice.

How about setting a flag on focus so we can fire on focus and ignore clicks but then listen for clicks on the focussed element too? Make sense? Take a look at the demo jsFiddle - If you focus or click on the unfocussed .index2 it triggers the focus event and ignores the click. Whilst in focus, clicking on it will trigger the click.
I have no idea why you would want this (I cant imagine anyone wanting to click on a focussed element for any reason (because the carat is already active in the field) but here you go:
$(function () {
$('.input2').on("click focus blur", function(e) {
e.stopPropagation();
if(e.type=="click"){
if($(this).data("justfocussed")){
$(this).data("justfocussed",false);
} else {
//I have been clicked on whilst in focus
console.log("click");
}
} else if(e.type=="focus"){
//I have been focussed on (either by clicking on whilst blurred or by tabbing to)
console.log("focus");
$(this).data("justfocussed",true);
} else {
//I no longer have focus
console.log("blur");
$(this).data("justfocussed",false);
}
});
});
http://jsfiddle.net/XALSn/12/

This probably won't be the best answer, but this is a way of doing it. I would suggest adding tab indexes to your inputs and firing the focus event when you blur from another input.
I've added that to this fiddle:
http://jsfiddle.net/XALSn/9/
$(function () {
$('.input2').click(function(e) {
alert("click");
e.preventDefault();
});
});
$('input').blur(function(){
$('input').focus(function() {
alert("focus");
});
});

You can use one thing I am using very often in JS
var doSomething = true;
$(function () {
$('.input2').click(function(e) {
if (doSomething) {
// do something :)
}
doSomething = false;
});
$('.input2').focus(function() {
if (doSomething) {
// do something :)
}
doSomething = false;
});
});
But You have to change value of doSomething on mouseout or foucs over etc. :)

$(function () {
var hasFocus = false;
$("body")
.off()
.on({
click : function()
{
if(!hasFocus)
{
hasFocus = true;
alert("click");
}
},
focus : function()
{
if(!hasFocus)
{
hasFocus = true;
alert("focus");
}
}
},".input2");
});
try setting a flag hasFocus and act accordingly
http://jsfiddle.net/AEVTQ/2/

just add e.preventDefault() on the click event
$(function () {
$('.input2').click(function(e) {
console.log("click");
e.preventDefault();
e.stopPropagation();
});
$('.input2').focus(function() {
console.log("focus");
});
});
If I understand your question right, the e.prevnetDefault() will prevent the browser from automatically focusing on click. Then you can do something different with the click than would with the focus

Related

Can you stop the jQuery focusout from firing when losing focus?

I've got an input box that I want to have save its value when it loses focus.
Pretty straightforward stuff and I'm able to get that done via jQuery's focusout event.
The problem however, is that I want to NOT fire the focusout event when the user clicks on an "X" icon next to the input box (example shown below)
So when the user tabs out of this input box, or clicks outside of the box or they click the green checkbox it should fire the focusout event... but if they click the red "X", it should NOT fire the focusout.
Is this possible to do with JavaScript / jQuery?
EDIT:
Some of you have recommended using event.relatedTarget, but it seems like that's returning null. I'll include my code in question for clarity:
// This is the cancel button with the red X
$("body").on("click", "span[id*='Cancel']", function(e)
{
showLabel($(this));
});
// this is the code to trigger the blur / focusout event
// trouble is that the "e.relatedTarget" is null
$("body").on("focusout", "input, textarea", function (e) {
if($(e.relatedTarget).is("span[id*='Cancel']")){
return false;
}
$(this).siblings("span[id*='OK']").trigger("click");
return false;
});
Here's a screen grab of me debugging this in JS (you'll see that the $(e.relatedTarget) selector returns nothing):
You can cancel de event returning the focus to previous element.
$('#inputText').focusout(function(event) {
setTimeout(function(){
if (document.activeElement.id == "btnCancel") {
$(event.target).focus();
return false;
}
},1);
});
This jsFiddle shows how to do it: https://jsfiddle.net/mpervh3t/
Hope it helps
You must use relatedTarget like this :
$(document).ready(function(){
$(".btn").on("focusout",function(e){
if($(e.relatedTarget).hasClass("red")) {
alert("You clicked on X button");
}
else {
alert("Fire Focus out")
}
})
})
Final code :
<!DOCTYPE html>
<html>
<head>
<style>
.gr {
color: green;
}
.red {
color: red;
}
</style>
</head>
<body>
<input type="text" class="btn"><button class="gr">Ok</button><button class="red">X</button>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script>
$(document).ready(function(){
$(".btn").on("focusout",function(e){
if($(e.relatedTarget).hasClass("red")) {
alert("You clicked on X button");
}
else {
alert("Fire Focus out")
}
})
})
</script>
</body>
</html>
As per my comment:
"I have had to do a similar type of thing with a blur event. Basically what I had to do was call a setTimeout on the blur to execute my function to save the data, and then on the click event of the X, cancel the timeout. That way, unless the X is clicked, the save function will fire. The delay can be pretty negligable, too."
I found the relevant code
var sliderTimeout = null;
$(".slider-trigger").on("blur", function () {
sliderTimeout = setTimeout(function () {
$(".slider").hide();
}, 100);
});
$(".ui-slider-handle").on("focus", function () {
clearTimeout(sliderTimeout);
});
Here is the full demo of the code in action. It does much more than demonstrate this, but if you examine the behavior of focusing/blur on the "margin" input, you will see that if you blur the margin input, the slider hides, but if you click on the slider, it cancels the hide and stays shown. It's the exact same concept, just a slightly different application.
Here, I did the thing.
https://jsfiddle.net/kowmLf2a/1/
In the blur event I target the related target. See if that related target is the item that I don't want to blur with. If it is then return false.
Code for reference:
$('#input').blur(function(event){
if($(event.relatedTarget).is('#bt2')){
return false;
}
alert($(this).val());
});

Show a Div first and then Submit on second click of button in a form

I have a form with multiple divs with same names (full-width). They all are on the same level. One of them is hidden (with a class hide). What I want is that if I select Submit, it should not submit, first hide all the brother divs of the hidden div (in this case full-width) and unhide the one with the class hide.
Now when I press again, it should just submit the Form.
JSFiddle is here:- http://jsfiddle.net/xmqvx/2/
Your code had a couple issues:
You used event.preventDefault but passed event in as e - should be e.preventDefault
Your ID selector targeted an ID that didnt exist (changed to #submit-this)
The working code:
$("#submit-this").click(function (e) {
e.preventDefault();
if ($(".full-width").hasClass("hide")) {
$(".full-width").hide();
$(".full-width.hide").removeClass("hide").show();
} else {
alert("Submitting");
$("#this-form").submit();
}
});
http://jsfiddle.net/xmqvx/4/
You could also take advantage of JavaScript's closures like so, to avoid having your behavior be dependent on your UI:
$(document).ready(function () {
var alreadyClicked = false;
$("#submit-this").click(function (e) {
e.preventDefault();
if (alreadyClicked) {
$('#this-form').submit();
} else {
$('.full-width').hide();
$('.hide').show();
alreadyClicked = true;
}
});
});

Global click event blocks element's click event

This should happen
If the user clicks on one of the two input boxes, the default value should be removed. When the user clicks elswhere on the webpage and one text field is empty, it should be filled with the default value from the data-default attribute of the spefic element.
This happens
When somebody clicks somewhere on the page and the field is empty, the field will be filled with the right value, but when somebody clicks in the field again the text isn't removed. It seems like the $(document) click event is blocking the $(".login-input") click event, because the $(".login-input") is working without the $(document) click event.
JSFiddle
A sample of my problem is provieded here: JSFiddle
Tank you for helping!
When you click on the input, the script is working, but since the input is in the document, a click on the input is a click on the document aswell. Both function will rune, document is the last one.
That is called event bubblingand you need to stop propagation :
$(document).ready(function () {
$(".login-input").click(function (e) {
e.stopPropagation()
$(this).val("");
});
});
Fiddle : http://jsfiddle.net/kLQW9/3/
That's not at all how you solve placeholders, you do it like so :
$(document).ready(function () {
$(".login-input").on({
focus: function () {
if (this.value == $(this).data('default')) this.value = '';
},
blur: function() {
if (this.value == '') this.value = $(this).data('default');
}
});
});
FIDDLE
Preferably you'd use the HTML5 placeholder attribute if really old browsers aren't an issue.
EDIT:
if you decide to do both, check support for placeholders in the browser before applying the javascript :
var i = document.createElement('input'),
hasPlaceholders = 'placeholder' in i;
if (!hasPlaceholders) {
// place the code above here, the condition will
// fail if placeholders aren't supported
}
Try below code
$(document).ready(function () {
$(".login-input").click(function () {
$(this).val("");
});
});
$(document).ready(function () {
$(".login-input").each(function () {
if ($(this).val() === "") {
$(this).val($(this).attr("data-default"));
}
});
$(".login-input").blur(function () {
if ($(this).val() === "") {
$(this).val($(this).attr("data-default"));
}
});
});
Check fiddle
Why not to use focus and blur events?
$(document).ready(function () {
$(".login-input").focus(function () {
$(this).val("");
});
});
$(document).ready(function () {
$(".login-input").blur(function () {
if ($(this).val() === "") {
$(this).val($(this).attr("data-default"));
}
});
});
http://jsfiddle.net/kLQW9/5/
P.S. In yours, and this code, on focus all data fro input will be cleared. If you need to clear only default text, add proper condition for that.

Do not fire one event if already fired another

I have a code like this:
$('#foo').on('click', function(e) {
//do something
});
$('form input').on('change', function(e) {
//do some other things
));
First and second events do actually the same things with the same input field, but in different way. The problem is, that when I click the #foo element - form change element fires as well. I need form change to fire always when the content of input is changing, but not when #foo element is clicked.
That's the question )). How to do this?
Here is the code on jsfiddle: http://jsfiddle.net/QhXyj/1/
What happens is that onChange fires when the focus leaves the #input. In your case, this coincides with clicking on the button. Try pressing Tab, THEN clicking on the button.
To handle this particular case, one solution is to delay the call to the change event enough check if the button got clicked in the meantime. In practice 100 milisecond worked. Here's the code:
$().ready(function() {
var stopTheChangeBecauseTheButtonWasClicked = false;
$('#button').on('click', function(e) {
stopTheChangeBecauseTheButtonWasClicked = true;
$('#wtf').html("I don't need to change #input in this case");
});
$('#input').on('change', function(e) {
var self = this;
setTimeout(function doTheChange() {
if (!stopTheChangeBecauseTheButtonWasClicked) {
$(self).val($(self).val() + ' - changed!');
} else {
stopTheChangeBecauseTheButtonWasClicked = false;
}
}, 100);
});
});
And the fiddle - http://jsfiddle.net/dandv/QhXyj/11/
It's only natural that a change event on a blurred element fires before the clicked element is focused. If you don't want to use a timeout ("do something X ms after the input was changed unless in between a button was clicked", as proposed by Dan) - and timeouts are ugly - you only could go doing those actions twice. After the input is changed, save its state and do something. If then - somewhen later - the button is clicked, retrieve the saved state and do the something similar. I guess this is what you actually wanted for your UI behaviour, not all users are that fast. If one leaves the input (e.g. by pressing Tab), and then later activates the button "independently", do you really want to execute both actions?
var inputval = null, changedval = null;
$('form input').on('change', function(e) {
inputval = this.value;
// do some things with it and save them to
changedval = …
// you might use the value property of the input itself
));
$('#foo').on('click', function(e) {
// do something with inputval
});
$('form …').on('any other action') {
// you might want to invalidate the cache:
inputval = changedval;
// so that from now on a click operates with the new value
});
$(function() {
$('#button').on('click', function() {
//use text() not html() here
$('#wtf').text("I don't need to change #input in this case");
});
//fire on blur, that is when user types and presses tab
$('#input').on('blur', function() {
alert("clicked"); //this doesn't fire when you click button
$(this).val($(this).val()+' - changed!');
});
});​
Here's the Fiddle
$('form input').on('change', function(e) {
// don't do the thing if the input is #foo
if ( $(this).attrib('id') == 'foo' ) return;
//do some other things
));
UPDATE
How about this:
$().ready(function() {
$('#button').on('click', function(e) {
$('#wtf').html("I don't need to change #input in this case");
});
$('#input').on('change', function(e) {
// determine id #input is in focus
if ( ! $(this).is(":focus") ) return;
$(this).val($(this).val()+' - changed!');
});
});

Select all contents of textbox when it receives focus (Vanilla JS or jQuery)

What is a Vanilla JS or jQuery solution that will select all of the contents of a textbox when the textbox receives focus?
$(document).ready(function() {
$("input:text").focus(function() { $(this).select(); } );
});
<input type="text" onfocus="this.select();" onmouseup="return false;" value="test" />
$(document).ready(function() {
$("input[type=text]").focus().select();
});
$(document).ready(function() {
$("input:text")
.focus(function () { $(this).select(); } )
.mouseup(function (e) {e.preventDefault(); });
});
jQuery is not JavaScript which is more easy to use in some cases.
Look at this example:
<textarea rows="10" cols="50" onclick="this.focus();this.select()">Text is here</textarea>
Source: CSS Tricks, MDN
This is not just a Chrome/Safari issue, I experienced a quite similar behavior with Firefox 18.0.1. The funny part is that this does not happen on MSIE! The problem here is the first mouseup event that forces to unselect the input content, so just ignore the first occurence.
$(':text').focus(function(){
$(this).one('mouseup', function(event){
event.preventDefault();
}).select();
});
The timeOut approach causes a strange behavior, and blocking every mouseup event you can not remove the selection clicking again on the input element.
HTML :
var textFiled = document.getElementById("text-filed");
textFiled.addEventListener("focus", function() { this.select(); });
Enter Your Text : <input type="text" id="text-filed" value="test with filed text">
Using JQuery :
$("#text-filed").focus(function() { $(this).select(); } );
Using React JS :
In the respective component -
<input
type="text"
value="test"
onFocus={e => e.target.select()}
/>
my solution is to use a timeout. Seems to work ok
$('input[type=text]').focus(function() {
var _this = this;
setTimeout(function() {
_this.select();
}, 10);
});
This will also work on iOS:
<input type="text" onclick="this.focus(); this.setSelectionRange(0, 9999);" />
https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/select
I know inline code is bad style, but I didn't want to put this into a .js file.
Works without jQuery!
<input type="text" value="blah blah" onfocus="this.select(); this.selAll=1;" onmouseup="if(this.selAll==0) return true; this.selAll=0; return false;"></input>
The answers here helped me up to a point, but I had a problem on HTML5 Number input fields when clicking the up/down buttons in Chrome.
If you click one of the buttons, and left the mouse over the button the number would keep changing as if you were holding the mouse button because the mouseup was being thrown away.
I solved this by removing the mouseup handler as soon as it had been triggered as below:
$("input:number").focus(function () {
var $elem = $(this);
$elem.select().mouseup(function (e) {
e.preventDefault();
$elem.unbind(e.type);
});
});
Hope this helps people in the future...
This will work, Try this -
<input id="textField1" onfocus="this.select()" onmouseup="return false" />
Works in Safari/IE 9 and Chrome, I did not get a chance to test in Firefox though.
I know there are already a lot of answers here - but this one is missing so far; a solution which also works with ajax generated content:
$(function (){
$(document).on("focus", "input:text", function() {
$(this).select();
});
});
Like #Travis and #Mari, I wanted to autoselect when the user clicked in, which means preventing the default behaviour of a mouseup event, but not prevent the user from clicking around. The solution I came up with, which works in IE11, Chrome 45, Opera 32 and Firefox 29 (these are the browsers I currently have installed), is based on the sequence of events involved in a mouse click.
When you click on a text input that does not have focus, you get these events (among others):
mousedown: In response to your click. Default handling raises focus if necessary and sets selection start.
focus: As part of the default handling of mousedown.
mouseup: The completion of your click, whose default handling will set the selection end.
When you click on a text input that already has focus, the focus event is skipped. As #Travis and #Mari both astutely noticed, the default handling of mouseup needs to be prevented only if the focus event occurs. However, as there is no "focus didn't happen" event, we need to infer this, which we can do within the mousedown handler.
#Mari's solution requires that jQuery be imported, which I want to avoid. #Travis's solution does this by inspecting document.activeElement. I don't know why exactly his solution doesn't work across browsers, but there is another way to track whether the text input has focus: simply follow its focus and blur events.
Here is the code that works for me:
function MakeTextBoxAutoSelect(input)
{
var blockMouseUp = false;
var inputFocused = false;
input.onfocus =
function ()
{
try
{
input.selectionStart = 0;
input.selectionEnd = input.value.length;
}
catch (error)
{
input.select();
}
inputFocused = true;
};
input.onblur =
function ()
{
inputFocused = false;
};
input.onmousedown =
function ()
{
blockMouseUp = !inputFocused;
};
input.onmouseup =
function ()
{
if (blockMouseUp)
return false;
};
}
I hope this is of help to someone. :-)
I was able to slightly improve Zach's answer by incorporating a few function calls. The problem with that answer is that it disables onMouseUp completely, thereby preventing you from clicking around in the textbox once it has focus.
Here is my code:
<input type="text" onfocus="this.select()" onMouseUp="javascript:TextBoxMouseUp();" onMouseDown="javascript:TextBoxMouseDown();" />
<script type="text/javascript">
var doMouseUp = true;
function TextBoxMouseDown() {
doMouseUp = this == document.activeElement;
return doMouseUp;
}
function TextBoxMouseUp() {
if (doMouseUp)
{ return true; }
else {
doMouseUp = true;
return false;
}
}
</script>
This is a slight improvement over Zach's answer. It works perfectly in IE, doesn't work at all in Chrome, and works with alternating success in FireFox (literally every other time). If someone has an idea of how to make it work reliably in FF or Chrome, please share.
Anyway, I figured I'd share what I could to make this a little nicer.
What is a JavaScript or jQuery solution that will select all of the contents of a textbox when the textbox receives focus?
You only need to add the following attribute:
onfocus="this.select()"
For example:
<input type="text" value="sometext" onfocus="this.select()">
(Honestly I have no clue why you would need anything else.)
This worked for me (posting since it is not in answers but in a comment)
$("#textBox").focus().select();
onclick="this.focus();this.select()"
$('input').focus(function () {
var self = $(this);
setTimeout(function () {
self.select();
}, 1);
});
Edit: Per #DavidG's request, I can't provide details because I'm not sure why this works, but I believe it has something to do with the focus event propagating up or down or whatever it does and the input element getting the notification it's received focus. Setting the timeout gives the element a moment to realize it's done so.
If you chain the events together I believe it eliminates the need to use .one as suggested elsewhere in this thread.
Example:
$('input.your_element').focus( function () {
$(this).select().mouseup( function (e) {
e.preventDefault();
});
});
Note: If you are programming in ASP.NET, you can run the script using ScriptManager.RegisterStartupScript in C#:
ScriptManager.RegisterStartupScript(txtField, txtField.GetType(), txtField.AccessKey, "$('#MainContent_txtField').focus(function() { $(this).select(); });", true );
Or just type the script in the HTML page suggested in the other answers.
I sow this one some where , work perfectly !
$('input').on('focus', function (e) {
$(this)
$(element).one('mouseup', function () {
$(this).select();
return false;
}) .select();
});
I'm kind of late to the party, but this works perfectly in IE11, Chrome, Firefox, without messing up mouseup (and without JQuery).
inputElement.addEventListener("focus", function (e) {
var target = e.currentTarget;
if (target) {
target.select();
target.addEventListener("mouseup", function _tempoMouseUp(event) {
event.preventDefault();
target.removeEventListener("mouseup", _tempoMouseUp);
});
}
});
My solution is next:
var mouseUp;
$(document).ready(function() {
$(inputSelector).focus(function() {
this.select();
})
.mousedown(function () {
if ($(this).is(":focus")) {
mouseUp = true;
}
else {
mouseUp = false;
}
})
.mouseup(function () {
return mouseUp;
});
});
So mouseup will work usually, but will not make unselect after getting focus by input

Categories

Resources