vue-numero-input
by joplomacedo
HTML
<div id="app">
<vue-numero-input v-model="theNumber" :min="0.5" :precision="2" :min="0" :max="20"></vue-numero-input>
<div>
val: {{ theNumber }}
</div>
<div>
typeof val: {{ typeof theNumber }}
</div>
</div>
CSS
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
#app {
background: #fff;
border-radius: 4px;
padding: 20px;
transition: all 0.2s;
}
li {
margin: 8px 0;
}
h2 {
font-weight: bold;
margin-bottom: 15px;
}
del {
color: rgba(0, 0, 0, 0.3);
}
Vue
const isValidNumStr = (() => {
const allowedChars = [
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"0",
".",
"-",
];
return function ({ numStr, options: { max, min, precision } }) {
//make sure it's a numstr
numStr = "" + numStr;
if (numStr.split("").some((char) => !allowedChars.includes(char))) {
return false;
}
if (numStr.includes("-")) {
if (min >= 0) {
return false;
}
//if the minus isnt last char
// (also covers existence of two minuses)
if (numStr.lastIndexOf("-") !== 0) {
return false;
}
}
if (numStr.includes(".")) {
if (precision == 0) {
//includes dot and precison = 0
return false;
}
if (numStr.split(".").length - 1 > 2) {
//more than one dot
return false;
}
const decimalPart = numStr.split(".")[1];
if (decimalPart.length > precision) {
//more decimals than allowed precison
return false;
}
}
if ( numStr == '') {
return true;
}
/*
if ( numStr === '0.' || numStr === '.' && min > 0 && min < 1) {
return true;
}
*/
const num = +numStr;
if (num < min) {
return false;
}
if (num > max) {
return false;
}
return true;
};
})();
function convertNumStrToNum({numStr, defaultNum}) {
if (numStr == '' || numStr === "." || numStr === "-." || numStr === "-") {
return defaultNum;
}
return +numStr;
}
function getPrecisionFromNum(num) {
const decimalPart = ("" + num).split(".")[1];
return decimalPart ?...