Make input readonly on mobile devices only - javascript

I have an input that uses the bootstrap color picker. The input happens to be in a scrollable modal, and when it's about under half of the screen on a mobile phone, the virtual keyboard will partially or fully cover the color selector. I've managed to fix this by making the input readonly, since the click event is still triggered and the selector still appears. However I'd still like to let power-users on desktops type their own hex colors if they wish.
Is there any reliable way to make an input readonly only on mobile devices, that allows dynamic loading(input will be loaded via jquery's .load() or .html() if POST)?
Note that I'm aware I can do this by using it as a component, I just want to know if it's possible or not for future reference as well, though I'd prefer the current input-only design. I was very suprised there was nothing on this on SO especially since people had my problem but with the date-picker.

Maybe you could use media-queries and some sort of click-through stuff.
Cool thing is, it prevents javascript as well.
Here you go:
document.getElementById('test1').addEventListener('click', function() {
alert('1');
});
document.getElementById('test2').addEventListener('click', function() {
alert('1');
});
input[type="text"] {
pointer-events: none;
}
<input type="text" value="It's just a test 1" id="test1" />
<input type="search" value="It's just a test 2" id="test2" />
For better understanding i added two javascript clicks and as you can see, the click doesn't work for the input with "pointer-event:none".

Related

Cross-Browser: Different behaviors for disabled input fields (the text can/can't be copied)

I have a input html field that is disabled. In some browsers (Chrome, Edge, Internet Explorer and Opera) is possible to select and copy the text but, at least, in Firefox it is not possible.
You can test it by executing the following code in different browsers:
<input type="text" disabled value="is disable">
<input type="text" readonly value="is readonly">
I read in here that disabled fields can be focus, here that A disabled input element is unusable and un-clickable and in here that A read-only input field cannot be modified (however, a user can tab to it, highlight it, and copy the text from it).
I didn't find anything saying that the text from disabled inputs can't be copied.
There is standard behavior and some browsers are not respecting it or can the browsers choose if the text from a disabled input can or can't be copied?
And there is a solution for allowing, in all browsers, the text from a disabled input field to be copied?
Note: My application is implemented using Angular/TypeScript languages.
It seams that the only browser that has a distinct behavior is firefox. I opened an issue in here trying to understand if is a design option or if is a bug. I'm waiting now for an answer.
Change your field from disabled to readonly. That is the correct attribute for the behaviour you want.
Don't waste time hacking a javascript solution together as it will be even more flaky than the minor differences in browser behaviour.
If the issue is that you want your readonly fields to look like disabled fields, it's fairly easy to style an input with a readonly attribute set. You don't need to change behaviour to change appearance.
input[readonly] {
background: #EEE;
color: #666;
border: solid 1px #CCC;
}
<input readonly value="I am readonly">
I tried to use user-select in an input but it can't prevent selecting of text to it. Even wrap it to a div with a user-select: none style still not work. It's only work for (I think) non-focusable element like div, span, etc.
However, right now I think user-select: none is the only better option if you want to ensure that user won't copy the text from the page even in many different browsers (check user-select browsers compatibility). So I would suggest, create a component that something like this:
<input *ngIf="!isDisabled" value="model" />
<div *ngIf="isDisabled" style="user-select: none">{{model}}</div>
Caveat: You have to styled the div to be more like a disabled input.
There is nothing wrong with doing this when you disable a form control.
<input type="text" disabled readonly value="is disable">
or
<input type="text" disabled="disabled" readonly="readonly" value="is disable">
However, that may not produce consistent behavior as it pertains to copying text (after selecting it).
An Imperfect JavaScript Way:
I have not used a select type event in a while, but I suggest toggling the ability to select the text. You might also play with the focus and blur events.
External CSS Style Sheet:
.preventSelection {user-select: none} // IE 10+
W3Schools: user-select:
Quick and Dirty Event Handler:
function preventDisabledControlTextCopy(e)
{
// blah, blah, blah
if (e.target.disabled === true) {
// Add "preventSelection" to e.target.className
// Alternatively, change the focus to somewhere else!
} else {
// Remove "preventSelection" from e.target.className
}
}
// Blah, blah, blah-blah blah
textBox.addEventListener("select", preventDisabledControlTextCopy, false);
It is never a waste of time to seek options. I skipped many details, but I made the important part explicit (as Stackoverflow is a tool people use to learn things). Implementation is up to you.
Final Thoughts:
The best answer might be to use CSS and JavaScript and toggle visibility: hidden (IE 4+) or display: none (IE 8+), depending on your scenario, DOM structure, and the complexity you are able to manage.
Dynamic forms are a great way to experience the interplay between HTML, CSS, and JavaScript.

autofocus attribute not working in Firefox on display state change

I'm trying to add auto focus to a form. I have it working in Chrome but cannot get it working in Firefox with the below code. I think the reason could potentially be that it needs to be just autofocus rather than autofocus="autofocus". Would I be correct in assuming this? If so is there some way I can add it? I'm using a framework called SilverStripe and don't have direct access to editing the input field as it's done dynamically so would need to do it via JavaScript most likely.
<input type="text" name="Search" class="form-control search-form" id="TemplateSearchForm_SearchForm_Search" placeholder="Search..." autofocus="autofocus">
Note I am initially hiding the input box and displaying on the click of an icon by adding a class:
jQuery('.search').click(function () {
if(jQuery('.search-btn').hasClass('fa-search')){
jQuery('.search-open').fadeIn(500);
} else {
jQuery('.search-open').fadeOut(500);
}
});
I couldn't find anything in the HTML specification to validate the autofocus behavior exhibited by Chrome. Here's an excerpt from the spec on this behavior.
From 4.10.19.7 Autofocusing a form control: the autofocus attribute:
When an element with the autofocus attribute specified is inserted into a document, user agents should run the following steps:
[...]
Note: This handles the automatic focusing during document load.
It doesn't mention anything about applying this behavior when the display state changes (as Chrome is apparently doing), only when the element is first inserted into the DOM. This actually appears to a be a bug in Chrome as Firefox is following the HTML spec.
Instead of using the autofocus attribute, you will have to trigger the focus through JavaScript.
You could use JavaScript to automatically focus into any elements with autofocus='yes'
$('[autofocus="yes"], [autofocus="autofocus"], [autofocus="true"]').focus();
This should, theoretically target any elements that have autofocus set to either true, yes, or autofocus and focus on them.

How to prevent the virtual keyboard of mobile devices from showing up with javascript? [duplicate]

This question already has answers here:
prevent mobile default keyboard when focusing an <input> from showing
(9 answers)
Closed 5 months ago.
I am developing the front end site for a coupon company, and I have a page where the user only needs to input phone number and $$ spent. We came up with a fun on-screen keyboard built in Javascript, that is easy to use, and fast. However, I am looking for a solution to stop the soft keyboard from popping when the user focuses and enters text/numbers in those fields.
I know about the "number/phone/email" type attributes that HTML5 came up with. However, at the risk of sounding crazy, I really want to just use my on-screen keyboard.
Note: this web site is mostly targeted to tablets.
Thanks.
Scott S's answer worked perfectly.
I was coding a web-based phone dialpad for mobile, and every time the user would press a number on the keypad (composed of td span elements in a table), the softkeyboard would pop up. I also wanted the user to not be able to tap into the input box of the number being dialed. This actually solved both problems in 1 shot. The following was used:
<input type="text" id="phone-number" onfocus="blur();" />
Since the soft keyboard is part of the OS, more often than not, you won't be able to hide it - also, on iOS, hiding the keyboard drops focus from the element.
However, if you use the onFocus attribute on the input, and then blur() the text input immediately, the keyboard will hide itself and the onFocus event can set a variable to define which text input was focused last.
Then alter your on-page keyboard to only alter the last-focused (check using the variable) text input, rather than simulating a key press.
For further readers/searchers:
As Rene Pot points out on this topic,
By adding the attribute readonly (or readonly="readonly") to the input field you should prevent anyone typing anything in it, but still be able to launch a click event on it.
With this method, you can avoid popping up the "soft" Keyboard and still launch click events / fill the input by any on-screen keyboard.
This solution also works fine with date-time-pickers which generally already implement controls.
I'm very confused as to why no one has put this... maybe I'm misunderstanding the question but,
<input inputmode="none" />
Those answers aren't bad, but they are limited in that they don't actually allow you to enter data. We had a similar problem where we were using barcode readers to enter data into a field, but we wanted to suppress the keyboard.
This is what I put together, it works pretty well:
https://codepen.io/bobjase/pen/QrQQvd/
<!-- must be a select box with no children to suppress the keyboard -->
input: <select id="hiddenField" />
<span id="fakecursor" />
<input type="text" readonly="readonly" id="visibleField" />
<div id="cursorMeasuringDiv" />
#hiddenField {
height:17px;
width:1px;
position:absolute;
margin-left:3px;
margin-top:2px;
border:none;
border-width:0px 0px 0px 1px;
}
#cursorMeasuringDiv {
position:absolute;
visibility:hidden;
margin:0px;
padding:0px;
}
#hiddenField:focus {
border:1px solid gray;
border-width:0px 0px 0px 1px;
outline:none;
animation-name: cursor;
animation-duration: 1s;
animation-iteration-count: infinite;
}
#keyframes cursor {
from {opacity:0;}
to {opacity:1;}
}
// whenever the visible field gets focused
$("#visibleField").bind("focus", function(e) {
// silently shift the focus to the hidden select box
$("#hiddenField").focus();
$("#cursorMeasuringDiv").css("font", $("#visibleField").css("font"));
});
// whenever the user types on his keyboard in the select box
// which is natively supported for jumping to an <option>
$("#hiddenField").bind("keypress",function(e) {
// get the current value of the readonly field
var currentValue = $("#visibleField").val();
// and append the key the user pressed into that field
$("#visibleField").val(currentValue + e.key);
$("#cursorMeasuringDiv").text(currentValue + e.key);
// measure the width of the cursor offset
var offset = 3;
var textWidth = $("#cursorMeasuringDiv").width();
$("#hiddenField").css("marginLeft",Math.min(offset+textWidth,$("#visibleField").width()));
});
When you click in the <input> box, it simulates a cursor in that box but really puts the focus on an empty <select> box. Select boxes naturally allow for keypresses to support jumping to an element in the list so it was only a matter of rerouting the keypress to the original input and offsetting the simulated cursor.
This won't work for backspace, delete, etc... but we didn't need those. You could probably use jQuery's trigger to send the keyboard event directly to another input box somewhere but we didn't need to bother with that so I didn't do it.
example how i made it , After i fill a Maximum length it will blur from my
Field (and the Keyboard will disappear ) , if you have more than one field , you can just add the line that i add '//'
var MaxLength = 8;
$(document).ready(function () {
$('#MyTB').keyup(function () {
if ($(this).val().length >= MaxLength) {
$('#MyTB').blur();
// $('#MyTB2').focus();
}
}); });
I am facing the same issue, I am able to hide android keyboard even focus is in textbox by just adding one css property
<input type="text" style="pointer-events:none" />
and it works fine...
I am fighting the soft keyboard on the Honeywell Dolphin 70e with Android 4.0.3. I don't need the keyboard because the input comes from the builtin barcode reader through the 'scanwedge', set to generate key events.
What I found was that the trick described in the earlier answers of:
input.blur();
input.focus();
works, but only once, right at page initialization. It puts the focus in the input element without showing the soft keyboard. It does NOT work later, e.g. after a TAB character in the suffix of the barcode causes the onblur or oninput event on the input element.
To read and process lots of barcodes, you may use a different postfix than TAB (9), e.g. 8, which is not interpreted by the browser. In the input.keydown event, use e.keyCode == 8 to detect a complete barcode to be processed.
This way, you initialize the page with focus in the input element, with keyboard hidden, all barcodes go to the input element, and the focus never leaves that element. Of course, the page cannot have other input elements (like buttons), because then you will not be able to return to the barcode input element with the soft keyboard hidden.
Perhaps reloading the page after a button click may be able to hide the keyboard. So use ajax for fast processing of barcodes, and use a regular asp.net button with PostBack to process a button click and reload the page to return focus to the barcode input with the keyboard hidden.
I could not use some of the suggestions provided.
In my case I had Google Chrome being used to display an Oracle APEX Application.
There were some very specific input fields that allowed you to start typing a value and a list of values would begin to be displayed and reduced as you became more specific in your typing. Once you selected the item from the list of available options, the focus would still be on the input field.
I found that my solution was easily accomplished with a custom event that throws a custom error like the following:
throw "throwing a custom error exits input and hides keyboard";
This might help others, that just want to disable the soft keyboard in general. I managed to disable the soft keyboard not by javascript but by installing a new keyboard layout called Null Keyboard

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>

jquery: when i click a div, give focus to a textbox

$('.my-button').click(function() {
$(".my-textbox").focus()
});
Before Jquery 1.4 this used to be the way to call focus to a textbox, now it doesn't work. When I click the button, I want to call focus to the textbox, what i mean by "focus", is that I want the textbox to act like it was just clicked on, so that the user will not have to click on the textbox.
.focus is supposed to do an auto click onto the textbox i want it to, why isn't it working now? it broke in Jquery 1.4. I just need to know how to do it.
It still works. See here.
reference: jQuery focus docs
As mentioned there, calling 'focus' on one element may trigger 'blur' on another - and so use 'focusin' instead.
Your code works fine for me. However, it looks like you're trying to create a clickable label for an input element. If that's the case, there's an existing element named <label> that will do the job for you, no JavaScript required:
<label for="myTextBox">I'm a label, click me</label>
<input type="text" id="myTextBox" />
Example: http://jsfiddle.net/pkk6y/
Those are class selectors not IDs - not sure if that's relevant, but they're inherently not unique - particularly in the focus function jquery may just plain refuse - try using IDs (and #mybutton, #mytextbox)
Update: The jQuery doc page points out issues with IE:
The focus event does not bubble in
Internet Explorer. Therefore, scripts
that rely on event delegation with the
focus event will not work consistently
across browsers.

Categories