Id like to share my code and see if anyone can find any issues with it. I think it is a simple code, not too long, purely javascript and an improved <input> field for html.
you have the tags "min" and "max" that allow you to set a minimum and maximum value for the input field.
it ONLY registers numbers and can do negatives (if min < 0 )
if the input is < min, it clears the input and replaces with min value.
if the input is > max, it clears the input and replaces with max value.
it avoids leading "000" values (ei number = 0083)
max characters input length is unnecessary, just set max to "9999" for 4 characters
it allow "-" character but only at beginning (if > min)
it allows copy/pasting but only if the pasted value is an integer.
it allow undo-redo
to use the code, make an html element like this:
here is the javascript code:
you have the tags "min" and "max" that allow you to set a minimum and maximum value for the input field.
it ONLY registers numbers and can do negatives (if min < 0 )
if the input is < min, it clears the input and replaces with min value.
if the input is > max, it clears the input and replaces with max value.
it avoids leading "000" values (ei number = 0083)
max characters input length is unnecessary, just set max to "9999" for 4 characters
it allow "-" character but only at beginning (if > min)
it allows copy/pasting but only if the pasted value is an integer.
it allow undo-redo
to use the code, make an html element like this:
HTML:
<int-input id="id-here" min="0" max="360" > </int-input>
here is the javascript code:
JavaScript:
class intInput extends HTMLElement
{
constructor()
{
super();
this.min = 0;
this.max = 999;
this.onkeydown = this._keydown;
this.onblur = this._blur;
this.onpaste = this._paste;
}
connectedCallback()
{
if (this.hasAttribute("max"))
{
this.getMax(this.getAttribute("max"));
}
if (this.hasAttribute("min"))
{
this.getMin(this.getAttribute("min"));
}
if(this.max < 0 ) this.max = 0; //range =[-∞, 0 ]
//for rangeg [-∞, -x], we will need a diffirent system for negatives only!
if( this.min >= this.max ) this.min = this.max-1;
this.innerHTML = this.min;
//set basic properties//
this.setAttribute("contenteditable", true);
this.style.display = "inline-block";
this.style.width = "100px";
this.style.height = "20px";
this.style.padding = "4px 2px 0px 4px";
this.style.border = "1px solid #000000";
this.style.textAlign = "left";
this.style.fontWeight = 'normal';
//this.style.wordWrap = "normal";
this.style.setProperty('white-space', "nowrap");
this.style.overflow = "auto";
this.style.setProperty('scrollbar-width', "none");
}
_keydown(evt)
{
var val = this.innerHTML.trim();
var sel = document.getSelection();
let selStart = sel.baseOffset;
let selEnd = sel.extentOffset;
if( selStart > selEnd )
{
selStart = sel.extentOffset;
selEnd = sel.baseOffset;
}
//if (isNumber(evt.key) -> only allow number keys
//allow: backspace, '-', left, right, up, down, home, end, ctrl
if( !this.isNumber(evt.key) && evt.key != "Backspace" && evt.key != "-" && evt.key != "ArrowLeft" && evt.key != "ArrowRight" && evt.key != "ArrowUp" && evt.key != "ArrowDown" && evt.key != "Home" && evt.key != "End" && !( window.event.ctrlKey) )
evt.preventDefault();
//1: prevent '-' ////////////////////////////////////////////////////////
//prevent "-"
if(evt.key == "-")
{
if( selStart == 0 ) //'-' can only be entered at start//
{
//if min >=0, than we cannot have negatives, so disable '-'
if (this.min >= 0)
{
evt.preventDefault();
return;
}
//overwritting first digit -> allow '-'
else if( selEnd > 0 )
{
}
//if val == '0' we replace it with '-'
else if (val[0]=='0')
{
evt.preventDefault();
this.setVal('-');
}
//if val == '-' no need to do anything
else if(val[0] == "-")
{
evt.preventDefault();
return;
}
}
else //can never have '-' after selStart = 0
{
evt.preventDefault();
return;
}
}
//2: prevent '0' ///////////////////////////////////////////////////////
//prevent entering "0"
if( evt.key == "0" )
{
if( selStart == 2 )
{
//if we already have '-0' second digit cannot be '0'
if( val[1] == '0' && val[0] == '-')
evt.preventDefault();
}
if( selStart == 1 )
{
//if we already have '0' or '-' second digit cannot be '0'
if( val[0] == '0' || val[0] == '-')
evt.preventDefault();
}
if( selStart == 0 ) //we are at start position
{
//only allow '0' if everything is selected
if(selEnd < val.length)
evt.preventDefault();
}
}
//3: if val == '0', replace with number//////////////////////////////////////
if( this.isNumber(evt.key) )
{
//if val='0', replace it with key number//
if(val[0]=='0')
{
evt.preventDefault();
this.setVal(evt.key);
}
}
//4: prevent > max, prevent < min //////////////////////////////
const newInput = parseInt(val.substring(0, selStart) + evt.key + val.substring(selEnd,val.length) );
////////////////////////////////////////////
//if newinput < min, make it = min
if( newInput < this.min )
{
evt.preventDefault();
this.setVal(this.min);
}
///////////////////////////////////////////////
//if newinput > max, make it = max
if( newInput > this.max )
{
evt.preventDefault();
this.setVal(this.max);
}
}
_blur(evt)
{
if(this.innerHTML == "" || this.innerHTML == "-")
{
if(this.min > 0 ) this.setVal(this.min);
else this.setVal('0');
}
}
_paste(evt)
{
//variables
let cur_text = this.innerHTML.trim();
let pasted_text = evt.clipboardData.getData('text');
//let pasted_text_mod = "";
//
var sel = document.getSelection();
let selStart = sel.baseOffset;
let selEnd = sel.extentOffset;
if( selStart > selEnd )
{
selStart = sel.extentOffset;
selEnd = sel.baseOffset;
}
//get new text (cur_text+pasted text)//
let new_text = cur_text.substring(0, selStart) + pasted_text + cur_text.substring(selEnd,cur_text.length);
evt.preventDefault();
//go through each character, if a digit is NOT [0-9] or '-'at beginning or have '00...' or has '-000'//
if( new_text.length > 1 )
{
if(new_text[0] == '-' && new_text[1] == '0') return; //cannot have newtext = '-008328...';
if(new_text[0] == '0' ) return; //cannot have newtext = '0...'; //08328
}
for (let i = 0; i < new_text.length; i++)
{
let char = new_text[i];
if( i==0 && char == '-') //allow '-' at i=0 //-3232
{
}
else if( !this.isNumber(char) ) //char must be a number only
{
//error, paste cannot be done!
return;
}
}
if( parseInt(new_text) < this.min )
this.setVal(this.min);
else if( parseInt(new_text) > this.max )
this.setVal(this.max);
else if( pasted_text != "" )
document.execCommand("insertText", false, pasted_text );
}
//other functions//////////////////////////////////////////////
setVal(newVal)
{
if( this.innerHTML != newVal )
{
var sel = document.getSelection();
var range = document.createRange();
range.selectNodeContents(this);
sel.removeAllRanges()
sel.addRange(range)
document.execCommand("insertText", false, newVal);
}
}
isNumber(val)
{
if (val == "0" || val == "1" || val == "2" || val == "3" || val == "4" || val == "5" || val == "6" || val == "7" || val == "8" || val == "9") return true;
return false;
}
getMax(str)
{
if( str != "" ) //value is not ""
{
const val = str.replace(/\D/g, ""); //only get numbers//
if(str[0] == "-" )
{
if( val.length > 1 ) this.max = "-"+str.replace(/\D/g, "");
}
else
{
if( val.length > 0 ) this.max = str.replace(/\D/g, "");
}
}
}
getMin(str)
{
if( str != "" ) //value is not ""
{
const val = str.replace(/\D/g, ""); //only get numbers//
if(str[0] == "-" )
{
if( val.length > 1 ) this.min = "-"+str.replace(/\D/g, "");
}
else
{
if( val.length > 0 ) this.min = str.replace(/\D/g, "");
}
}
}
}
customElements.define("int-input", intInput);
Last edited: