Extend function to prevent paste inside an input field - javascript

I'm currently trying to prevent typing everything instead of numbers and points inside a an input field. The problem is that pasting letter or strange things still works. So is there a way to prevent it in my function?
I could do a HTML part like onpaste="return false;" but maybe there is a better solution that uses my available function. Thanks for your help!
jQuery( document ).ready( function ( $ ) {
$( document ).on( "keypress keyup paste", "#test", function ( event ) {
let input = $( this ).val();
console.log(input);
console.log(event.which);
if ( ( event.which !== 46 || $( this ).val().indexOf( '.' ) !== -1 ) && ( event.which < 48 || event.which > 57 ) ) {
event.preventDefault();
} else if ( ( input.indexOf( '.' ) !== -1 ) && ( input.substring( input.indexOf( '.' ) ).length > 2 ) ) {
event.preventDefault();
}
} );
} );
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="test"/>
Edit:
I also found out that the sign ^ still works too but has no event? How is this possible?
The idea is to only allow numbers with points and two decimals like 22222.22 for example.
Edit 2:
Input type number is not working because it allows more than just numbers and points.
<input type="number"/>

Somehow below code handles ctrlX, ctrlV, ^, and allows decimal input
const input = document.querySelector('input')
let old = input.value
input.addEventListener('input', function() {
if (!this.checkValidity()) {
this.value = old
} else {
old = this.value
}
})
<input type="text" pattern="\d+(\.[\d]{0,2})?"/>
For dynamically added input (by using event delegation) we could store the old attribute on the input itself
jQuery( document ).ready( function ( $ ) {
$( document ).on( "input", "input.decimals", function ( event ) {
if (!this.checkValidity()) {
this.value = this.dataset.old || ''
} else {
this.dataset.old = this.value
}
return true
})
const pattern = '\\d+(\\.[\\d]{0,2})?'
document.querySelector('div').innerHTML += `<input class="decimals" type="text" pattern="${pattern}"/>`.repeat(2)
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div></div>

You can try to explicitly disable cut, copy, or paste functionality on targeted element (e.g: #txtInput element) using the snippet below:
$(document).ready(function(){
$('#txtInput').on("cut copy paste",function(e) {
e.preventDefault();
});
});
More on how to do this here: How to prevent pasting into input fields.

Have you tried the simple solution which is to use input of type number?
e.g. <input type="number" />
There is a caveat, the letter 'e' can be typed, i.e. Euler's Number

Related

Input field value when selected, cannot be overwritten

I validate an input field by those patterns:
only positive numbers
only one .
only numeric values
only two decimals after .
only numbers between 0 and 100
limit input to 5 characters (0 ... 1.1 ... 10.2 ... 33.23 ... 99.99 or 100)
These validations work with my code fine. Even there is a better way to code this validation. But anyways - my issue, which I can't solve right now is - if I enter a value for example 99.99 or 100 or 23.23 and I want to change the value again by selecting / mark the entire value with my mouse for example - it will not change! If I write 2.33 and I select/mark the entire value with my mouse it will change. So it seems I'm facing a 'false' state which does not allow me to enter another digit and right now I could not find a kind of an event which detects that I select something in my input field.
I have prepared an JSFIDDLE code - where do I have my confusion?
ps: I am also aware that maybe my keypress event is overwriting the false/true states, I'm trying to solve this afterwards.
Thank you very much!
Best Regards
$('#inpNumber').on('input', function() {
var inpVal = $(this).val();
if ( inpVal > 100 || inpVal < 0 || !inpVal) {
$( "#inpNumber" ).removeClass( "is-valid" );
$( "#inpNumber" ).addClass( "is-invalid" );
} else {
$( "#inpNumber" ).removeClass( "is-invalid" );
$( "#inpNumber" ).addClass( "is-valid" );
}
});
$('#inpNumber').keypress(function (event) {
var input = $(this).val();
if ((input.indexOf('.') != -1) && (input.substring(input.indexOf('.')).length > 2)) {
event.preventDefault();
return false;
}
return isNumberRegChecked(event, this);
return isNumber(event, this);
});
function isNumberRegChecked( evt, element ) {
var inpVal = $(element).val();
// ^(\d\d?(\.\d\d?)?|100(\.00?)?)$ also possible
var checkShare = /^(\d{0,2}(\.\d{0,2})?)$/.test(inpVal);
if (checkShare == false)
return false;
return true;
}
// THE SCRIPT THAT CHECKS IF THE KEY PRESSED IS A NUMERIC OR DECIMAL VALUE.
function isNumber( evt, element ) {
var charCode = (evt.which) ? evt.which : event.keyCode;
if ((charCode != 46 || $(element).val().indexOf('.') != -1) && // “.” CHECK DOT, AND ONLY ONE.
(charCode < 48 || charCode > 57))
return false;
return true;
}

change spaces entered in input field to underscore in real time

I have an input field that should switch all spaces entered to a '_' in real time. Meaning when the user hits the spacebar in that input field a underscore is being displayed instead of a space. I am quite new to javascript/jquery so please don't judge my setTimeout-n00bidity to hard:
$( "#inputId" ).keydown(function (key){
var code = key.keyCode || key.which;
if( code == 32 ) { //Space key code
$( this ).val(
function( index, value ){
return value.substr( 0, value.length - 1 );
})
setTimeout(
function(){
$(this).val($(this).val() + "_");
}, 10
)
}
})
You may listen to the input event and then replace the spaces with underscores in the listener. This way, you don't need to have a timeout.
$("#inputId").on('input', function(key) {
var value = $(this).val();
$(this).val(value.replace(/ /g, '_'));
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="inputId">
No jQuery, simple solution:
var input = document.getElementById("inputId");
input.oninput = function (e) {
e.target.value = e.target.value.replace(' ', '_');
}
<input type="text" id="inputId" />
Use the keyup event rather than keydown, and simply replace all spaces with _. The keyup event runs after the value has been modified based on what the user typed, so you don't need to check the charCode.
$("#inputId").keyup(function() {
$(this).val(function(i, oldval) {
return oldval.replace(/ /g, '_');
});
});
You can use Change value of key board input
ex:
<div>
<label>Test:</label>
<input type="text" id="test">
</div>
$("#test").on("keypress", function (e) {
if (32 == e.keyCode) {
e.preventDefault();
var newString = $("#test").val() + "_";
$("#test").val(newString);
}
});
Related: jQuery: Change keyboard value when input
$( "#inputId" ).keyup(function (key){
var code = key.keyCode || key.which;
if( code == 32 ) { //Space key code
$(this).val($(this).val().replace(/ /g,"_"));
}
});

Check if active element has particular class via javascript

I'm writing a single-field form and want the Enter key to advance the form to the next input field. Since there's another form on the page, I only want the Enter key to advance the form when one of the inputs in that form is the activeElement.
I've achieved this with what seems like an extremely verbose if() statement here:
document.addEventListener( 'keydown', function( ev ) {
var keyCode = ev.keyCode || ev.which;
var ids = [ 'this', 'that', 'there', 'thing', 'other' ];
if ( document.getElementById( ids[0] ) === document.activeElement || document.getElementById( ids[1] ) === document.activeElement || document.getElementById( ids[2] ) === document.activeElement || document.getElementById( ids[3] ) === document.activeElement || document.getElementById( ids[4] ) === document.activeElement) {
if( keyCode === 13 ) {
ev.preventDefault();
self._nextQuestion();
}
}
} );
Each of the inputs are the same class: .questions. I've tried something like:
document.addEventListener( 'keydown', function( ev ) {
var keyCode = ev.keyCode || ev.which;
var ids = [ 'this', 'that', 'there', 'thing', 'other' ];
if ( document.querySelector('.questions') === document.activeElement) {
if( keyCode === 13 ) {
ev.preventDefault();
self._nextQuestion();
}
}
} );
But of course, this only accesses the first instance of .questions on the page. I don't want to iterate over nodes, as it doesn't seem much better than what I have already.
I'm a novice, and I'm looking for more concise logic.
Just check if the activeElement has the questions class.
var pattern = /(?:^|\s)questions(?:\s|$)/
if (document.activeElement.className.match(pattern)) {
...
}
squint provided an improved regex that will account for more funky situations in the classname.
Try this:
if ((" "+document.activeElement.className+" ").indexOf(" questions ") > -1) {
...
}
First of all, you can utilise classList api to check element for given className presence, e.g. document.activeElement && document.activeElement.classList.contains('question').
All the proposed approaches are really helpful and should fix the problem. On the other hand, you might want to keep you application's state in one place so you can manage it easily. By doing so, you make your application more predictable and easier to debug.
Here's an approach you might want to take:
HTML Code:
<input class="question" value="1"/>
<input class="question" value="2"/>
<input class="question" value="3"/>
<input class="question" value="4"/>
<input class="question" value="5"/>
JavaScript Code:
var component = {
activeQuestion: 0,
questionSelector: '.question',
get activeQuestionElement () {
return component.allQuestionElements[component.activeQuestion];
},
get allQuestionElements () {
return document.querySelectorAll(component.questionSelector);
},
next: function () {
var activeElement = document.activeElement;
if (activeElement && activeElement === component.activeQuestionElement && component.allQuestionElements[component.activeQuestion+1]) {
component.activeQuestion++;
component.highlightQuestion();
}
},
highlightQuestion: function () {
component.activeQuestionElement.focus();
},
install: function () {
document.addEventListener('keyup', function (event) {
if (event.which === 13) {
component.next.call(component);
}
});
document.addEventListener('click', function (event) {
var className = component.questionSelector.slice(1);
if (event.target.classList.contains(className)) {
component.activeQuestion = [].slice.call(document.querySelectorAll(component.questionSelector)).indexOf(event.target);
component.highlightQuestion();
}
})
}
};
component.install();
As you can see above, component is a single object instance that holds useful information like activeQuestion index, question selector, some computed properties that return DOM elements. The install method binds event listeners which manage the state when events occur.
Here's a demo:
http://jsfiddle.net/maciejsmolinski/xzyvye8z/embedded/result/
When you click enter when any of the fields is focused, it is going to move focus to the next one. In addition to that, clicking on any of the fields changes active question as well. You can easily alter the behaviour by modifying the code I posted above. It is just a basic skeleton you can use to build your own functionality on top of.
This is a very basic component. You can build anything on top of it. You can introduce ES6 syntax (classes, arrow functions, const instead of var) but I intentionally left that part untouched to make it easier to understand.
Hope it helps!
You guys pointed me in the right direction with document.activeElement.className, so I upvoted all who mentioned it, but the most concise solution that works here seems to be this:
document.addEventListener( 'keydown', function( ev ) {
var keyCode = ev.keyCode || ev.which;
// enter
if ( document.activeElement.className === 'questions') {
if( keyCode === 13 ) {
ev.preventDefault();
self._nextQuestion();
}
}
} );
I'll give you guys some time to critique this before I mark it as the answer...

Disable zero as first letter in <input>

Below code disables 0 as the first character in #foo.
However, you can bypass this by typing 123, then drag to select 123 and putting 0. (or ctrl+a on input)
Is there a way to block this scenario?
$('input#foo').keypress(function(e){
if (this.value.length == 0 && e.which == 48 ){
return false;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="foo" />
I would handle the input, propertychange, and paste events. Then use regex to match for anything that begins with 0 and replace the current value with the value minus the leading 0.
http://jsfiddle.net/SeanWessell/5qxwpv6h/
$('input ').on('input propertychange paste', function (e) {
var val = $(this).val()
var reg = /^0/gi;
if (val.match(reg)) {
$(this).val(val.replace(reg, ''));
}
});
Bug fix reported by Kevin/Updated per recommendations of canon:
http://jsfiddle.net/SeanWessell/5qxwpv6h/2/
$('input').on('input propertychange paste', function (e) {
var reg = /^0+/gi;
if (this.value.match(reg)) {
this.value = this.value.replace(reg, '');
}
});
I think you're looking for the keydown jQuery event as opposed to the keypress event. Here's some move info on the difference between the two. Try regex to get rid of leading zeroes:
$('input#foo').keydown(function(e){
this.value = this.value.replace(/^0+/, '');
});
Here's the fixed version :
<input id="foo" />
$('input#foo').keyup(function(e){
if(this.value.substring(0,1) == "0")
{
this.value = this.value.replace(/^0+/g, '');
}
});
jsfiddle : http://jsfiddle.net/ewmb1yq9/4/
This could work:
$('input#foo').keyup(function(e) {
if((this.value+'').match(/^0/)) {
this.value = (this.value+'').replace(/^0+/g, '');
}
});
The only thing that could bother you with this solution is that zero is displayed for a second and then deleted, since we are using keyup event.
A quick demo
Accept only numeric values not prefixed by zero. Supports Ctrl + A:
var escapeKeys = [8, 46];
$('input#foo').keyup(function (e) {
if ($.inArray(e.keyCode, escapeKeys) != 0) {
if ((this.value + String.fromCharCode(e.keyCode)).match(/^[1-9][0-9]*$|^$/) != null) {
this.lastValidValue = this.value + String.fromCharCode(e.keyCode);
} else if (this.lastValidValue) {
this.value = this.lastValidValue;
} else {
this.value = "";
}
} else {
this.lastValidValue = this.value;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="foo" />
If you want to catch the changes to the input's value (including the changes made by dragging part of the text for example), you can watch the input event.
$('input#foo').on("input", function(){
alert($(this).val());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="foo" />
You could add a "submit" event to validate whether it's entered or not, regardless of how it could have gotten there:
$( "form" ).submit(function( event ) {
if ( $( "input:first" ).val() != 0 ) {
$( "span" ).text( "Validated..." ).show();
return;
}
$( "span" ).text( "Not valid!" ).show().fadeOut( 1000 );
event.preventDefault();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<p>Type 'Anything but 0' to validate.</p>
<form action="javascript:alert( 'success!' );">
<div>
<input type="text">
<input type="submit">
</div>
</form>
<span></span>
jQuery's working is example is last on page here (https://api.jquery.com/submit/)
NOTE: The most important part will be to add the "event.preventDefault()" action, because that will keep the form from accidentally submitting.

text box decimal format fixing

I have a simple text box and I am entering number value to this.And i want to format the number value to two decimal places.Like If i enter the 10 in the text box and after pressing entering or leaving textbox it should be converted into 10.00.Please tell me if there exist any possibility to do this using javascript or vb.net or asp.net property of textbox.I already tried in JavaScript on enter key or tab key press but it convert it into 10.00 each time when i press the enter or tab.here is code
//Make Formatting with .00
document.onkeydown = function disableKeys() {
if( typeof event != 'undefined' ) {
if( (event.keyCode == 9) ||
(event.keyCode == 13) ) {
var a;
var b;
a=parseFloat(document.getElementById('txtpkrusd').value,10);
b=parseFloat(document.getElementById('txtRatelb').value,10);
document.getElementById('txtpkrusd').value=formatNumber(a);
document.getElementById('txtRatelb').value=formatNumber(b);
}
};
};
var num = 10;
var result = num.toFixed(2); //will give 10.00
Examples
hiya hope this helps: (apart from my comment above i.e. to round use .toFixed(num))
demo (enter the number and press enter) : http://jsfiddle.net/6wG26/5/ OR Enter and Tab keys both here http://jsfiddle.net/Mtw7c/7/
Please; let me if this is not what you want I will delete my post; but this will help you.
Since you dint had much code up I have made forked sample here:
**HTML:**
<input type="text" name="one" class="currency">
**JQuery code:**
(function($) {
$.fn.currencyFormat = function() {
this.each( function( i ) {
$(this).change( function( e ){
if( isNaN( parseFloat( this.value ) ) ) return;
this.value = parseFloat(this.value).toFixed(2);
});
});
return this; //for chaining
}
})( jQuery );
$( function() {
$('.currency').currencyFormat();
});​
OR ENter key & Tab key here: http://jsfiddle.net/Mtw7c/7/
$('.currency').live('keydown', function(e) {
var key = e.keyCode || e.which;
if (key== 9 || key == 13) {
e.preventDefault();
if( isNaN( parseFloat( this.value ) ) ) return;
this.value = parseFloat(this.value).toFixed(2);
// call custom function here
}
});
​
hope this helps and it will be good if you read the following link - sample taken from here but to make it sample for you, In jQuery, what's the best way of formatting a number to 2 decimal places?
You can always put validation for the number only text box & other amendments, Hope this helps mate, cheers!!

Categories

Resources