I am sure this is something really stupid I am missing.
I am writing a small snippet that adds a hyphen to a string grabbed from an input field. The hyphen is only added once we hit position 4, so I can type 123 and the hyphen will not appear. If I type 1234, it'll automatically change to 1234-. The problem is with handling pasting, somewhere down the line inside jQuery (after my code has executed), it's injecting more characters into the field.
My approach is simple enough. I look at the keyup and keydown event, check the input and insert the hyphen. For pasting I look at the paste even, grab the string, split it and insert a hyphen depending on if one is present or not.
$('[id$="field"]').on('paste', function (event) {
var element = this;
var text = event.originalEvent.clipboardData.getData('text').split('');
if (text.length > 4 && text.indexOf('-') < 0) {
text.splice(4, 0, '-');
$(element).val(text.join(''));
}
});
$('[id$="field"]').bind('keyup keydown', function (event) {
var input = $(this).val();
if (input.length === 4 && event.keyCode !== 8) {
$($(this).val(input + '-'));
}
});
The keyup and keydown listener works just fine. If I paste in 12345, I end up with 1234-5 when I hit $(element).val(text.join('')); yet afterwards that extra char pops whilst jQuery is doing its thing.
I am rather baffled.
Any ideas?
Since you are overriding the typical "paste" behavior by updating the value of the input box directly, you need to prevent the "default" paste behavior.
$('[id$="field"]').on('paste', function (event) {
event.preventDefault();
// ...
Related
I am having a input type text.
<input type="text" class="checkForDot" />
What i am trying to do is, when a user enters numbers into the box then find for the "." in the field, if it contains more then one ".", then prevent it to enter another "." in the text field.
my jquery code is:
$(".checkForDot").on("keyup", function (event) {
CheckForDot($(this).val());
});
function CheckForDot(value) {
if (value != null || value != '') {
var str = value.toString();
if (str.indexOf('.', str.indexOf('.') + 1) != -1) {
console.log("ok");
}
}
}
It is working fine, if two "." enters into the text box, but how to prevent to enter multiple "." in the text field?
If any other approach better than this please tell.
$(document).ready(function() {
var original='';
$('.checkForDot').on('input', function() {
if ($(this).val().replace(/[^.]/g, "").length > 1){
$(this).val(original);
}else{
original = $(this).val();
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type='text' class='checkForDot' />
Try to use this regex to find how many dots you got in string.
If you are looking to make a field that only allows for numbers, you should consider using an input of type="number" as they will only allow for valid number characters to by added to its value. In some cases, it might even bring a different visual keyboard to ease of filling, wich is better for accessibility and UX. The number input field will, by default allow for mutliple dots, wich is annoying and is a bit harder to prevent than in a text field so it's a case of figuring wether accessibility and your UX is more important than adding a few extra lines of Javascript.
A lot of people will tell you that it is bad practice to limit keyboard actions, and they are right. when you do a preventDefault() on everything but numbers and ".", you disable tabing through form fields, the browser alt menu, any ctrl shortcuts, anything that happens within the browser.
This solution is simple and will only allow one dot in the number field. It doesn't prevent from clicking back in the number and adding numbers before the ".". It doesn't prevent from executing browser keyboard shortcuts like refresh, copy and pasting, as long as the pasted value is a valid number. It will allow to add "." withing the body of the number.
The only behavior that can't be prevented is if the user press the dot key at the end of the input repeatedly, the dot will blink on and off. This happens because of the way the number field handles its value. Wen the user types a dot at the end of a number like "13.", javascript can only retreive "13" when looking at its value as long as no decimal number have been placed. If the user typed a dot again, the value of "13.." would not be a valid number and therefore javascript woudl retreive "". This ensure you eighter get a valid number or nothing at all. In my solution, if a value returns "" without the press of backspace, delete or cut, it gets rolled back to the last valid value, wich in my example was "13", obtained from the typed value "13.". Preventing this behavior seems practically impossible and isn't a deal breaker as you get ensured your field value is always a valid, single dot number.
let lastValidInputValue;
let selectedDot = false;
const onKeypress = (e) => {
if (e.key === "." && e.target.value.indexOf(".") !== -1 && !selectedDot) e.preventDefault();
selectedDot = false;
};
const onInput = (e) => {
if (e.target.value !== "") {
lastValidInputValue = e.target.value;
} else if (e.inputType.match(/delete/g)) {
lastValidInputValue = "";
} else {
e.target.value = lastValidInputValue;
}
};
const onSelect = (e) => {
selectedDot = (window.getSelection().toString().indexOf(".") > -1)? true : false;
}
<input type="number" id="myNumber" name="myNumber" step="any" onkeypress="onKeypress(event)" oninput="onInput(event)" onselect="onSelect(event)">
You can find very detailed comments and extra bits in this Codepen
Right now i can detect if the input changes in the TinyMCE Editor, but i can't seem to figure out how to get what was changed/typed.
setup:function(editor) {
editor.on('input', function(e){
//pseudo condition
if (this.value === 'X') {
console.log('You type X', e);
}
});
}
I would like it to reach the console.log if X is typed into the editor, and maybe a way to move from that position back and forward just in case i have read pre and post text from that specific position.
The purpose of this is to be able to trigger another action when a specific word is typed into the editor like for suggestions and such.
There is a slice() function in JavaScript that returns you a "slice" of a string. You can use it to determine (for example) what are the last 6 characters in your input.
Example:
setup:function(editor) {
editor.on('input', function(e){
if (this.value.slice(this.value.length - 6, this.value.length) === '{link:') {
//Do magic
}
});
}
I am working on a function to limit the number of chars. a user is allowed to type inside an input text field.
This is it:
$.fn.restringLength = function (id, maxLen) {
$(id).keypress(function(e){
var kCode = e.keyCode ? e.keyCode : e.which,
len = $(id).val().length;
if (kCode != 8 && kCode != 46) {
if (len > maxLen) e.preventDefault();
}
});
}
The function binds the keypress event and gets the code of the pushed key.
If the char. limit is reached, it allows only the delete and backspace keys to be pushed.
What it needs to work great, is a way to bind the "onselect" event in order to have the following behavior:
when the user selects the whole text with the mouse, and types a letter or a number, the whole text gets deleted and that letter appears.
This is something that most of us do when we want to replace some text with another, and I'd like my function to enable this.
Any ideas how?
If i may add something,
Your solution use keypress event, so the event is triggered before the new value of input is computed. That's why you have to check for special key like backspace , enter ... theses do not just add a character to the string so they require special treatment.
For this kind of processing, it's more convinient to have the handler triggered after the string computation. In that way, you can access the input value and modify it if it's not correct.
Unfortunately jquery does not support this event but you can use it with vanilla javascript method.
$(id)[0] // get the vanilla js element
.oninput = function(e){
this.value = this.value.substr( 0 , 10 ) // this.value contain the string after the key press processing
}
While adding text in a textarea, I dont want to allow '*' after '&'.
I want to check on Asterisk keypress, whether previous symbol added is '&', if yes, user cannot add '*'.
Kindly help, how to proceed.
You might be better off having a general function that runs after every "keyup" event which cleans up the textarea by removing any asterisks (*) immediately after an ampersand (&). This way, even if the user pastes some content which contains the invalid sequence (&*) it will still be cleaned up. So something like this:
myTextArea.onkeyup = function() {
myTextArea.value = myTextArea.value.replace(/&\*/, '&');
return true;
};
var input = document.getElementById("input");
input.addEventListener("keydown", function(e) {
if(e.shiftKey && e.keyCode === 55 && input.value.substr(input.value.length - 1) === "*") {
e.preventDefault();
}
},false);
This will add an event to check the incoming character and the last in the current input. If the incoming is shift+55 (thats shift-7 or &) and the last character in the input is "*" preventDefault will bail out of the event and not input what was just typed. This example wont work in IE because its using addEventListener but the same approach will work with IE attachEvent or event jQuery events for full cross browser.
Because you can paste using contextual menu, Ctrl-V, Shift-Ins, etc...
myTextArea.onchange = function() {
myTextArea.value = myTextArea.value.replace(/&\*/, '&');
return true;
};
And of course, this does not replace a good server side validation
I have a form field for entering a user id. The user id is always 6 characters so the field is limited to a maxlength of 6 characters.
The field has an onkeyup() event to call a function that looks up the user id and fills in several other form fields if the user id is valid. Most people I know have used onblur() for something like this but I never liked how a user has to tab to or click on another field before the autofilling AJAX goes off.
The function right now will return w/o doing anything if the field length is < 6 characters or if the key that was pressed is a left or right cursor field.
There's one flaw left I haven't been able to think around. Since the field is limited to 6 characters, if 6 characters are already entered and another key is pressed, the value of the field will not change but the function will fire and validate the field (un-necessary validation/db-query).
Is there anyway to prevent the function from going off in this case? I'm thinking it's not possible but wanted to check. I had a thought if the field length was 6 I could check the last key pressed against the 6th character of the field, but if someone typed something like 'a' as the 6th character and then 'a' again, it wouldn't work. I guess that could eliminate all possibilities except for the one case though one case (not perfect but better).
(rails) <%= f.text_field :uid, :size => 10, :maxlength => 6, :class => 'validate_text', :onkeyup => uid_lookup (event)', :autocomplete => :off %>
<script type="text/javascript">
String.prototype.trim = function() {
return this.replace(/^\s+|\s+$/g,"");
}
</script>
<script type="text/javascript">
uid_lookup = function(e){
var unicode=e.keyCode? e.keyCode : e.charCode;
if (unicode == 37 || unicode == 39) { // ignore a left or right arrow press
return
}
var uid= $('uid').value;
uid = uid.trim();
$('uid).value = uid; //uid's have no spaces, go ahead and remove if typed
if (uid.length != 6) {
return
}
// db lookup & form autofill
}
</script>
The solution is not to use onkeyup. The correct event to use is HTML5's oninput, which is supported by almost every major browser out there. The one browser lacking support is—of course—Internet Explorer 8, but we can emulate the event using IE's proprietary onpropertychange event which will fire whenever an input element's value property changes.
I'm not familiar with rails, but the best way to apply the event is using JavaScript so that you can gracefully degrade if oninput isn't supported:
var el = document.getElementById("myEl");
// Check support
if ("onpropertychange" in el && !("oninput" in el)) {
el.onpropertychange = function () {
if (event.propertyName == "value")
uuid_lookup.call(this, event);
}
}
else
el.oninput = uuid_lookup;
The other great thing about this event is that it only fires when the value changes - much like onchange but more real-time. This means you can do away with your key detection for left and right arrows in the uuid_lookup function.
Can you not use another variable to store the previous value of the field the last time the validation function was fired? Then you can simply return if uid.value = lastValue.
Not perfect, but it would save some processing.