handing focus from input element to button - javascript

On clicking a button, I want an input element to get focus. When the input element looses focus, I want the button to receive focus. Here is a simple example.
<body>
<button id="b1"
onclick="document.getElementById('i1').focus();">1</button>
<input id="i1" type="text"
onblur="document.getElementById('b1').focus();"/>
<button id="b2"
onclick="document.getElementById('i2').focus();">2</button>
<input id="i2" type="text"
onblur="document.getElementById('b2').focus();"/>
</body>
When I click any of the buttons, the input element gets focus. This works as desired. When I leave any of the two inputs by clicking on the canvas, the focus does not go to the button. This is my main issue.
When I leave the first input with tab, all browsers pass the focus to the first button. But when I leave the second button with tab, only firefox passes the focus to the second button. Chrome and opera don't show a focus. I am puzzled as to why the second button is treated differently.

You don't need to use JavaScript. HTML and CSS is enough. Use label tag and convert it's look like button. :)
label.btn{
-webkit-appearance: button;
-moz-appearance: button;
appearance: button;
padding: 1px 6px;
border:1px solid
}
<label class="btn" for="i1" id="b1">1</label>
<input id="i1" type="text"/>
<label class="btn" for="i2" id="b2">2</label>
<input id="i2" type="text" />

If you add a :focus style in your CSS, you can see it works fine. I've moved your JS out of the HTML markup for visibility and added some listeners for keyboard users.
Caution: Forcing focus back to the button interferes with the page's natural flow, so I probably wouldn't advise unless you have it attached to some input validation that fires when needed; else, how do keyboard users move to the next element?
const inputOne = document.getElementById('i1');
const btnOne = document.getElementById('b1');
const inputTwo = document.getElementById('i2');
const btnTwo = document.getElementById('b2');
// Listen for click to button one
btnOne.addEventListener('click', function() {
inputOne.focus();
})
// Make sure we listen for keyboard users
btnOne.addEventListener('keydown', function(event) {
if(event.keyCode === 90) {
inputOne.focus();
}
})
// Leaving input one
inputOne.addEventListener('blur', function() {
btnOne.focus();
})
// Listen for click to button two
btnTwo.addEventListener('click', function() {
inputTwo.focus();
})
// Make sure we listen for keyboard users
btnTwo.addEventListener('keydown', function(event) {
if(event.keyCode === 90) {
inputTwo.focus();
}
})
// Leaving input two
inputTwo.addEventListener('blur', function() {
btnTwo.focus();
})
:focus {
border: 1px solid red;
}
<button id="b1">1</button>
<input id="i1" type="text"/>
<button id="b2">2</button>
<input id="i2" type="text" />

Related

How to slide to particular HTML element using javascript?

How to set focus and slide down to the html when button is clicked . How to slide to particular HTML element using javascript?
p:focus, p:active {
color: green;
}
p {
min-height: 250px;
}
<body>
<input type="button" onclick="getfocus()" value="Get focus">
<input type="button" onclick="losefocus()" value="Lose focus">
<p>Click the buttons to give focus and/or remove focus from the link above.</p>
<p>Click the buttons to give focus and/or remove focus from the link above.</p>
<p>Click the buttons to give focus and/or remove focus from the link above.</p>
<p id="myAnchor">Click the buttons to give focus and/or remove focus from the link above.</p>
<script>
function getfocus() {
document.getElementById("myAnchor").focus();
}
function losefocus() {
document.getElementById("myAnchor").blur();
}
</script>
</body>
Adding tabindex="0" to p#myAnchor solves the issue
tabindex="0" means that the element should be focusable in sequential
keyboard navigation, after any positive tabindex values and its order
is defined by the document's source order.
function getfocus() {
document.getElementById("myAnchor").focus();
}
function losefocus() {
document.getElementById("myAnchor").blur();
}
p:focus,
p:active {
color: green;
}
p {
min-height: 200px;
}
<input type="button" onclick="getfocus()" value="Get focus">
<input type="button" onclick="losefocus()" value="Lose focus">
<p>Click the buttons to give focus and/or remove focus from the link above.</p>
<p>Click the buttons to give focus and/or remove focus from the link above.</p>
<p>Click the buttons to give focus and/or remove focus from the link above.</p>
<p tabindex="0" id="myAnchor">Click the buttons to give focus and/or remove focus from the link above.</p>
If by get focus you mean get there:
function getfocus() {
document.getElementById("myAnchor").scrollIntoView();
}
and if by loose focus if you mean going back to the top:
function looseFocus(){
window.scrollTo(0, 0);
}
but <p> is not focusable.
If you really want focus you need an anchor <p><a id="myAnchor" href="#">Click the buttons to give focus and/or remove focus from the link above.</a></p>

Prevent html input focus being lost to the body tag

When I have focus on the input field and I click in any open area of the body, the body becomes the document.activeElement , Is there a way to prevent the body focus completely.
What I am looking for is :
To prevent focus the body and maintain focus on the input field.
To avoid the firing of the blur event on the input field.
I've tried adding tabindex=-1 but I believe its for Tab functionality and hence does not work in this case.
document.querySelector("#inpdontlosefocus")
.addEventListener("blur",function(){
const $log = document.querySelector("#log");
$log.innerText += "\r\nLost focus";
})
html,body {
width:100vw;
height: 100vh;
}
<body id="notokaytogetfocus">
<input id="inpdontlosefocus" type="" placeholder="dont lose focus to body">
<input id="inpokaytofocus" type="" placeholder="allow focus">
<div id="log"></div>
</body>
Here is a solution that will always keep the focus on input fields in your document:
you will be able to switch the focus between input fields.
if you clicked outside an element that is not input, it will get the lastest input blurred and will apply focus on it.
var blurred, focused;
const $log = document.querySelector("#log");
var els = document.querySelectorAll('input');
Array.prototype.forEach.call(els, function(el) {
el.addEventListener('focus', function() {
focused = this;
});
el.addEventListener('blur', function() {
$log.innerText += "\r\nLost focus;"
blurred = this;
});
});
document.addEventListener("click", function(e) {
e.preventDefault();
if (focused && focused.tagName == "INPUT") {
$log.innerText += "\r\nactiveElement= " + document.activeElement.id;
focused.focus();
} else if (blurred) blurred.focus();
})
html,
label {
width: 100%;
height: 100%;
}
<body id="notokaytogetfocus">
<input id="inpdontloosefocus" placeholder="dont loose focus to body">
<input id="inpokaytofocus" placeholder="allow focus">
<div id="log"></div>
</body>
I'd added more html elements for a more accurate demonstration, the logic here is if the event source in body is not focus-able then we set focus back to the input we want, other wise the its a focusable element thus will get the focus(e.g. button, link, input, ...); notice that click event is attached to body and clicking outside body won't have this behavior.
document.querySelector('.notokaytogetfocus').addEventListener("click",function (e){
if(e.target == document.activeElement){
console.log("focusable element");
}else{
console.log("not focusable element");
// we'll set foucs on desired input
document.querySelector("#inpdontlosefocus").focus()
}
})
.notokaytogetfocus{height: 100vh; width:100vw;}
<div class="notokaytogetfocus">
<input id="inpdontlosefocus" type="" placeholder="dont lose focus to body">
<input id="inpokaytofocus" type="" placeholder="allow focus">
<button>do!(focusable)</button>
<p>lorem ipsum</p>
<div>some text</div>
</div>

Change text of button if it has a display of none?

I have a list of of checkboxes that are being used a search fields for a database. When someone clicks a checkbox it will show a button with the text from the label of that checkbox. However, I need that button to be have empty text when it is not visible (in the case of someone clicking the checkbox to hide the button).
Here's my code:
$(document).ready(function() {
$('#locationAll').click(function() {
var value = $('#locationAll').parent().text();
$('#location-all-button').html(value + " ×").toggle('fast');
});
});
$(document).ready(function() {
$('.search-popup').click(function() {
$(this).hide('fast');
});
if ($('.search-popup').css('display') == 'none') {
$(this).text("");
};
});
button {
background-color: lightgray;
border-radius: 20px;
display: none;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label>
<input type="checkbox" value="all" id="locationAll" />All
</label>
<br>
<br>
<button class="search-popup btn" id="location-all-button"></button>
For some reason I can't make the button stay hidden before the checkbox on the example here but that isn't a problem in my full code. if you need more info let me know I might have missed something.
Ok so I changed a few things. I made this work for any checkbox that follows the naming scheme I made really quickly. The scheme is the id of the button = the "button-"+id. Also I hiding all buttons with a class right form the start to set their default state.
$(document).ready(function()
{
\\change to allow all checkboxes to trigger
$('input[type=checkbox]').click(function()
{
\\change the id so it match a button when add "button-" to the start
\\this allows me to target the matching button with any chechbox
$('#button-'+$(this).attr('id')).toggle('fast');
});
$('.search-popup').click(function()
{
$(this).hide('fast');
\\ sets the check box to false so it not checked when you close it
$("#"+$(this).text().replace("  ×","")).attr('checked', false);
});
\\hides all buttons right form the start
$('button.search-popup').each(function()
{
$(this).hide();
});
});
<label>
<input type="checkbox" value="all" id="All" />All
</label>
<br>
<br>
<button class="search-popup btn" id="button-All">All  ×</button>
now if you want to create and remove buttons when a checkbox has changed state you can add an if state meant in that checks to see if the button with the matching id exists or not,!$(tag).size().

Trigger drop event

I have a form with an input type="file". I have a div surrounding the input. I then set the input to display:none. In JavaScript, I set that when you select the div, the input gets selected.
That all works nice and dandy, but how can I make it that when you drag a file onto the div, the input should trigger a drop event?
So here's how I would do the click event:
$('#target').click();
I'm looking for something like this:
$('#target').drop();
JSFiddle
$(document).ready(function() {
$('#browseFileDiv').click(function(e) {
$(this).find('input[type="file"]').click();
});
$('#browseFileDiv input').click(function(e) {
e.stopPropagation();
});
});
#browseFileDiv {
height: 200px;
width: 200px;
background-color: orange;
border-radius: 50%;
}
#browseFileDiv > input {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form action="upload.php" enctype="multipart/form-data" method="POST" id="uploadform">
<div id="browseFileDiv">
<input id="openFile" name="img" type="file" />
</div>
</form>
First, you don't need to wrap the <input type="file"> with a div around it and then with javscript trigger the .click() event for that input file if you click the div, make a <label> for this input file and style it, thus you can trigger the click event with HTML only without the need for javascript:
<label for="openFile" id="browseFile"></label>
<input id="openFile" name="img" type="file">
Updated: Then, as in this JS Fiddle the problem is that you need to return false; for the ondragover and ondrop events
var browseFile = document.getElementById('browseFile');
browseFile.ondragover = function () {
return false;
};
browseFile.ondrop = function (event) {
event.preventDefault && event.preventDefault();
var files = event.dataTransfer.files;
console.log(files);
return false;
};
** Note that the above works for multiple files as well.
Resource: http://html5doctor.com/drag-and-drop-to-server/
$('#browseFileDiv').on('drop', function(){/* code here */}) is probably what you're looking for.
You probably really want to use jQuery UI. Click the view source button.

Javascript OnMouseOver and Out disable/re-enable item problem

I wanted to have some radio buttons that disabled when the mouse went over and enabled again when it went out (just for fun).
<form>
<input type="radio" name="rigged" onMouseOver="this.disabled=true" onMouseOut="this.disabled=false">
</form>
When the mouse goes on it it does what it should be when it goes back off the button wont re-enable. Also, how do I make it default to enable so that when you refresh the page it doesn't stay disabled.
Thanks in advance.
You could achieve the same effect by wrapping your radio buttons in a div tag and setting the onmouseover and onmouseout events.
<div id="container" onmouseout="this.disabled=false" onmouseover="this.disabled=true">
<input name="rigged" type="radio">
</div>
The above solution only works in IE, for a solution that works in FireFox do the following.
<script type="text/javascript">
function toggleDisabled(el) {
try {
el.disabled = el.disabled ? false : true;
}
catch(E){
}
if (el.childNodes && el.childNodes.length > 0) {
for (var x = 0; x < el.childNodes.length; x++) {
toggleDisabled(el.childNodes[x]);
}
}
}
</script>
*This javaScript function was borrowed from here: Enable or disable DIV tag and its inner controls using Javascript
<div id="container" onmouseover="toggleDisabled(this)" onmouseout="toggleDisabled(this)">
<input name="rigged" type="radio">
</div>
The inputs do not fire the mouseout events because they are disabled.
So you have to wrap it in a div and catch the div's events.
If you want pure javascript, use Phaedrus's example "toggleDisabled" script.
If you want jQuery and not-so-newbie friendly:
<html>
<head>
<title>Page</title>
<script src="jquery-1.3.2.min.js"></script>
<script>
$(function() {
function toggleDisabled(d) {
var disable = d;
this.disableChildren = function() { $(this).children().each(function() { this.disabled = d; }); }
}
$("form .radios").hover(new toggleDisabled(true).disableChildren, new toggleDisabled(false).disableChildren);
});
</script>
</head>
<body>
<form>
<div class="radios">
<input type="radio" name="rigged" value="1"/> Item One<br />
<input type="radio" name="rigged" value="2"/> Item Two<br />
<input type="radio" name="rigged" value="3"/> Item Three<br />
<input type="radio" name="rigged" value="4"/> Item Four
</div>
</form>
</body>
</html>
I had a similar problem with wanting an image to expose, and then go regular when the mouse left the image. I was using jQuery and ended up hooking into mouseenter and mouseout, instead of the events you are using. You might want to try those.
$('#rigged').mouseenter(function() {
$(this).disabled = true;
}).mouseout(function() {
$(this).disabled = false;
});
Something like that.
Again, that's using jQuery.
(You'll have to give the input radio button the id 'rigged')
I think when it's becoming disabled, it's not going to fire any events.
You could try a few things.
On mouseover, make an invisible div overlay the radio box. This will make it impossible to use. Then on the mouseout of this invisible div, remove the div.
You could play with mouse x and y coords, and see if they overlay your radio elements. This isn't an optimal solution though.
Markup for the first, in jQuery, would go something like this
$('#rigged').after('<div id="overlay" style="display: none;"></div>'); // make this the size of the radio button and/or associated label (if present). also, maybe with absolute and relative positioning, make sure it will overlap the radio element
$('#rigged').bind('mouseover', function() {
$('#overlay').show();
});
$('#overlay').live('mouseout', function() {
$(this).hide();
});
You'll need to adapt this to work with multiple elements.

Categories