Backspace does not delete dashes - javascript

I'm attempting to create a field that adds dashes to a number so that it takes the form of a telephone number. It adds the dashes, but if the user tries to backspace their way back to the beginning it does not allow the user to delete the dash. Well, it deletes it but then the dash re-populates.
The JavaScript that allows only numbers with exceptions that I'm currently using:
function forceNumber(e) {
var keyCode = e.keyCode ? e.keyCode : e.which;
if((keyCode < 48 || keyCode > 58) && keyCode != 8 && keyCode != 188 && keyCode != 189) {
return false;
}
return true;
}
The js that creates the dashes:
function addDashes(n){
n = n.replace(/,/g, "");
var s=n.split('.')[1];
(s) ? s="."+s : s="";
n=n.split('.')[0];
if(n.length == 3 || n.length == 7 || n.length == 13){
s="-"
}
return n+s;
}
And the PHP/HTML call (I'm not sure if the right-align may be the cause):
<p id="phone_number">
<label for="phone_number"><?php _e('Phone Number','mydomain') ?><br />
<input type="text" name="phone_number" id="phone_number" class="input" size="25" style="text-align:right" onkeypress="return forceNumber(event);" onkeyup="this.value=addDashes(this.value);"/>
</p>

Simple change in your html I changed this line to add the event information:
<input ... onkeyup="this.value=addDashes(this.value, event);"/>
In the addDashes function I changed the signature to take the event and added an if to handle the backspace
function addDashes(n, ev){
// ...
}
However I noticed a more fundamental problem with your method. If somebody inserts a character it'll break the logic. So if the text is 123-45, and I paste the number 6 between 2 & 3, the result will be 1263-45.
Here's a different approach to addDashes that just checks the whole string each time.
function addDashes(n, ev){
n = n.replace(/[^\d]/g, "");
if (n.length > 3) {
n = insert(n, 3, '-');
if (n.length > 7) {
n = insert(n, 7, '-');
if (n.length > 13) {
n = insert(n, 13, '-');
}
}
}
return n;
}
function insert(s1, index, s2) {
return s1.substring(0, index) + s2 + s1.substring(index);
}
Another variation of addDashes that avoids the conditionals in favor of an unwieldy regex.
function addDashes(n, ev){
n = n.replace(/[^\d]/g, "")
.replace(/(\d{3}(?=\d))((\d{3}(?=\d))|(\d{0,3}$))((\d{4}(?=\d))|(\d{0,4}$))/,
function(m, $1, $2, $3, $4, $5, $6, $7) {
return (($1) ? $1 + '-' : m) +
(($3) ? $3 + '-' : $4) +
(($6) ? $6 + '-' : $7);
});
return n;
}
You can also adjust the second method to do different formatting without having to worry about string lengths. For example you can change the replace function to return in the format (ddd) ddd-dddd
return (($1) ? '(' + $1 + ') ' : m) +
(($3) ? $3 + '-' : $4) +
(($6) ? $6 + '-' : $7);

if(n.length == 3 || n.length == 7 || n.length == 13){
s="-"
}
When you backspace the dash, the length is 3 again, so the dash gets added. You are going to have to check if the last key the user pressed is backspace, like
var lastKeyIsBackspace;
if(!lastKeyIsBackspace && (n.length == 3 || n.length == 7 || n.length == 13)){
s="-";
}
Then, check if the key was backspace in your key handler:
function forceNumber(e) {
var keyCode = e.keyCode ? e.keyCode : e.which;
if((keyCode < 48 || keyCode > 58) && keyCode != 8 && keyCode != 188 && keyCode != 189) {
return false;
}
// check if the key was backspace (key code 8)
if (keyCode == 8) lastKeyIsBackspace = true;
else lasyKeyIsBackspace = false;
return true;
}

Here is how I would do it. One thing I'm doing is removing the javascript from the actual dom elements. So your input would look like this:
<input type="text" name="phone_number" id="phone_number" class="input" size="25" style="text-align:right" />
UPDATE: since I noticed you have jquery sourced and you prefer the dashes to show before the 4th and 7th digits are typed. the following should be good for you:
http://jsfiddle.net/3e9XE/8/
$(document).ready(function () {
$("#phone_number").on("keypress", function (e) {
var keyCode = e.keyCode ? e.keyCode : e.which;
if ((keyCode < 48 || keyCode > 58) && keyCode != 8 && keyCode != 188 && keyCode != 189) {
e.preventDefault();
}
})
.on("keyup", function (e) {
var str = this.value;
if (e.keyCode == 8) {
if ("-" == str.charAt(str.length - 1)) {
str = str.substring(0, str.length - 1);
}
} else {
str = str.replace(/\D/g, '')
.replace(/(\d{3})(.*)/, "$1-$2")
.replace(/(\d{3}-\d{3})(.*)/, "$1-$2");
}
this.value = str;
});
});

Related

JQuery to allow only alphabets, numeric and forward slash in TextBox

I have a text field in ASP.NET and i want to allow only alphanumeric and forward slash (/) keys in that. I tried the following code,
function jsCheckInput(e) {
var evt = (e) ? e : window.event;
var key = (evt.keyCode) ? evt.keyCode : evt.which;
if (key != null) {
key = parseInt(key, 10);
if (key < 47 || (key > 57 && key < 65) || (key > 90 && key < 97) || key > 122) {
if (!jsIsUserFriendlyChar(key)) {
return false;
}
}
else {
if (evt.shiftKey) {
return true;
}
}
}
return true;
}
function jsIsUserFriendlyChar(val) {
// Backspace, Tab, Enter, Insert, and Delete
if (val == 8 || val == 9 || val == 13 || val == 45 || val == 46) {
return true;
}
// Ctrl, Alt, CapsLock, Home, End, and Arrows
if ((val > 16 && val < 21) || (val > 34 && val < 41)) {
return true;
}
return false;
}
In the web forms page i added like below,
<asp:TextBox ID="text_value" CssClass="textbox" onkeydown="return jsCheckInput(event);" runat="server"></asp:TextBox>
Here i am able to enter alphabets and numbers but i am not able to enter the value /. I have enabled the shift key so i can give shift + ? to enter the forward slash. Also another problem is when i press shift + any numeric key the special characters there like ! # # $ % ^ & * ( ) ... are also coming in tet field. What am i doing wrong here?
if you want to use Regular Expression. Ignore if you don't
const regex = /^[a-z0-9\/]+$/gi;
const str = `asdasdas/asdfaASDASDA`; //test string
if(regex.test(str )){
console.log('Allowed'+str);
}
Tested here
You don't need shift key to type forward slash. Key code for forward slash(/) is 191. Just add this also in your if condition.
function jsCheckInput(e) {
var evt = (e) ? e : window.event;
var key = (evt.keyCode) ? evt.keyCode : evt.which;
if (key != null) {
key = parseInt(key, 10);
if (key < 47 || (key > 57 && key < 65) || (key > 90 && key < 97) || key > 122 || key != 191) {
if (!jsIsUserFriendlyChar(key)) {
return false;
}
}
}
return true;
}
SOLUTION
Finally found a solution as below,
function jsCheckInput(e, t) {
try {
if (window.event) {
var charCode = window.event.keyCode;
}
else if (e) {
var charCode = e.which;
}
else { return true; }
if ((charCode > 64 && charCode < 91) || (charCode > 96 && charCode < 123) || (charCode > 46 && charCode < 58))
return true;
else if (jsIsUserFriendlyChar(charCode))
return true;
else
return false;
}
catch (err) {
alert(err.Description);
}
}
This code works perfectly!!

Limit numbers before and after decimal point on input number

How to limit numbers for before and after the decimal point, something like 123.123 , so it can have max 3 numbers before . and max 3 numbers after .
<div class="form-group">
<input type="number" class="form-control" name="ta" id="ta" placeholder="ta" ng-model="ta.kol" ng-maxlength="15"/>
<p ng-show="taForm.kol.$error.maxlength" class="help-block">Max 15 symbols !</p>
</div>
You can add a onchange event on the input field and call a function that validates the current input value using regex and communicate same to the user.
Regex : ^[0-9]{0,3}.?[0-9]{0,3}$
JS Code to validate:
function validateNumberInput(inputNumber){
return number.search(/^[0-9]{0,3}.?[0-9]{0,3}$/) == 0 ? true : false;
}
Also you can write a directive in angular that can handle the same.
This can be solved with a simple piece of javascript if you just add an Event Listener to the input and then split the input on the decimal point you can then check the length of both parts and act accordingly.
https://jsfiddle.net/pk07net6/
function checkNumbers()
{
console.log(this.value);
var numbers = this.value.split('.');
var preDecimal = numbers[0];
var postDecimal = numbers[1];
if (preDecimal.length>3 || postDecimal.length>3)
{
alert("Max 3 numbers before and after the decimal point.")
this.select();
}
}
//ADD LISTENER TO INPUT
var input = document.getElementById("numberInput");
console.log(input);
input.addEventListener("change", checkNumbers)
You can use ng-pattern with a regex:
<input ng-pattern="/^[0-9]{1,3}(\.\d{0,3})?/" />
docs: https://docs.angularjs.org/api/ng/directive/ngPattern
For the fraction its pretty easy as you can use Angular number filter. As for the number before the digit you should create a filter like this :
app.filter('beforeDigit', function ($filter) {
return function (input) {
if (input>1000)
return (input % 1000)
elseif(input<1000)
return input;
};
});
So in the end you will end up with something like this :
{{val | filter:{number:3}, filter:beforeDigit }}
After hours of work, I create java-script function which work on keypress event. Number can be 8 characters before decimal separator and 2 character after decimal separator.
https://codepen.io/dumbelovic/pen/bvdXXq
function BeforeAfter(e, obj) {
sepDec = "."
var keycode;
var fieldval = obj.value;
if (window.event) keycode = window.event.keyCode;
else if (e) { keycode = e.which; }
else { return true; }
// denided first charatcter to be zero
if (fieldval == "" && keycode == 48)
return false;
// denided first character to be decimal point
if (fieldval == "" && (keycode == 44 || keycode == 46))
return false;
// enter first decimal point,
// but every next try to eneter decimal point return false
if (fieldval != "" && ((keycode == 44 || keycode == 46))) {
if (fieldval.indexOf(sepDec) < 0) {
var newValue = fieldval + sepDec;
$(obj).val(newValue);
}
return false;
}
var splitfield = fieldval.split(sepDec);
var beforeDecimalPoint;
var afterDecimalPoint;
if (splitfield.length == 1) {
beforeDecimalPoint = splitfield[0];
afterDecimalPoint = "";
}
else if (splitfield.length == 2) {
beforeDecimalPoint = splitfield[0];
afterDecimalPoint = splitfield[1];
}
if (beforeDecimalPoint.length == 8 && keycode != 8 && keycode != 0) {
if (obj.selectionStart >= 0 && obj.selectionStart <= 8)
return false;
}
if (afterDecimalPoint.length == 2 && keycode != 8 && keycode != 0) {
if (obj.selectionStart >= beforeDecimalPoint.length + 1 && obj.selectionStart <= beforeDecimalPoint.length + 1 + 2)
return false;
}
return true;
}

jQuery replace comma with dot doesn't work

I have tried to append the code from another post which works perfectly on fiddle on this link: http://jsfiddle.net/WfpEu/51/
The code replaces comma "," as soon as the user types it and turns it to dot "."
$.fn.ForceNumericOnly = function() {
return this.each(function() {
$(this).keydown(function(e) {
if(e.keyCode==188 || e.keyCode==110 || e.keyCode==108){
e.preventDefault();
$(this).val($(this).val() + '.');
}
var key = e.charCode || e.keyCode || 0;
return (key == 8 || key == 9 || key == 46 || key == 110 || key == 188 || key == 190 || (key >= 35 && key <= 40) || (key >= 48 && key <= 57) || (key >= 96 && key <= 105));
});
});
};
$(".item").ForceNumericOnly();
I have tried to append it to my code here http://jsfiddle.net/p2Hbm/104/ and it doesn't work as it should and i don't know what is wrong. I can't write letters in input fields which is good but also i can't write comma "," it doesn't show up at all.
You need to add the itemclass to your input fields.
Working fiddle: http://jsfiddle.net/p2Hbm/106/

Need to replace "comma" with 'dot'

Please help me to adjust an existing script to replace COMMA with DOT.
I use a script which limit the inserting character into Text fields. Only 1,2,3,4,5,6,7,8,9,0 and "." and "," are accepted to be inserted. I would like to have two buttons of inserting DOT - key==188 (comma) and key== 190 (dot).
jQuery.fn.ForceNumericOnly =
function()
{
return this.each(function()
{
$(this).keydown(function(e)
{
var key = e.charCode || e.keyCode || 0;
return (
key == 8 ||
key == 9 ||
key == 46 ||
key == 110 ||
key == 188 ||
key == 190 ||
(key >= 35 && key <= 40) ||
(key >= 48 && key <= 57) ||
(key >= 96 && key <= 105));
});
});
};
$("#iMONEY").ForceNumericOnly();
It can be tested HERE
Just use
if(e.keyCode == 188){
e.preventDefault();
$(this).val($(this).val() + '.');
}
Here you go. :)
For future references Mini-Tutorial.
The value of the textbox is updated after keypress event is fired. It's not a place to replace comma with dot. Use keyup event instead:
jQuery.fn.ForceNumericOnly =
function()
{
this.keyup(function(e)
{
// console.log("Change");
$(this).val($(this).val().replace(/,/g,"."));
});
};
$("#iMONEY").ForceNumericOnly();
DEMO
var key = e.charCode || e.keyCode || 0;
// 110 is numpad comma code
if (key === 188 && key === 110) {
e.preventDefault();
$(this).val($(this).val() + '.');
}
You need to use the Replace method
var someVariable = "1,2,3,4,5,6,7,8,9,0";
$mylabel.text( someVariable.replace(',', '.') );
EDIT:
If you are checking from TextBox then do it like this:
if(Key == 188){
var someVariable = $("#TEXTBOXID").val();
somVariable = someVariable.replace(',', '.');
}

allowing input only for float number

I have pain-time when making input that only allows float number with jquery library. my code can't prevent chacacter "." when it's becoming first input, can anyone guide me to solve this problem?
$('.filterme').keypress(function(eve) {
if ( ( eve.which != 46 || $(this).val().indexOf('.') != -1 )
&& ( eve.which < 48 || eve.which > 57 )
|| ( $(this).val().indexOf('.') == 0)
)
{
eve.preventDefault();
}
});​
I use this - works for keyboard input or copy and paste
$('input.float').on('input', function() {
this.value = this.value.replace(/[^0-9.]/g, '').replace(/(\..*?)\..*/g, '$1');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<input type="text" class="float" />
Explanation:
First regex replaces anything that's not a number or a decimal.
Second regex removes any instance of a second decimal.
I filter the first position input with the jQuery Caret plugin. Otherwise, once the dot is typed, it's already late to check where it was placed. I tried checking for the dot, then deleting the dot, but it does not look nice.
jQuery caret plugin:
http://examplet.buss.hk/js/jquery.caret.min.js
What I did:
http://jsfiddle.net/FCWrE/422/
Try it :)
$('.filterme').keypress(function(eve) {
if ((eve.which != 46 || $(this).val().indexOf('.') != -1) && (eve.which < 48 || eve.which > 57) || (eve.which == 46 && $(this).caret().start == 0)) {
eve.preventDefault();
}
// this part is when left part of number is deleted and leaves a . in the leftmost position. For example, 33.25, then 33 is deleted
$('.filterme').keyup(function(eve) {
if ($(this).val().indexOf('.') == 0) {
$(this).val($(this).val().substring(1));
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/caret/1.0.0/jquery.caret.min.js"></script>
<input type="text" class="filterme">
Regular expression would be my recommendation as well. If the value is being passed as a number and not a string you can use .toString to change it to a string and validate it with regular expression. For example:
var str = value.toString();
if(!str.match(/^-?[0-9]*[.][0-9]+$/)) {
alert("Value must be a float number");
return;
}
return value;
The above regex will match if the value passed is a floating point number. It accepts both negative and positive numbers. If you only want to accept positive numbers simply remove the '-?' from the expression. It will also fail if the value is simply zero '0' without any decimal point. If you want to accept zero simply add it as a condition to the 'if' statement.
You can use the above validation and an onchange event to prevent the user from entering a non-flot number.
Why not using Regular Expression
^[0-9]*[.][0-9]+$
Read code and test here..
You can use the following method, called on onkeypress event. Below is the HTML snippet followed by the JS method:
input type="text" onkeypress="return isNumberKey(event)" id="floor"
function isNumberKey(evt){
var charCode = (evt.which) ? evt.which : event.keyCode
if (charCode == 46){
var inputValue = $("#floor").val();
var count = (inputValue.match(/'.'/g) || []).length;
if(count<1){
if (inputValue.indexOf('.') < 1){
return true;
}
return false;
}else{
return false;
}
}
if (charCode != 46 && charCode > 31 && (charCode < 48 || charCode > 57)){
return false;
}
return true;
}
Note: The above code also ensures that you enter only single decimal in the input.
Here is my solution, works with negative numbers too (fiddle)
$("input").keypress(function (event) {
var inputCode = event.which;
var currentValue = $(this).val();
if (inputCode > 0 && (inputCode < 48 || inputCode > 57)) {
if (inputCode == 46) {
if (getCursorPosition(this) == 0 && currentValue.charAt(0) == '-') return false;
if (currentValue.match(/[.]/)) return false;
}
else if (inputCode == 45) {
if (currentValue.charAt(0) == '-') return false;
if (getCursorPosition(this) != 0) return false;
}
else if (inputCode == 8) return true;
else return false;
}
else if (inputCode > 0 && (inputCode >= 48 && inputCode <= 57)) {
if (currentValue.charAt(0) == '-' && getCursorPosition(this) == 0) return false;
}
});
function getCursorPosition(element) {
if (element.selectionStart) return element.selectionStart;
else if (document.selection)
{
element.focus();
var r = document.selection.createRange();
if (r == null) return 0;
var re = element.createTextRange(),
rc = re.duplicate();
re.moveToBookmark(r.getBookmark());
rc.setEndPoint('EndToStart', re);
return rc.text.length;
}
return 0;
}
This works for me:
var str = document.getElementById('product_'+id_product).value;
if( !str.match(/^[0-9]*([.,][0-9]+)?$/) ) {
console.log("Value must be a number or float number");
}else{
console.log("The number is valid");
}
I hope this can help someone.
Regards!

Categories

Resources