add numpad sheet component

This commit is contained in:
MaysWind
2020-12-10 03:34:44 +08:00
parent fa34a1c9d2
commit 7a94c6cdeb
5 changed files with 441 additions and 41 deletions
+8
View File
@@ -75,6 +75,14 @@ body {
--f7-theme-color-tint: #d09467;
}
.no-right-border {
border-right: 0;
}
.no-bottom-border {
border-bottom: 0;
}
i.icon.la, i.icon.las, i.icon.lab {
font-size: 28px;
}
+312
View File
@@ -0,0 +1,312 @@
<template>
<f7-sheet class="numpad-sheet" :opened="show" @sheet:closed="onSheetClosed">
<f7-page-content class="no-margin no-padding">
<f7-row class="numpad-values">
<span class="numpad-value">{{ currentDisplay }}</span>
</f7-row>
<f7-row class="numpad-buttons">
<span class="numpad-button numpad-button-num" @click="inputNum(7)">
<span class="numpad-button-text">7</span>
</span>
<span class="numpad-button numpad-button-num" @click="inputNum(8)">
<span class="numpad-button-text">8</span>
</span>
<span class="numpad-button numpad-button-num" @click="inputNum(9)">
<span class="numpad-button-text">9</span>
</span>
<span class="numpad-button numpad-button-function no-right-border" @click="setSymbol('×')">
<span class="numpad-button-text">&times;</span>
</span>
<span class="numpad-button numpad-button-num" @click="inputNum(4)">
<span class="numpad-button-text">4</span>
</span>
<span class="numpad-button numpad-button-num" @click="inputNum(5)">
<span class="numpad-button-text">5</span>
</span>
<span class="numpad-button numpad-button-num" @click="inputNum(6)">
<span class="numpad-button-text">6</span>
</span>
<span class="numpad-button numpad-button-function no-right-border" @click="setSymbol('')">
<span class="numpad-button-text">&minus;</span>
</span>
<span class="numpad-button numpad-button-num" @click="inputNum(1)">
<span class="numpad-button-text">1</span>
</span>
<span class="numpad-button numpad-button-num" @click="inputNum(2)">
<span class="numpad-button-text">2</span>
</span>
<span class="numpad-button numpad-button-num" @click="inputNum(3)">
<span class="numpad-button-text">3</span>
</span>
<span class="numpad-button numpad-button-function no-right-border" @click="setSymbol('+')">
<span class="numpad-button-text">&plus;</span>
</span>
<span class="numpad-button numpad-button-num no-bottom-border" @click="inputDot()">
<span class="numpad-button-text">.</span>
</span>
<span class="numpad-button numpad-button-num no-bottom-border" @click="inputNum(0)">
<span class="numpad-button-text">0</span>
</span>
<span class="numpad-button numpad-button-num no-bottom-border" @click="backspace">
<span class="numpad-button-text">
<f7-icon f7="delete_left"></f7-icon>
</span>
</span>
<span class="numpad-button numpad-button-function numpad-button-confirm no-right-border no-bottom-border" @click="confirm()">
<span :class="{ 'numpad-button-text': true, 'numpad-button-text-confirm': !currentSymbol }">{{ confirmText }}</span>
</span>
</f7-row>
</f7-page-content>
</f7-sheet>
</template>
<script>
export default {
props: [
'amount',
'show'
],
data() {
const self = this;
return {
previousValue: '',
currentSymbol: '',
currentValue: self.getStringValue(self.amount)
}
},
computed: {
currentDisplay() {
const previousValue = this.$utilities.appendThousandsSeparator(this.previousValue);
const currentValue = this.$utilities.appendThousandsSeparator(this.currentValue);
if (this.currentSymbol) {
return `${previousValue} ${this.currentSymbol} ${currentValue}`;
} else {
return currentValue;
}
},
confirmText() {
if (this.currentSymbol) {
return '=';
} else {
return this.$i18n.t('OK');
}
}
},
watch: {
amount: function(newValue){
this.currentValue = this.getStringValue(newValue);
}
},
methods: {
getStringValue(value) {
let str = this.$utilities.numericCurrencyToString(value);
if (str.indexOf(',')) {
str = str.replaceAll(/,/g, '');
}
const dotPos = str.indexOf('.');
if (dotPos < 0) {
if (str === '0') {
return '';
}
return str;
}
let integer = str.substr(0, dotPos);
let decimals = str.substring(dotPos + 1, str.length);
let newDecimals = '';
for (let i = decimals.length - 1; i >= 0; i--) {
if (decimals[i] !== '0' || newDecimals.length > 0) {
newDecimals = decimals[i] + newDecimals;
}
}
if (newDecimals.length < 1) {
if (integer === '0') {
return '';
}
return integer;
}
return `${integer}.${newDecimals}`;
},
inputNum(num) {
if (this.currentValue === '0') {
this.currentValue = num.toString();
return;
} else if (this.currentValue === '-0') {
this.currentValue = '-' + num.toString();
return;
}
const dotPos = this.currentValue.indexOf('.');
if (dotPos >= 0 && this.currentValue.substring(dotPos + 1, this.currentValue.length).length >= 2) {
return;
}
this.currentValue = this.currentValue + num.toString();
},
inputDot() {
if (this.currentValue.indexOf('.') >= 0) {
return;
}
if (this.currentValue.length < 1) {
this.currentValue = '0';
} else if (this.currentValue === '-') {
this.currentValue = '-0';
}
this.currentValue = this.currentValue + '.';
},
setSymbol(symbol) {
if (this.currentValue) {
if (this.currentSymbol) {
this.confirm();
}
this.previousValue = this.currentValue;
this.currentValue = '';
}
this.currentSymbol = symbol;
},
backspace() {
if (!this.currentValue || this.currentValue.length < 1) {
if (this.currentSymbol) {
this.currentValue = this.previousValue;
this.previousValue = '';
this.currentSymbol = '';
}
return;
}
this.currentValue = this.currentValue.substr(0, this.currentValue.length - 1);
},
confirm() {
if (this.currentSymbol && this.currentValue.length >= 1) {
const previousValue = this.$utilities.stringCurrencyToNumeric(this.previousValue);
const currentValue = this.$utilities.stringCurrencyToNumeric(this.currentValue);
let finalValue = 0;
switch (this.currentSymbol) {
case '+':
finalValue = previousValue + currentValue;
break;
case '':
finalValue = previousValue - currentValue;
break;
case '×':
finalValue = Math.round(previousValue * currentValue / 100);
break;
default:
finalValue = previousValue;
}
this.currentValue = this.getStringValue(finalValue);
this.previousValue = '';
this.currentSymbol = '';
} else if (this.currentSymbol && this.currentValue.length < 1) {
this.currentValue = this.previousValue;
this.previousValue = '';
this.currentSymbol = '';
} else {
const amount = this.$utilities.stringCurrencyToNumeric(this.currentValue);
this.currentValue = '';
this.$emit('numpad:change', amount);
}
},
onSheetClosed() {
this.currentValue = '';
this.previousValue = '';
this.currentSymbol = '';
this.$emit('numpad:closed');
}
}
}
</script>
<style>
.numpad-sheet {
height: auto;
}
.numpad-values {
border-bottom: 1px solid var(--f7-page-bg-color);
}
.numpad-value {
display: flex;
position: relative;
padding-left: 16px;
font-size: 24px;
line-height: 1;
height: 50px;
justify-content: center;
align-items: center;
box-sizing: border-box;
user-select: none;
}
.numpad-buttons {
display: flex;
flex-wrap: wrap;
}
.numpad-button {
display: flex;
position: relative;
text-align: center;
border-right: 1px solid var(--f7-page-bg-color);
border-bottom: 1px solid var(--f7-page-bg-color);
cursor: pointer;
height: 60px;
flex-direction: column;
justify-content: center;
align-items: center;
box-sizing: border-box;
user-select: none;
}
.numpad-button.active-state {
background-color: var(--f7-list-button-pressed-bg-color);
}
.numpad-button-num {
width: calc(80% / 3);
}
.numpad-button-function {
width: 20%;
}
.numpad-button-confirm {
background-color: var(--f7-theme-color);
color: #ffffff;
}
.numpad-button-confirm.active-state {
background-color: var(--f7-theme-color-tint);
}
.numpad-button-text {
display: block;
font-size: 28px;
line-height: 1;
}
.numpad-button-text-confirm {
font-size: 20px;
}
</style>
+1 -41
View File
@@ -2,21 +2,6 @@ import currency from "../consts/currency.js";
import settings from "../lib/settings.js";
import utils from "../lib/utils.js";
function appendThousandsSeparator(value) {
const finalChars = [];
for (let i = 0; i < value.length; i++) {
if (i % 3 === 0 && i > 0) {
finalChars.push(',');
}
finalChars.push(value.charAt(value.length - 1 - i));
}
finalChars.reverse();
return finalChars.join('');
}
export default function ({i18n}, value, currencyCode) {
if (!utils.isNumber(value) && !utils.isString(value)) {
return value;
@@ -26,32 +11,7 @@ export default function ({i18n}, value, currencyCode) {
value = value.toString();
}
const negative = value.charAt(0) === '-';
if (negative) {
value = value.substr(1);
}
if (value.length === 0) {
value = '0.00';
} else if (value.length === 1) {
value = '0.0' + value;
} else if (value.length === 2) {
value = '0.' + value;
} else {
let integer = value.substr(0, value.length - 2);
let decimals = value.substr(value.length - 2, 2);
if (settings.isEnableThousandsSeparator() && integer.length > 3) {
integer = appendThousandsSeparator(integer);
}
value = `${integer}.${decimals}`;
}
if (negative) {
value = `-${value}`;
}
value = utils.numericCurrencyToString(value);
const currencyDisplayMode = settings.getCurrencyDisplayMode();
+118
View File
@@ -1,6 +1,7 @@
import CryptoJS from "crypto-js";
import uaParser from 'ua-parser-js';
import accountConstants from '../consts/account.js';
import settings from "./settings.js";
function isFunction(val) {
return typeof(val) === 'function';
@@ -99,6 +100,120 @@ function copyArrayTo(fromArray, toArray) {
return toArray;
}
function appendThousandsSeparator(value) {
if (!settings.isEnableThousandsSeparator() || value.length <= 3) {
return value;
}
const negative = value.charAt(0) === '-';
if (negative) {
value = value.substr(1);
}
const dotPos = value.indexOf('.');
const integer = dotPos < 0 ? value : value.substr(0, dotPos);
const decimals = dotPos < 0 ? '' : value.substring(dotPos + 1, value.length);
const finalChars = [];
for (let i = 0; i < integer.length; i++) {
if (i % 3 === 0 && i > 0) {
finalChars.push(',');
}
finalChars.push(integer.charAt(integer.length - 1 - i));
}
finalChars.reverse();
let newInteger = finalChars.join('');
if (negative) {
newInteger = `-${newInteger}`;
}
if (dotPos < 0) {
return newInteger;
} else {
return `${newInteger}.${decimals}`;
}
}
function numericCurrencyToString(num) {
let str = num.toString();
const negative = str.charAt(0) === '-';
if (negative) {
str = str.substr(1);
}
if (str.length === 0) {
str = '0.00';
} else if (str.length === 1) {
str = '0.0' + str;
} else if (str.length === 2) {
str = '0.' + str;
} else {
let integer = str.substr(0, str.length - 2);
let decimals = str.substr(str.length - 2, 2);
integer = appendThousandsSeparator(integer);
str = `${integer}.${decimals}`;
}
if (negative) {
str = `-${str}`;
}
return str;
}
function stringCurrencyToNumeric(str) {
if (!str || str.length < 1) {
return 0;
}
const negative = str.charAt(0) === '-';
if (negative) {
str = str.substr(1);
}
if (!str || str.length < 1) {
return 0;
}
const sign = negative ? -1 : 1;
if (str.indexOf(',')) {
str = str.replaceAll(/,/g, '');
}
let dotPos = str.indexOf('.');
if (dotPos < 0) {
return sign * parseInt(str) * 100;
} else if (dotPos === 0) {
str = '0' + str;
dotPos++;
}
const integer = str.substr(0, dotPos);
const decimals = str.substring(dotPos + 1, str.length);
if (decimals.length < 1) {
return sign * parseInt(integer) * 100;
} else if (decimals.length === 1) {
return sign * parseInt(integer) * 100 + sign * parseInt(decimals) * 10;
} else if (decimals.length === 2) {
return sign * parseInt(integer) * 100 + sign * parseInt(decimals);
} else {
return sign * parseInt(integer) * 100 + sign * parseInt(decimals.substr(0, 2));
}
}
function base64encode(arrayBuffer) {
if (!arrayBuffer || arrayBuffer.length === 0) {
return null;
@@ -227,6 +342,9 @@ export default {
isBoolean,
copyObjectTo,
copyArrayTo,
appendThousandsSeparator,
numericCurrencyToString,
stringCurrencyToNumeric,
base64encode,
arrayBufferToString,
stringToArrayBuffer,
+2
View File
@@ -38,6 +38,7 @@ import tokenIconFilter from './filters/tokenIcon.js';
import IconSelectionSheet from "./components/mobile/IconSelectionSheet.vue";
import ColorSelectionSheet from "./components/mobile/ColorSelectionSheet.vue";
import NumberPadSheet from "./components/mobile/NumberPadSheet.vue";
import App from './Mobile.vue';
Vue.use(VueI18n);
@@ -47,6 +48,7 @@ Vue.use(VueClipboard);
Vue.component('PincodeInput', PincodeInput);
Vue.component('IconSelectionSheet', IconSelectionSheet);
Vue.component('ColorSelectionSheet', ColorSelectionSheet);
Vue.component('NumberPadSheet', NumberPadSheet);
Framework7.use(Framework7Vue);
const i18n = new VueI18n(getI18nOptions());