Give a form field focus while out of viewport? - javascript

I'd like to be able to give a formfield (via javascript or otherwise) focus while it's out of the viewport, without having the scrollbar move to shift it into the viewport.
Is that possible?
I know & understand that it'll pop into the viewport as soon as the user starts typing - that works fine for my use case.

Simply done by creating a JavaScript function onLoad in the body tag and sending the focus to the form field doesn't matter if it's out of viewport.
HTML
<body onload="FocusMe();">
<input type="text" id="FocusTo">
JAVAscript
function FocusMe () {
document.getElementById("FocusTo").focus();
}

Related

How to detect where in an input element user has clicked

Is there a way to detect where in an input element's content a user has clicked? Specifically in Firefox?
I need to know not where the caret is but where the caret would be when the user clicks into an input element.
I am trying to fix a bug in firefox where the user cannot click to place the caret into an input element which has had '.select()' called on it -- the caret fails to appear in firefox, so I want to place it manually if possible.
Thanks!
You can get the pixel position of the user's click (relative to the input field) by reading the click event's offsetX and offsetY:
// get the click position:
document.getElementById('test').onclick = function(e) {
console.log(e.offsetX, e.offsetY)
};
// for testing the 'select' issue:
document.getElementById('btn').onclick = function() {
document.getElementById('test').select();
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id="test">xxxxxx</textarea>
<button id="btn">Select</button>
Converting that to the desired caret location is not easy, though, because it will depend on font sizes and the text content of the input field. The best I can think of would be to do something like the technique used in textarea-caret-position, except iterating through every possible caret position in the textarea to find the one closest to where the user clicked. Which is almost certainly overkill for the task you have in mind.
(For what it's worth, the current version of firefox (v57) does not seem to have any trouble placing the caret correctly whether the input field is selected or not. I'm not certain whether this was the case in previous versions.)
Found the root of the problem, some bad css had set text-select to auto on input elements. Changing it to text-select:text allowed the fix I used for Safari to work in Firefox as well.

Detect "Enter" key and paint the textarea component

Before explaining the issue, I will explain my requirement and why I chose to create this custom component.
I have a requirement where whenever the user enters something in textarea, the textarea's height should increase/decrease automatically based on the entered text.
Since, textarea adds a scrollbar when content is increased but not stretch automatically. I thought to use contenteditable div instead of textarea. But contenteditable div has a problem in mobiles that we can't tap on the entered text.
So, I created a custom component where whatever I add in textarea, the same content will be added in a hidden div. and later the textarea will take out the height of the hidden div. This is working fine.
Here is the Fiddle
But I have a small problem that whenever the user is pressing "enter", this component is unable to adjust the textarea's height. and later if I press any letter, the textarea is adjusting properly. The problem is with just detecting "Enter" key that pressed at the end of the content (if the user pressed "Enter" key in mid of the content, this component is working fine).
Here is the component's HTML code:
<div class="wrapper">
<div class="textarea-clone"></div>
<textarea></textarea>
</div>
Try something like this ...
$('textarea').on('keyup', function (e) {
if(code == 13) { // keycode == 13 (enter)
$('.textarea-clone').text($(this).val());
}
});
EDIT:
This works for me and only resizes on enter key presses, thinking about it that's likely not your intention but this tests that specific scenario.
Maybe this is a browser thing, some browsers don't correctly implement all the events right, maybe try attaching to change, keypress, and keydown too, experiment and see what you get.
expanding on my comment to include overflow lines:
<textarea id=ta></textarea>
ta.oninput=function(){
this.rows=this.value.split("\n").length;
while(this.clientHeight < this.scrollHeight-2) this.rows=this.rows+1;
};
this is a good setup because it adjusts to pastes, long text, enter keys, and whatever else makes it need to be taller.
i think you might need to adjust the border+padding allotment.
2px is default on fiddle (0px padding + 1px each border) and works perfect.
obligatory fiddle: http://jsfiddle.net/aqfkqc8y/6/

How to move placeholder text along with the content of a textbox in HTML?

Suppose this is my textbox:
<input type="text" placeholder="%" />
And a user is supposed to enter a percentage inside, but without the % sign, only the numbers (e.g. 67 in 67%). But I want them to still remember that this is a text box in which you insert a percentage.
So how can I move the placeholder along with the text, make it unable to be deleted, always after the text?
And I do remember seeing it somewhere too, unless I got my facts wrong.
A way to do this would be to have an additional element overlaying the input element and moving the overlayed element as the user types.
But, I think a better UX experience would be to have the element as an add-on appended to the input field, as show in twitter bootstrap. See the "extending form controls" settings:
http://twitter.github.com/bootstrap/base-css.html#forms
You could simulate an input and change the width of the real input using javascript. (The trick is to use some invisible element to catch the needed width)
Exemple using JQuery: http://jsfiddle.net/Vu7hN/
$input.on('change keypress paste focus textInput input', function(){
testWidth.text($input.val());
$input.width(testWidth.width());
});

Can I move a DOMElement while preserving focus?

Suppose I have a simple HTML page with a textarea, and I want to wrap that textarea in a DIV. However, this doesn't always happen on startup / page load, so the user might have focus in that area, or even be typing.
I can move / wrap the area by creating a DIV, appending it to the textarea's parent, then putting the textarea inside of it, and it works great. However, when I do that, focus is removed from the textarea and if the user was in the middle of typing, they're going to get angry.
How can I move the textarea's DOM node without interrupting the user? Is this even possible?
Depending on the browser you may be able to determine which element has focus by using document.activeElement. Save the value before performing the move and then afterwards set the focus back using .focus() in the textarea is the same element as what you saved.
Well, refocusing (using focus()) is one thing, but you'll also want to keep the user's cursor at the same location (and possibly his current selection, if he's made one). It is possible though, using the document.selection/range API, see https://developer.mozilla.org/en/DOM/range .
This link describes a solution (slightly different problem) using that API in IE.
You only have to reset the focus after you move everything.
Use
.focus()
On your textArea after the move.
After appending the textarea to the div you simply have to call focus on the textarea, demonstrated in this fiddle
HTML
<textarea id="test">test</textarea>
JAVASCRIPT
var textarea = document.getElementById('test');
setTimeout(function(){
var div = document.createElement('div');
document.body.appendChild(div);
div.appendChild(textarea);
textarea.focus();
console.log('appended');
},2000);

Manually triggering the iPhone/iPad/iPod keyboard from JavaScript

I am developing an HTML code editor using simple DIV's and capturing events. When I use this on the iPad the keyboard never pops up since i'm not technically in an editable field.
Is there a way to programatically tell the iPad that I need a keybaord?
If your code is executed via something that was initiated via a user action then it will work.
E.g;
this works (pops keyboard):
<input type='text' id='foo'><div onclick='$("#foo").focus();'>click</div>
this doesn't work (input gets a border but no keyboard pop):
<input type='text' id='foo'>
<script>
window.onload = function() {
$("#foo").focus();
}
</script>
To make the keyboard show on iOS devices you need to focus on an editable element such as an input or a textarea. Furthermore, the element must be visible and the .focus() function must to be executed in response to a user interaction such as a mouse click.
The thing is - we DON'T want the input element to be visible..
I have fiddled with this for quiet some time and eventually got the result I was looking for.
First, create an element you want to use to show the keyboard - in this case a button, and a hidden input element: (Working jsFiddle or Test on a mobile device)
<button id="openKeyboard">Open Keyboard</button>
<input id="hiddenInput" style="visibility: hidden;">
Then use the following javascript:
document.getElementById('openKeyboard').addEventListener('click', function(){
var inputElement = document.getElementById('hiddenInput');
inputElement.style.visibility = 'visible'; // unhide the input
inputElement.focus(); // focus on it so keyboard pops
inputElement.style.visibility = 'hidden'; // hide it again
});
Notes:
I have noticed that iOS safari will automatically scroll and zoom to the area of the input so make sure you use proper viewport and position your input element in a relevant location.
You can use some CSS on your input like setting the opacity, height and width to 0. However, if your input is completely hidden this won't work again, so make sure you leave the padding or border just so there's something to be rendered (even though it won't show up due to the opacity). This also means you shouldn't use display:none to hide it, hidden elements are just not allowed to be focused.
Use the regular keyboard events (keydown, keypress, keyup) on your hidden input to access the user's interaction as you would normally do. Nothing special here.
Place a transparent textarea over the contentEditable div. The keyboard will open, as soon as the user focus the textarea.
Register an event listener on the textarea for the focus event and set the visibilityof the textarea to hidden. This prevents the blinking cursor.
Set the visibility of the textarea back to visible after the blur event occurred.
Register additional event listeners for keydown, keyup, keypressevents and process theses events the same way, as you process them in the contentEditable div.
I have found that calling prompt("Enter some value") does trigger the keyboard on my iPad 2. Not sure if this is helpful in your situation or not.
The answers to this questions suggest that it's not possible: Why doesn't #contenteditable work on the iPhone?
A colleague of mine who was working on a similar project ended up using a textarea for the iPad version of his editor, and contenteditable divs/spans for browsers that support contenteditable. Perhaps something similar would work for you.
Proxy input trick
I figured out another dirty workaround, but works well.
The trick is based on the fact, that if the keyboard is already open, changing the focus will not close the keyboard.
Add a small "proxy invisible input" in top left of the page with position fixed (the fixed position prevents the flicker, also make sure that the field has font-size bigger than 16px to prevent iOS page zoom on focus)
On clicking the button, just .focus() on this invisible field. The keyboard will open...
Show or render your other input fields
Now with the keyboard open just .focus() on the desired input. You can use small setTimeout delay, for example 500ms if needed
Here's a solution for you:
<input id="my-input" type="text" />
<script type="text/javascript">
var textbox = document.getElementById('my-input');
textbox.select();
</script>

Categories