I would like to have an input that would change to upper case on keyup. So I attach a simple event on keyup.
HTML
<input id="test"/>
Javascript (with jQuery)
$("#test").keyup(function(){
this.value = this.value.toUpperCase();
});
But I found that in Chrome and IE, when you push left arrow, the cursor automatically move to end. I notice that I should detect if the input is letter only. Should I use keycode range or regexp for detection?
Example: http://jsbin.com/omope3
Or you can use the following (this is probably faster and more elegant):
<input style="text-transform: uppercase" type='text'></input>
But that sends the as-typed value back in the form data, so use either of the following to store it as all-caps in the database:
MySQL: UPPER(str)
PHP: strtoupper()
Another solution, if you use the text-transform: uppercase; css property:
<input id='test' style='text-transform: uppercase;' type='text'></input>
And with jQuery help you choose the blur event:
$("#test").blur(function(){
this.value = this.value.toUpperCase();
});
With this solution, you don't have to upper the database fields, you can use the cursor for movement and the user can insert/rewrite the text in the input field.
Use this:
<input onkeyup="MakeMeUpper(this)" type="text"/>
And in your JS Code Part put:
function MakeMeUpper(f, e){
var actualValue = f.value;
var upperValue = f.value.toUpperCase();
if( actValue != upperValue){
f.value = upperValue;
}
}
This code won't change the text if the user entered something that is not text (left or right arrow).
Yeah, looks like some browsers move the cursor to the end when the value gets updated. You could do this:
$("#test").keyup(function(){
var upper = this.value.toUpperCase();
if (this.value != upper)
this.value = upper;
});
which will only change the value if it needs to be changed. However, that still leaves you with the problem that if you type abd, move left, hit c to get abcd, the cursor will still get moved to the end.
Javascript (with jQuery)
$("#test").keyup(function(){
$(this).val($(this).val().toUpperCase());
});
var str = $(this).val();
if (evt.keyCode != 37 && evt.keyCode != 39)
{
str = str.toLowerCase().replace(/\b[a-z]/g, function(letter) {
return letter.toUpperCase();
});
$(this).val(str);
}
You probably want to look at keyCode in your keyup function.
var UP_ARROW = 38,
DOWN_ARROW = 40;
$('#test').keyup(function(evt){
if (evt.keyCode == UP_ARROW)
{
this.value = this.value.toUpperCase();
}
if (evt.keyCode == DOWN_ARROW)
{
this.value = this.value.toLowerCase();
}
});
Related
I'm trying to validate a character to make sure it's a letter (not a number, symbol, etc.) BEFORE it's allowed to be entered into the form field. How can I do that with JavaScript?
Here is something I tried:
<script type="text/javascript">
function checkTest() {
var letterValue = document.forms[0].test.value;
var letterCheck = /[a-z]/i;
var letterTest = letterValue.test(letterCheck);
}
</script>
<html>
<body>
<form>
<input type="text" name="test" onkeypress="checkTest();"/>
</form>
</body>
</html>
This code will check the string of the value. I've tried using var letterLeng= letterValue.length and then using var letterChar = letterValue.charAt(letterLeng) or even var letterChar = letterValue.charAt(letterLeng - 1) and all to no avail. Any advice would be much appreciated.
Ask the event for the key that was pressed then test it:
function checkTest(event) {
event = event || window.event;
if (!/[A-Za-z]/.test(String.fromCharCode(event.keyCode || event.which))) {
if (event.preventDefault)
event.preventDefault();
else
event.returnValue = false;
}
}
<input type="text" name="test" onkeypress="checkTest(event);"/>
I like Alex K's answer, but I could not get the 'onkeypress' handler to work so I tried something using Jquery. It doesn't keep the bad letters from appearing briefly, but it does keep them from being entered.
It uses the 'keyup' event, which actually makes checking for the key code much easier in this instance since you want to limit it to [a-zA-Z]
$("#myinput").on("keyup", function (e) {
// Ignore the shift key.
if (e.keyCode === 16) {
return true;
}
if ((e.keyCode < 65 || e.keyCode > 90)) {
var str = $("#myinput").val();
$("#myinput").val(str.slice(0, str.length - 1));
}
});
The working fiddle is here: http://jsfiddle.net/yaa9snce/
What you are looking for is the onkeypress event.
<input type="text" onkeypress="myFunction()">
<script>
function myFunction() {
alert("You pressed a key inside the input field");
}
</script>
When non-printable char is pressed, it's replaced with let's say for CTRL=17 with "[CTRL]".
Here is code an example
$('#textbox1').keyup(function (event) {
if (8 != event.keyCode) {
if(17==event.keyCode){
$('#textbox1').val($('#textbox1').val()+"[CTRL]")
$('#textbox2').val($('#textbox1').val());
}else{
$('#textbox2').val($('#textbox1').val());
}
} else {
$('#textbox2').val($('#textbox1').val());
}
});
the problem is when user presses backspace the second input must reflect the content of the first one, so "[CTRL]" must be deleted at once like any other chars.
You could make use of the keyCode and/or in combination with charCode (if required). Basic idea would be:
Create a map of all required key codes in an array/object
Handle event for say keydown and listen for keycode
Look for the keycode in your map and if found show it
prevent the default (to prevent e.g. say backspace browsing back)
If not found in map, let the character go thru as usual.
A very basic example:
Demo: http://jsfiddle.net/abhitalks/L7nhZ/
Relevant js:
keyMap = {8:"[Backspace]",9:"[Tab]",13:"[Enter]",16:"[Shift]",17:"[Ctrl]",18:"[Alt]",19:"[Break]",20:"[Caps Lock]",27:"[Esc]",32:"[Space]",33:"[Page Up]",34:"[Page Down]",35:"[End]",36:"[Home]",37:"[Left]",38:"[Up]",39:"[Right]",40:"[Down]",45:"[Insert]",46:"[Delete]"};
$("#txt").on("keydown", function(e) {
// check if the keycode is in the map that what you want
if (typeof(keyMap[e.keyCode]) !== 'undefined') {
// if found add the corresponding description to the existing text
this.value += keyMap[e.keyCode];
// prevent the default behavior
e.preventDefault();
}
// if not found, let the entered character go thru as is
});
Edit: (as per the comments)
The concept remains the same, just copying the value to the second input:
Demo 2: http://jsfiddle.net/abhitalks/L7nhZ/3/
$("#txt1").on("keyup", function(e) {
if (typeof(keyMap[e.keyCode]) !== 'undefined') {
this.value += keyMap[e.keyCode];
e.preventDefault();
}
$("#txt2").val(this.value); // copy the value to the second input
});
Regarding deletion of the description, I could not get it done by caching the last inserted descrition from the map. Somehow, I kept struggling with the regex with a variable. Anyway, a simpler solution is to just add another event handler for keyup with hard-coded map.
Thanks to #serakfalcon for (that simple solution), which we are using here:
$('#txt1').keydown(function(event) {
if(8 == event.keyCode) {
var el = $(this);
el.val(el.val().replace(/\[(Tab|Enter|Shift|Ctrl|Alt|Break|Caps Lock|Esc|Space|Page (Up|Down)|End|Home|Left|Up|Right|Down|Insert|Delete)\]$/,' '));
$("#txt2").val(el.val());
}
});
You can check in the keydown for the last character in the input field. If it's a ] you can remove everything from the right to the last found opening bracket [. Unfortunatly this does not work if you're cursor is inside '[ ]'.
$('#textbox1').keydown(function(event) {
if(8 == event.keyCode) {
var element = $(this),
value = element.val(),
lastChar = value.slice(-1);
if(lastChar == ']') {
var lastIndex = value.lastIndexOf('['),
index = value.length - lastIndex;
element.val(value.slice(0, -index) + "]");
}
}
});
Fiddle
you can always use a regex.
$('#textbox1').keydown(function(event) {
if(8 == event.keyCode) {
var el = $(this);
el.val(el.val().replace(/\[(CTRL|ALT|SHIFT)\]$/,' '));
}
});
fiddle
Edit: combined with abhitalks code
Is there a way to block users from writing specific characters in input fields? I tried the code below, but when a user enters disallowed characters, they appear for a brief period before disappearing. I want the input to remain unchanged when invalid characters are written.
I want to use onchange because other restriction methods do not seem to work on mobile devices. The problem I want to solve is that characters appear briefly before being removed.
function checkInput(ob) {
const invalidChars = /[^0-9]/gi;
if(invalidChars.test(ob.value)) {
ob.value = ob.value.replace(invalidChars, "");
}
};
<input class="input" maxlength="1" onChange="checkInput(this)" onKeyup="checkInput(this)" type="text" autocomplete="off" />
you can use try this,
$('.input').keyup(function () {
if (!this.value.match(/[0-9]/)) {
this.value = this.value.replace(/[^0-9]/g, '');
}
});
SEE THIS FIDDLE DEMO
Updated :
You can try this Code,
$(document).ready(function() {
$(".input").keydown(function (e) {
// Allow: backspace, delete, tab, escape and enter
if ($.inArray(e.keyCode, [46, 8, 9, 27, 13, 110]) !== -1 ||
// Allow: Ctrl+A
(e.keyCode == 65 && e.ctrlKey === true) ||
// Allow: home, end, left, right
(e.keyCode >= 35 && e.keyCode <= 39)) {
// let it happen, don't do anything
return;
}
// Ensure that it is a number and stop the keypress
if ((e.shiftKey || (e.keyCode < 48 || e.keyCode > 57)) && (e.keyCode < 96 || e.keyCode > 105)) {
e.preventDefault();
}
});
});
SOURCE
SEE UPDATED FIDDLE DEMO
UPDATED FOR ANDROID:
<EditText
android:id="#+id/editText1"
android:inputType="number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/textView1"
android:layout_marginTop="58dp"
android:layout_toRightOf="#+id/textView1"
android:maxLength="1" >
</EditText>
I think it may help you... using android:inputType="number" you can do that.
A combination of keypress and paste events does a trick:
var text = document.getElementById('text');
text.onkeypress = text.onpaste = checkInput;
function checkInput(e) {
var e = e || event;
var char = e.type == 'keypress'
? String.fromCharCode(e.keyCode || e.which)
: (e.clipboardData || window.clipboardData).getData('Text');
if (/[^\d]/gi.test(char)) {
return false;
}
}
<input class="input" maxlength="10" id="text" type="text" autocomplete="off" />
This code prevents from typing or pasting anything but a number. Also no blinking and invalid characters don't show up.
Works in IE7+.
Demo: http://jsfiddle.net/VgtTc/3/
All answers given so far suffer from at least one of the following accessibility issues:
They validate key codes, which does not work with non-QWERTY keyboard layouts.
They do not cover all input methods; especially drag&drop is often forgotten.
They alter the value, which resets the position of the caret.
They use the pattern attribute, but this does not provide feedback until the form is submitted.
Wouldn't it be a much better idea to actually validate the input before it's inserted?
The beforeinput event fires before the input's value is changed. The event has a data property which describes the content that the user wants to add to the input field. In the event handler, you simply check the data attribute, and stop the event chain if it contains disallowed characters.
We end up with the following very simple, very short code.
const input = document.getElementById("input");
const regex = new RegExp("^[0-9]*$");
input.addEventListener("beforeinput", (event) => {
if (event.data != null && !regex.test(event.data))
event.preventDefault();
});
<label for="input">Enter some digits:</label>
<input id="input" />
Some closing notes:
Accessibility: Provide a clear explanation of what input format is expected from the user. For example, you can use the title attribute of the input to show a tooltip explaining the expected format.
Security: This is client-side validation, and does not guarantee that the pattern is enforced when the form is sent to a server. For that, you'll need server-side validation.
Here's a little hack you could try: DEMO
What it does is that it colors every input text white and then changes it back to black if it suits your requirements. If you could live with the bit of lag that occurs when you enter a valid character.
function checkInput(ob) {
var invalidChars = /[^0-9]/gi
if (invalidChars.test(ob.value)) {
ob.value = ob.value.replace(invalidChars, "");
}
else {
document.getElementById('yourinput').style.color = '#000';
}
};
function hideInput(ob) {
document.getElementById('yourinput').style.color = '#FFF';
};
html
<input id="yourinput" class="input" maxlength="1" onKeydown="hideInput(this)" onKeyup="checkInput(this)" type="text" autocomplete="off" />
css
input {color:#FFF;}
check this code,
$('.input').keypress(function(e) {
var a = [];
var k = e.which;
for (i = 48; i < 58; i++)
a.push(i);
if (!(a.indexOf(k)>=0))
e.preventDefault();
});
<input id="testInput"></input>
<script>
testInput.onchange = testInput.oninput = restrict;
function restrict() {
testInput.value = testInput.value.replace(/[^a-z]/g, "");
}
</script>
I came up with something slightly different. oninput instead of onkeyup/onkeydown, and onchange instead of onpaste.
I restrict invalid characters on both keypress and paste events like:
<input type="text" onkeydown="validateKey(event)" onpaste="validatePaste(this, event)">
And define functions to handle these events inside tab or a separate javascript file:
<script>
function validateKey(e) {
switch(e.keyCode) {
case 8,9,13,37,39:
break;
default:
var regex = /[a-z .'-]/gi;
var key = e.key;
if(!regex.test(key)) {
e.preventDefault();
return false;
}
break;
}
}
function validatePaste(el, e) {
var regex = /^[a-z .'-]+$/gi;
var key = e.clipboardData.getData('text')
if (!regex.test(key)) {
e.preventDefault();
return false;
}
}
</script>
This involves HTML + JS and/or JQuery:
I would have commented on the previous post, but I don't have comment reputation or cannot comment for some reason.
Josh Stodola's great code from Part I is as follows:
$(function() {
var txt = $("#myTextbox");
var func = function() {
txt.val(txt.val().replace(/\s/g, ''));
}
txt.keyup(func).blur(func);
});
This works great except .replace puts the cursor at the end of the string on every keyup (at least in IE8 and Chrome).
As a result, it renders the left & right cursor keys useless, which is needed inside the input box.
Is there any way to enhance the above code so that the cursor keys do not activate it, but so that the text still gets updated on the fly?
The best solution is to avoid using key events to capture text input. They're not the best tool for the job. Instead, you should use the HTML5 oninput event (supported in the latest and recent versions of every current major browser) and fall back to onpropertychange for older versions of Internet Explorer:
var alreadyHandled;
txt.bind("input propertychange", function (evt) {
// return if the value hasn't changed or we've already handled oninput
if (evt.type == "propertychange" && (window.event.propertyName != "value"
|| alreadyHandled)) {
alreadyHandled = false;
return;
}
alreadyHandled = true;
// Your code here
});
These events don't fire for keys that don't result in text entry — don't you just hate it when you shift-tab back to a form element and the resulting keyup event causes the page's script to move focus forward again?
Additional benefits over key events:
They fire immediately when the key is pressed and not when the key is lifted, as in keyup. This means you don't get a visual delay before any adjustments to the text are made.
They capture other forms of text input like dragging & droppping, spell checker corrections and cut/pasting.
Further reading at Effectively detecting user input in JavaScript.
Update the function:
var func = function(e) {
if(e.keyCode !== 37 && e.keyCode !== 38 && e.keyCode !== 39 && e.keyCode !== 40){
txt.val(txt.val().replace(/\s/g, ''));
}
}
try:
$(function() {
var txt = $("#myTextbox");
var func = function(e) {
if(e.keyCode != "37" && e.keyCode != "38" && e.keyCode != "39" && e.keyCode != "40"){
txt.val(txt.val().replace(/\s/g, ''));
}
}
txt.keyup(func).blur(func);
});
$(function() {
var txt = $("#myTextbox");
var func = function() {
txt.val(txt.val().replace(/\s/g, ''));
}
txt.keyup(function(evt){
if(evt.keyCode < 37 || evt.keyCode > 40) {
func;
}
}).blur(func);
});
Something like that should do it. It will run the function if the keycode isn't 37,38,39 or 40 (the four arrow key keycodes). Note that it won't actually stop the cursor position moving to the end when any other key is pressed. For that, you'd need to keep track of the current cursor position. Take a look at this link for jCaret plugin, which can do this
Is it possible to bind Ctrl+Alt+L to insert predefined string into focused textarea to cursor position? For example, I'm typing some text in textarea, then I'm pressing Ctrl+Alt+L and is inserted into current cursor position.
Yes. Use the keydown event and one of the caret-position-in-textarea functions floating around on Stack Overflow. For the key detection, note I've had to use the keydown event rather than the keypress event (which is what should be used for detecting what character has been typed) because IE doesn't fire the keypress events for Ctrl+Alt+L, so this could go wrong on differently mapped keyboards. For the cursor position, I've copied from this answer and have used something similar myself. See these answers for discussion of the problems with this in IE:
Caret position in textarea, in characters from the start
Is there an Internet Explorer approved substitute for selectionStart and selectionEnd?
Also, note that you may want to position the cursor somewhere sensible after doing this, which my code doesn't cover.
function getCaret(el) {
if ("selectionStart" in el) {
return el.selectionStart;
} else if (document.selection) {
el.focus();
var r = document.selection.createRange();
if (r == null) {
return 0;
}
var re = el.createTextRange(), rc = re.duplicate();
re.moveToBookmark(r.getBookmark());
rc.setEndPoint("EndToStart", re);
return rc.text.length;
}
return 0;
}
var textArea = document.getElementById("yourTextarea");
textArea.onkeydown = function(evt) {
evt = evt || window.event;
if (evt.ctrlKey && evt.altKey && evt.keyCode == 76) {
var cursorPos = getCaret(this);
this.value = this.value.slice(0, cursorPos)
+ ''
+ this.value.slice(cursorPos)
return false; // Prevent any default browser behaviour
}
};
I'm not sure about Ctrl-Alt-L, but there are definately ways to do this. For example:
<textarea name="MyText" id="MyText" onKeyPress="handleKey(this);"
onKeyDown="CaptureKeyDown(this);"></textarea>
<script>
function handleKey(ta) {
if (event.keyCode == 12) { // Ctrl-L
// Do your insert here
}
}
</script>
It is more complicated than this. Check out this HTML editor (written in HTML and JavaScript) at http://www.boltbait.com/htmleditor/ (the source can be downloaded there).
EDIT: Oops! I didn't see your jquery tag.