should not allow more than one space in between words - javascript

function stripspaces(input)
{
input.value = input.value.replace(/\s+/gi," ");
}
I written this function. It is working but when I point the mouse pointer or moving with left arrow in between word and giving space it is jumping to the last. Can anyone give me the solution?

You can prevent the input by calling e.preventingDefault we can simply test if the space key has been pressed and if there's a space either side of the cursor then prevent entry.
document.addEventListener('DOMContentLoaded', function() {
var input = document.getElementById('myInput');
input.addEventListener('keydown', function(e){
var input = e.target;
var val = input.value;
var end = input.selectionEnd;
if(e.keyCode == 32 && (val[end - 1] == " " || val[end] == " ")) {
e.preventDefault();
return false;
}
});
});
<input type="text" id="myInput">
This still has the issue that it won't prevent pastes into the box with double spaces. So it may be worth still replacing multiple spaces on focus loss to be sure that the input never contains multiple contiguous spaces.

I just came across the same use case. If you also want to handle copy/paste or any other way the input's value could change, use the input event:
document.addEventListener('DOMContentLoaded', function() {
// get a reference to the input element
const input = document.querySelector('#myInput');
// guard clause to check if `#myInput' actually exists in the current DOM
if(!input) return
// Run this every time the input's value changes
input.addEventListener('input', e => {
// get the value
const value = e.target.value
// check if the value isn't exactly ' ' and ends with a space
const hasTrailingSpace = value !== ' ' && value.charAt(value.length-1) === ' '
// extract words, remove empty words (handles double spaces)
const words = value.split(' ').filter(el => el !== '')
// create the sanitized value
let sanitizedValue = words.join(' ')
// add a trailing space if there was one
if( hasTrailingSpace ) sanitizedValue += ' '
// apply the sanitized value to the input's value
e.target.value = sanitizedValue
})
})
<p>Try inserting double spaces now! Also try copy/paste from somewhere else</p>
<input type="text" id="myInput">

Related

How do I format an account name and/or sort code using Javascript?

I am posting this question with my answer so far but would like to invite other solutions as I am not 100% sure about mine.
It will:
Automatically place the dashes in the right place so the user only has to enter the digits.
Can be any size. You can set a maxlength attribute on your input and it will continue to apply dashes intil it runs out of space. It will default to 8 characters max
Allowsuser to delete digits without the need to delete the dashes too.
Why am I posting a this?
I could not find the answer myself on StackOverflow and when you search this question on Google, it keeps returning a PHP answer for StackOverflow instead! There are even answers in there for Javascript.
Hopefully this question can produce other solutions too!
How does it work?
This is designed to work with a real-time input.
It works out the maximum length
It captures the event and works out if the delete key was pressed
The 'regex' part is saying to replace ever 2nd character with itself
plus a dash.
The next line first replaces anything that's not a number, then uses the regex to inject dashes and finally the string is sliced to remove any trailing slash
You would apply this function to your onkeyup or onpaste events, passing 'this' in.
function checkSortCode(el,ev){
var len = el.maxLength || 8;
ev = ev || window.event;
if(ev.keyCode == 8 && el.value.slice(-1) == "-"){
el.value = el.value.slice(0,-1);
} else {
var regex = new RegExp("(\\S{" + (2 - 1) + "}\\S)", "g");
el.value = el.value.replace(/[^0-9]/g,"").replace(regex,("$1"+"-")).slice(0,len);
}
}
.sortcode::placeholder{color:#eeeeee;}
body{font-family:arial,sans-serif;font-size:1.4em;}
input{font-size:1.4em;}
<label>Sort Code</label><br>
<input type="text" name="sortcode" onkeyup="checkSortCode(this,event)" onpaste="checkSortCode(this,event)" class="sortcode" size="8" maxlength="8" placeholder="00-00-00" />
Ideally, I wanted it to show the 00-00-00 format all the time and then the user would fill it in but have padded zeros where they hadn't. That's not easy as the cursor wants to go to the end of the input.
What you're looking for is called Input Masking. You can implement it yourself but I would recommend using a library to separate the actual input value and the mask.
Here an implementation using native js, you'll notice it's a bit janky.
<html>
<body>
<input id="input">
<script>
const pattern = '00-00-00-00'
const patternRegex = /^[0-9]{2}\-[0-9]{2}\-[0-9]{2}\-[0-9]{2}$/
const separator = '-'
/* returns current value completed by the pattern (filled with 0) */
const fill = value => {
return `${value}${pattern.substring(value.length)}`
}
/* format the input on keyup */
const format = event => {
/* only format the input at cursor position (to ignore filled pattern) */
const position = event.target.selectionStart
const value = event.target.value.substring(0, position)
/* rollback invalid inputs */
if (!patternRegex.test(fill(value))) {
event.target.value = event.target.value.substring(0, position - 1)
return
}
/* change target valuer to include pattern and restore carret position */
event.target.value = fill(value)
const newPosition = event.target.value[position] === separator ? position + 1 : position
event.target.setSelectionRange(newPosition, newPosition)
}
const input = document.getElementById('input')
input.addEventListener('keyup', format)
</script>
</body>
</html>
You can check some other implementation here : https://css-tricks.com/input-masking/
The reason why it's janky is because we format the input after a change occured. When using a library (or React), you can control the input value before it's rendered.

Fromat a TextField as soon as it's written to

I am trying to update a TextField as soon as the user types something in. I like to avoid people writing in different text formats but have the proper capitlisation eg. instead of jOHN or JOHN or john, the Text needs to be updated (firstCapitalLetter) John in this case.
I tried to copy the method as described here: Format input text to uppercase but I am failing to adapt it to my case. The txtFirstName is the ID of the TextField.
NWF$(document).ready(function () {
NWF$("#" + txtFirstName).change(function () {
// get the text value from the FirstNname textfield
var textContent = NWF$('#' + txtFirstName).text();
// check to see if the value is not null
if (textContent.length > 0) {
// format the first letter to UpperCase and the rest to LowerCase
textContent = NWF$("#" + txtFirstName).toUpperCase() + txtFirstName.substr(1).toLowerCase();
NWF.value = textContent;
}
});
});
I managed to get it working, after so many trials.
Now, the txtFirstName changes the format as wanted :)
NWF$(document).ready(function () {
NWF$("#" + txtFirstName).change(function () {
// get the text value from the FirstNname textfield
var textContent = this.value;
// check to see if the value is not null
if (textContent.length > 0) {
// format the first letter to UpperCase and the rest to LowerCase
textContent = textContent[0].toUpperCase() + textContent.substr(1).toLowerCase();
this.value = textContent;
}
});
});
Here is another option if you have to update two seperate txtFields.
Maybe one of you can propose a better approach on this.
Basically, I wanted to say, when the the txtFields are updated then they need to be formatted to the proper capitalisation to avoid things like: john / JOHN / jOHn
NWF$(document).ready(function () {
NWF$("#" + txtFirstName).change(function () {
// get the text value from the FirstNname textfield
var textContent = this.value; //alert(textContent)
// check to see if the value is not null
if (textContent.length > 0) {
// format the first letter to UpperCase and the rest to LowerCase
textContent = textContent[0].toUpperCase() + textContent.substr(1).toLowerCase();
this.value = textContent;
}
});
NWF$("#" + txtLastName).change(function () {
// get the text value from the FirstNname textfield
var textContent = this.value; //alert(textContent)
// check to see if the value is not null
if (textContent.length > 0) {
// format the first letter to UpperCase and the rest to LowerCase
textContent = textContent[0].toUpperCase() + textContent.substr(1).toLowerCase();
this.value = textContent;
}
});
});

Formatting input type="text" in JS

I have a text field with type='text' and I am trying to format the text with commas. Example: 500000000 would become 500,000,000.
I have the following code:
function addComma(values) {
values.value = values.value.replace(",", "").replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
if (document.getElementById("values"))
payment = parseInt(document.getElementById("values").value);
<label1>Rent</label1> <input id="values" type="text" onkeyup="addComma(this);">
However, it's printing 5,000,0,0,0,000 and the formatting is off for some reason. I also tried .toLocaleString(), but that doesn't seem to work either. What am I doing wrong here?
I was referred to a few other posts on Stack Overflow, but nothing seems to work out.
function addComma(values) {
const v = values.value && new Number(values.value.replace(/,/g,''));
values.value = v.toLocaleString();
}
if (document.getElementById("values"))
payment = parseInt(document.getElementById("values").value);
<label1>Rent</label1> <input id="values" type="text" onkeyup="addComma(this);">
You can do this by converting the number to a string, then manually iterating over each character and find places where a comma is needed.
function formatNumber(number) {
var str = number.toString();
var offset = str.length % 3;
var newStr = '';
for (var i = 0; i < str.length; i++) {
if (i > 0 && i % 3 === offset) {
newStr += ',';
}
newStr += str[i];
}
console.log(str, '=>', newStr);
}
formatNumber(5);
formatNumber(50);
formatNumber(500);
formatNumber(5000);
formatNumber(50000);
formatNumber(500000);
formatNumber(5000000);
I'd recommend using a change event rather than a keyup event as change will only update the value when the input is no longer the focus. If you use keyup the code will try and reinterpret the new string you add back to the input as a number and throw an error.
Here's the code using toLocaleString (just press tab after adding the number as if to move to the next input box):
const values = document.querySelector('#values');
values.addEventListener('change', handleChange, false);
function handleChange(e) {
const value = Number(e.target.value);
const formatted = value.toLocaleString();
values.value = formatted;
}
<input id="values" type="text">
The other answers posted before this one using the input field are ok to show how it works, but they are bugged as soon as you enter a new number when it has formatted to a string using toLocaleString(). For that reason I added the toNumber() function to be complete. In the example below I preform the following steps:
When user fills in a number in the input field and leaves the input field: Call toString(e) and make from the entered number a formatted string.
If the user again selects the input field, call toNumber(e) and format it back to a number.
This makes sure you won't get NaN when reselecting or will become completely unusable.
The NaN property represents "Not-a-Number" value. This property indicates that a value is not a legal number.
It is still possible to add text in it, this will result in NaN as text cannot be formatted to a number. This could be filtered out in the toString(e) when necessary. I did this in the example below by adding if (formatted !== 'NaN') {} Only when it's not NaN it will set the value to the new formatted number. Else it won't do anything. Please note: a number with dots is a string in this case so wont work either.
const values = document.querySelector('#values');
values.addEventListener('click', toNumber, false);
values.addEventListener('focusout', toString, false);
function toNumber(e) {
const value = e.target.value;
const unformatted = value.replace(/\D/g,'');
values.value = unformatted;
}
function toString(e) {
const value = Number(e.target.value);
const formatted = value.toLocaleString();
if (formatted !== 'NaN') {
values.value = formatted;
}
}
<input id="values" type="text">
To fix that, you can also remove my addition and add a filter before the toString(e) does it's thing and filter the dots, text etc. so only the numbers remain.

Allow only regex pattern in javascript

I want the user to input a number with format:
##/####
Where the "#" are numbers.
Here is the sample code:
(function() {
var previousValue = document.getElementById('myInput').value;
var pattern = /^\d{2}(\/\d{4})?$/;
function validateInput(event) {
event = event || window.event;
var newValue = event.target.value || '';
if (newValue.match(pattern)) {
// Valid input; update previousValue:
previousValue = newValue;
} else {
// Invalid input; reset field value:
event.target.value = previousValue;
}
}
document.getElementById('myInput').onkeyup = validateInput;
}());
<input id="myInput" type="text" maxlength=7 value="" />
I can only write the first two numbers, but I can't type anything else after that, even though the regular expression seems correct to me.
---EDIT---
After all the answers, I want to point out that I already have a validator that fires on the submit, which tells the user if they have typed in the correct form; I just wanted to somehow "guide" the user in the typing of the input.
Use this var pattern = /^\d{0,2}(\/\d{0,4})?$/; when user is typing which basically allow to type the pattern you want. And when input become blur check length of input field and validate accordingly.(or you can use minlength(make it equal to maxlength) if you are using input field in form then you will not require blur method)
(function() {
var previousValue = document.getElementById('myInput').value;
var pattern = /^\d{0,2}(\/\d{0,4})?$/;
function validateInput(event) {
len = event.target.value.length;
event = event || window.event;
var newValue = event.target.value || '';
if (newValue.match(pattern)) {
// Valid input; update previousValue:
previousValue = newValue;
} else {
// Invalid input; reset field value:
event.target.value = previousValue;
}
}
document.getElementById('myInput').onkeyup = validateInput;
}());
(function() {
function validateInput(event) {
len = event.target.value.length;
(len===7) ? console.log("Success") : console.log("fail");
}
document.getElementById('myInput').onblur = validateInput;
}());
<input id="myInput" type="text" milength=7 maxlength=7 value="" />
<button>1</button>
Probably you want to allow regex to validate correct when the user is still not finished with writing it down.
var pattern = /^\d{0,2}(\/\d{0,4})?$/;
But you would still need to validate it after that, so onblur check might be better.
First of all, you can analyze your regex here.
You will find that your regex:
/^\d{2}\/\d{4}?$/
matches a string that begins with two digits, followed by a slash and then 4 digits repeated zero or one time (the question mark).
Just remove the question mark in order to match the exact pattern.
From my point of view your problem is in event that you handle. Onkeyup fired after any key up. And if the current value of input field is not matched with your pattern you replace it with old one value. I think you need to handle change event instead of keyup: codepen
To me, your approach of validating seems wrong! You have to wait to do the validation until the user blurs away from the input field.
What I am suggesting is to use the event onblur instead of onkeyup, to perform your validation. How can you validate an input which is not completed?
Or else, you could program the event onkeypress, to check the key which is struck is one you need. You will have to deal with key codes and all.
EDIT
Managed to tackle the problem! Check if the following helps.
(function() {
var previousValue = document.getElementById('myInput').value;
function validateInput(event) {
event = event || window.event;
var newValue = event.target.value || '';
var previousValueLength = document.getElementById('myInput').value.length;
var pattern = /^\d{2}\/\d{4}$/;
switch(previousValueLength){
case 0:
pattern = /^$/;
break;
case 1:
pattern = /^\d{1}$/;
break;
case 2:
pattern = /^\d{2}$/;
break;
case 3:
pattern = /^\d{2}\/$/;
break;
case 4:
pattern = /^\d{2}\/\d{1}$/;
break;
case 5:
pattern = /^\d{2}\/\d{2}$/;
break;
case 6:
pattern = /^\d{2}\/\d{3}$/;
break;
}
if (newValue.match(pattern)) {
// Valid input; update previousValue:
previousValue = newValue;
} else {
// Invalid input; reset field value:
event.target.value = previousValue;
}
}
document.getElementById('myInput').onkeyup = validateInput;
}());
https://jsfiddle.net/zjg6azjn/9/

testing user entry on keyup and regex

In my case the requirement is like -
The first name should allow alphabets, some chars like comma, dash and ascent chars.
The code works fine when we try to paste the ascent chars or use "abctajpu" add on in firefox. But as soon as user types in ALT+0192 or any ALT key with num pad.
The keyup function does not work. It lets the user to key in every possible combination with the ALT key.
Here is the sample code..
var namePattern = /^[a-zA-Z,-. \'ÀÈÌÒÙàèìòùÁÉÍÓÚÝáéíóúýÂÊÎÔÛâêîôûÃÑÕãñõÄËÏÖÜŸäëïöüŸçÇŠšŽžÅå]$/g;
var negateNamePattern = /[^a-zA-Z,-. \'ÀÈÌÒÙàèìòùÁÉÍÓÚÝáéíóúýÂÊÎÔÛâêîôûÃÑÕãñõÄËÏÖÜŸäëïöüŸçÇŠšŽžÅå]/g;
$("#First_Name").bind('keyup paste altKey', function(event) {
var obj = $(this);
if (event.type == 'paste') {
setTimeout(function() {
validateRealTime(event, obj, namePattern, negateNamePattern)
}, 1);
} else {
validateRealTime(event, obj, namePattern, negateNamePattern);
}
});
The key up event will still be fired when they do any ALT key with num pad, however only when they stop typing will the new character be appended.
Is there a specific reason why you need to do a key up event?
You could validate your field whenever they lose focus on the input.
Also, can we see your validateRealTime function?
EDIT
I think I've figured out a way to accomplish what you want.
We'll have to change your function to validate a string passed instead of getting the value of the object:
function validateRealTime(str, regExPattern, negateRegExPattern) {
var fieldVal = str;
fieldVal = fieldVal.replace(/^(\s+)/g,'');
fieldVal = validateInput(fieldVal, regExPattern, negateRegExPattern);
// return the new and validated value
return fieldVal;
}
I've removed the event from the function, but you can add it if you are using it somewhere else.
Also, we need to change from a keyup to a keypress event. This will allow us to determine when the ALT is pressed (ALT + # = one keypress, whereas ALT + # = # keyups)
Futhermore, since the value of the input gets updated on keyup, we need to make sure that on keyup only the validated string appears.
var validatedValue; // Store validate value to display on 'keyup'
var namePattern = /^[a-zA-Z,-. \'ÀÈÌÒÙàèìòùÁÉÍÓÚÝáéíóúýÂÊÎÔÛâêîôûÃÑÕãñõÄËÏÖÜŸäëïöüŸçÇŠšŽžÅå]$/g;
var negateNamePattern = /[^a-zA-Z,-. \'ÀÈÌÒÙàèìòùÁÉÍÓÚÝáéíóúýÂÊÎÔÛâêîôûÃÑÕãñõÄËÏÖÜŸäëïöüŸçÇŠšŽžÅå]/g;
$("#First_Name").bind('keyup', function(event){
$(this).val(validatedValue);
})
.bind('keypress paste', function(event){
var obj = $(this);
var char;
var string;
var newval;
if (event.type == 'paste'){
setTimeout(function(){validateRealTime(obj.val(), namePattern, negateNamePattern)}, 1);
} else {
// Get the ASCII code of the key pressed and get the Char representation of it
// When we do an ALT+#, it returns only one ASCII value
char = String.fromCharCode(event.keyCode);
// Get the current string and append the character added by the ALT
// We need to do this, because the val() is not updated yet, it still contains
// the old value
string = obj.val() + char;
validatedValue= validateRealTime(string, namePattern, negateNamePattern);
}
});
Also, I have not tested the paste event.
Finally its working....here is the working code...
$("#First_Name").bind('keyup paste', function(event){
var obj = $(this);
if(event.altKey) {
$("#First_Name").bind('keypress', function(event){
setTimeout(function(){validateRealTime(event, obj, namePattern, negateNamePattern)}, 1);
});
} else if (event.type == 'paste'){
setTimeout(function(){validateRealTime(event, obj, namePattern, negateNamePattern)}, 1);
} else {
validateRealTime(event, obj, namePattern, negateNamePattern);
}
});
Thanks a lot for the guidance...the trick was to delay the time so that keyup gets the typed in character.

Categories