I'm building a JavaScript game where audio plays and based on the audio you're supposed to type some text into a big textbox. JavaScript is used to score your answer and then clear the textbox to prepare for the next audio clip.
The problem: In some cases when pressing the esc (escape) key while focused within an empty <input type="text" />, the textbox gets populated with some old text.
I'm using MooTools and have tried using event.stop() (which stops propagating and also executes preventDefault) within keypress, keydown, and keyup with no luck.
How can I prevent the [esc] button from changing the value within a textbox?
(This is important because I'm using the [esc] key as a keyboard shortcut to replay the audio)
I was able to fix this by just calling blur() and then focus() on the input box. That cleared the problem in Firefox for me at least.
Interesting problem - it happens in IE for example but not Chrome. Here is a solution I have tested in Chrome and IE (it seems to work).
Expanded version:
Script in page header:
<script>
var buff; //Must have global scope
var input = document.getElementById("testinput"); //Defined here to save cpu (instead of on every key press).
function CheckPreBuff(e)
{
var ev = window.event ? event : e; //Get the event object for IE or FF
var unicode = (typeof(ev.keyCode) != "undefined")? ev.keyCode : ev.charCode;
if(unicode != 27) buff = input.value; //The 'escape' key has a unicode value of 27
else input.value = buff; //Only set the input contents when needed, so not to waste cpu.
}
</script>
Where 'testinput' is the input we are disabling escape on. The testinput html is below:
<input id="testinput" onkeypress="CheckPreBuff();" onkeyup="CheckPreBuff();" type="text"/>
Notice both 'onkeyup' and 'onkeypress' were used - technically only 'onkeyup' is needed, although using 'onkeypress' prevents the text box going blank momentarily whilst the escape key is depressed.
Manually minified + error prevention + multiple inputs supported (if you prefer)
Script in header:
<script>
var buff = [];
function InitCPB(obj){if(typeof(obj)=="undefined")return;buff[0]=obj;buff[1]="";obj.onkeypress=CPB;obj.onkeyup=CPB;}
function CPB(e){if(typeof((buff[0]))=="undefined")return;var ev=window.event?event:e;(((typeof(ev.keyCode)!="undefined")?ev.keyCode:ev.charCode)!=27)?buff[1]=(buff[0]).value:(buff[0]).value=buff[1];}
</script>
testinput html tag (although an id is no longer needed):
<input onfocus="InitCPB(this);" type="text"/>
Both methods keep a copy of what the text inputs contained before the next key was pressed, if the key pressed was 'escape', unicode 27, then the previous text entry was put back into the text box (this is discriminatory so the script does not add too much load to the browser on every key press).
The second version allows for multiple text inputs on the same page having the escape key disabled - just so long as they have the onFocus attribute set as above (the multiple elements will not interfere with each other). It also checks the objects being passes to it are defined, to prevent accidental mis-implementation giving IE a heart attack!
I hope this helps.
When escape detected do what is needed to be done and at the end return false;
It solved the problem in firefox 25 for me.
Related
Looking for a simple and clear way to detect when a enter key was pressed over an input text in order to be able to perform the move to the next input field and get triggered the validation related events.
After several attempts I found the answer.
It is necessary to add a couple of tags within the input text source code tags, one for the Javascript which will be triggered by onkeypress and another one for the clientlistener which will "attach" the defined Javascript function to the specific input text.
Tested on Jdeveloper 11.1.2.1.0, this will cause a tab-like behaviour if the enter key is pressed, useful to manage an input from a barcodescanner which cannot be programmed to send a tab keychar after the reading
<af:inputText> .... [here you will have several tags and attributes, just start to write before the closing tag for your inputText]
<af:resource type="javascript">
function takeEnterAsTab(componentEvent)
{
var evt = componentEvent.getNativeEvent();
if (AdfAgent.AGENT.getKeyCode(evt) == 13)
{
AdfFocusUtils.focusNextTabStop(componentEvent.getNativeEventTarget());
}
}
</af:resource>
<af:clientListener method="takeEnterAsTab" type="keyPress"/>
</af:inputText>
How can i capture the following keys in Textbox using JavaScript?
Ctl + a
Ctl + c
Ctl + v
Following is the original Situation.
I have three Textboxes for Phones numbers. Textbox1 max length is 3 , 2nd's is 3 and 3rd is 4. When user types three digits in TextBox1 the cursor moves automatically to TextBox2 same thing happens with TextBox2 as well as TextBox3. I am handling this functionality in keyup event. Now, I am parallely using your code. But it moves in keyup event as well. This case happens when all TextBoxes are filled. Now suppose I am in TextBox1 and presses Ctl + A . This moves the user to third TextBox(unacceptable case). This is the issue.
Use the select, copy and paste events respectively. Pretty much universally supported these days.
var textBox = document.getElementById("textBoxId");
textBox.onpaste = function() {
alert("paste");
};
Likewise for the other events. Demo here: http://jsfiddle.net/timdown/EC2Hf/
And what about right click, osx that does not use control, the edit copy option on the browser, the button on my old keyboard, etc?
There is more than just key presses.
That said, most browsers support
oncopy and onpaste events.
You would have to first check if the ctrl button was clicked and then the correspnding letter keys. This link may help you out
I have a input text box disabled:
<input type="text" name="name" disabled="disabled" />
In IE and in Chrome you can copy and paste the value populated in that input field but in Firefox you cannot.
Firefox does not allow clipboard manipulation through JavaScript for valid security concerns.
Any suggestion? Is there a work around this?
readonly="readonly" will do the job
it should be supported by the major browsers
I don't like using readonly="readonly", ever. It leaves the field focusable and reachable via tab keypress and, if, god forbid, the user hits the backspace key while the read-only field is focused, then most browsers treat it like the user hit the 'back' button and bring up the previously viewed page. Not what you want to see happen when you're filling out a large form, especially if you are using some archaic browser that doesn't preserve the form data when you hit the 'next' button to return to it. Also very, very bad when using some single-page web application, where 'back' takes you to a whole other world, and 'next' doesn't even restore your form, much less its data.
I've worked around this by rendering DIVs instead of input fields when I need the field disabled (or PRE instead of a textarea). Not always easy to do dynamically but I've managed to make fairly short work of it with AngularJS templates.
If you have time, head over to the Mozilla Bugzilla and ask them to fix it.
tl;dr: Support for selecting and copying text in a disabled field is unreliable; use the readonly attribute or a non-input element, such as a <span> instead, if this functionality is necessary. Use JavaScript to modify the behavior of the readonly input to prevent unwanted behavior such as going back a page when someone hits the backspace key while the readonly input has focus.
*UPDATE: 2018.12.24
The spec has changed since this answer was originally posted (thanks to Wrightboy for pointing this out); it now includes the following caveat with regards to disabled fields:
Any other behavior related to user interaction with disabled controls, such as whether text can be selected or copied, is not defined in this standard.
— https://html.spec.whatwg.org/multipage/input.html#the-readonly-attribute
Disabled fields still cannot receive focus nor click events.
Because the standard does not define whether or not text within disabled controls can be selected or copied and because at least one major browser doesn't support that functionality, it's probably best to avoid relying on that behavior.
Original Answer
This is the expected behavior for a disabled field (as of the original date of this answer). IE and Chrome are being generous, but Firefox is behaving appropriately.
If you want to prevent the user from changing the value of the field, but you still want them to be able to read it, and/or copy it's value, then you should use the readonly attribute. This will allow them to set focus to the element (necessary for copying), and also access the field via the tab button.
If you are concerned about a user accidentally hitting the backspace button inside the readonly field and causing the browser to navigate back a page, you can use the following code to prevent that behavior:
document.addEventListener("DOMContentLoaded", function() {
var inputs = document.querySelectorAll('[readonly]');
for(var i=0; i < inputs.length; i++){
inputs[i].addEventListener('keydown', function(e){
var key = e.which || e.keyCode || 0;
if(key === 8){
e.preventDefault();
}
})
}
});
<input value="Hello World" readonly=readonly />
As quick answer, one can have another not disabled element to enable + copy/paste + redisable your input text, like this:
$('#btnCopy').click(function(){
$('#txtInputDisabled').removeAttr('disabled');
$('#txtInputDisabled').select();
document.execCommand("copy");
$('#txtInputDisabled').attr('disabled','disabled');
});
You can se my complete response to this post
Refer to my post to the same question. It does the following:
Makes the textbox just like readonly without using the readonly attribute on the input tag, but will honor tab index and set focus
Supports all clipboard functions win and mac with mouse or keyboard
Allows undo, redo and select all
Restrict HTML input to only allow paste
You can accomplish this in share point by utilizing the contenteditable attribute as follows with jquery.
$("#fieldID").attr("contenteditable", "false");
This will allow the user to highlight the text and copy it but will not allow them to enter anything in the field.
My site has an input box, which has a onkeydown event that merely alerts the value of the input box.
Unfortunately the value of the input does not include the changes due to the key being pressed.
For example for this input box:
<input onkeydown="alert(this.value)" type="text" value="cow" />
The default value is "cow". When you press the key s in the input, you get an alert("cow") instead of an alert("cows"). How can I make it alert("cows") without using onkeyup? I don't want to use onkeyup because it feels less responsive.
One partial solution is to detect the key pressed and then append it to the input's value, but this doesn't work in all cases such as if you have the text in the input highlighted and then you press a key.
Anyone have a complete solution to this problem?
NOTE: It's over a decade (!!) since I wrote this answer. The input event has become ubiquitous, and should be used instead of this hack.
What does keydown/keyup even mean for tablet and voice input devices?
The event handler only sees the content before the change is applied, because the mousedown and input events give you a chance to block the event before it gets to the field.
You can work around this limitation by giving the browser a chance to update the field's contents before grabbing its value - the simplest way is to use a small timeout before checking the value.
A minimal example is:
<input id="e"
onkeydown="window.setTimeout( function(){ alert(e.value) }, 1)"
type="text" value="cow" />
This sets a 1ms timeout that should happen after the keypress and keydown handlers have let the control change its value. If your monitor is refreshing at 60fps then you've got 16ms of wiggle room before it lags 2 frames.
A more complete example (which doesn't rely on named access on the Window object would look like:
var e = document.getElementById('e');
var out = document.getElementById('out');
e.addEventListener('input', function(event) {
window.setTimeout(function() {
out.value = event.target.value;
}, 1);
});
<input type="text" id="e" value="cow">
<input type="text" id="out" readonly>
When you run the above snippet, try some of the following:
Put the cursor at the start and type
Paste some content in the middle of the text box
Select a bunch of text and type to replace it
Please, try to use oninput event.
Unlike onkeydown, onkeypress events this event updates control's value property.
<input id="txt1" value="cow" oninput="alert(this.value);" />
Note that in newer browsers you'll be able to use the new HTML5 "input" event (https://developer.mozilla.org/en-US/docs/DOM/window.oninput) for this. Most non-IE browsers have supported this event for a long time (see compatibility table in the link); for IE it's version >/9 only unfortunately.
keyup/down events are handled differently in different browsers. The simple solution is to use a library like mootools, which will make them behave the same, deal with propagation and bubbling, and give you a standard "this" in the callback.
To my knowledge you can't do that with a standard input control unless you roll your own.
Jquery is the optimal way of doing this. Please reference the following below:
let fieldText = $('#id');
let fieldVal = fieldText.val();
fieldText.on('keydown', function() {
fieldVal.val();
});
How to restrict the maximum number of characters that can be entered into an HTML <textarea>? I'm looking for a cross-browser solution.
The TEXTAREA tag does not have a MAXLENGTH attribute the way that an
INPUT tag does, at least not in most standard browsers. A very simple and effective way to limit the number of characters that can be typed into a TEXTAREA tag is:
<textarea onKeyPress="return ( this.value.length < 50 );"></textarea>
Note: onKeyPress, is going to prevent any button press, any button including the backspace key.
This works because the Boolean expression compares the field's length
before the new character is added to the maximum length you want (50 in this example, use your own here), and returns true if there is room for one more, false if not. Returning false from most events cancels the default action.
So if the current length is already 50 (or more), the handler returns false,
the KeyPress action is cancelled, and the character is not added.
One fly in the ointment is the possibility of pasting into a TEXTAREA,
which does not cause the KeyPress event to fire, circumventing this check.
Internet Explorer 5+ contains an onPaste event whose handler can contain the
check. However, note that you must also take into account how many
characters are waiting in the clipboard to know if the total is going to
take you over the limit or not. Fortunately, IE also contains a clipboard
object from the window object.1 Thus:
<textarea onKeyPress="return ( this.value.length < 50 );"
onPaste="return (( this.value.length +
window.clipboardData.getData('Text').length) < 50 );"></textarea>
Again, the onPaste event and clipboardData object are IE 5+ only. For a cross-browser solution, you will just have to use an OnChange or OnBlur handler to check the length, and handle it however you want (truncate the value silently, notify the user, etc.). Unfortunately, this doesn't catch the error as it's happening, only when the user attempts to leave the field, which is not quite as friendly.
Source
Also, there is another way here, including a finished script you could include in your page:
http://cf-bill.blogspot.com/2005/05/textarea-maxlength-revisited.html
HTML5 now allows maxlength attribute on <textarea>.
It is supported by all browsers except IE <= 9 and iOS Safari 8.4. See support table on caniuse.com.
$(function(){
$("#id").keypress(function() {
var maxlen = 100;
if ($(this).val().length > maxlen) {
return false;
}
})
});
Reference Set maxlength in Html Textarea