![]() Server : Apache System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64 User : corals ( 1002) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /home/corals/vreg/components/Forms/vueDelayedInputMask/ |
<script> import _ from "lodash"; import InputAddon from "./addons/InputAddon.vue"; import types, {PASSWORD_MASK} from "./masked/types"; const HIDE_DELAY = 800; const FILL_CHAR = "*"; const EMPTY_STRING = ""; const ENTER_KEY_CODE = 13; export default { name: "VueDelayedInputMask", props: { id: { type: String, }, value: { type: String, default: () => { return EMPTY_STRING; }, }, name: { type: String, required: true, }, placeholder: { type: String, default: () => { return EMPTY_STRING; }, }, wrapperClassName: { type: String, }, classNames: { type: Array, default: () => { return []; }, }, delayTime: { default: () => { return HIDE_DELAY; }, }, fillChar: { type: String, default: () => { return FILL_CHAR; }, }, needClearOnFocus: { type: Boolean, default: false, }, needFillOnBlur: { type: Boolean, default: false, }, disabled: { type: Boolean, default: false, }, keyEnter: { type: Function, default: () => { }, }, hideFieldType: { type: String, default: "hidden", }, pattern: { default: PASSWORD_MASK, }, showHelperAddon: { type: Boolean, default: false }, maxLength: { type: Number, required: false, default: Number.MAX_SAFE_INTEGER }, onlyNumbers: { type: Boolean, required: false, default: false }, autocomplete: { type: String, required: false, default: 'off' } }, data() { return { input: EMPTY_STRING, clear: _.isUndefined(this.value) || _.isNull(this.value) ? EMPTY_STRING : this.value, }; }, created() { this.$on("fillInput", () => { let filling = _.throttle(this.__fillPattern, this.delayTime, {leading: false}); filling(); }); if (this.value) { this.input = this.value; this.__fillPattern(); } }, methods: { /** * Handle input into password input * @param $event * @private */ __inputHandler($event) { if ($event.keyCode === ENTER_KEY_CODE) { this.keyEnter(); } if (!this.__isSpecialKey($event.keyCode)) { this.__computeInputData($event); } }, /** * Check insert position and add new char (inputed or copy-pasted into input) * @param $event * @param value * @private */ __computeInputData($event, value = false) { let inputValues = value ? value : $event.target.value; if (inputValues && this.onlyNumbers) { inputValues = inputValues.replace(/[^0-9●]/g, ''); $event.target.value = inputValues; } let selectIndex = $event.target.selectionStart; let selectIndexEnd = $event.target.selectionEnd; let realValue = $event.target.value; let shift = inputValues.length - this.clear.length; if (selectIndex !== selectIndexEnd) { this.clear = inputValues; } else if (shift > 0) { let addedChars = realValue.slice(selectIndex - shift, selectIndex); this.clear = this.clear.slice(0, selectIndex - shift) + addedChars + this.clear.slice(selectIndex - shift); } else if (shift < 0) { this.clear = this.clear.slice(0, selectIndex) + this.clear.slice(selectIndex - shift); } if (this.maxLength) { this.clear = this.clear.substr(0, this.maxLength); this.input = this.input.substr(0, this.maxLength); } this.$emit("fillInput"); }, /** * Handle paste event and call compute method * @param $event * @private */ __copyPasteHandler($event) { this.__computeInputData($event, $event.clipboardData.getData("text")); }, /** * Clear inputs * @private */ __clearOnFocus() { this.$set(this, "input", EMPTY_STRING); this.$set(this, "clear", EMPTY_STRING); }, __getFillAction(actionName) { return _.get(types, actionName); }, /** * Fill field chars by symbol from props */ __fillPattern() { let filledInput = EMPTY_STRING; typeof this.pattern === "function" ? (filledInput = this.pattern(this.fillChar, this.input)) : (filledInput = this.__getFillAction(this.pattern)(this.fillChar, this.input)); if (filledInput) { filledInput = filledInput.substr(0, this.maxLength); } this.$set(this, "input", filledInput); }, /** * Clear value */ __unFilled() { this.input = this.clear; }, /** * Check Ctrl, Enter, Shift and other keys * @param keyCode * @returns {boolean} * @private */ __isSpecialKey(keyCode) { return (keyCode >= 9 && keyCode <= 20) || (keyCode >= 33 && keyCode <= 40) || keyCode === 224; }, /** * Wrap * @param $event * @param fieldPath * @private */ __inputProxy($event, fieldPath) { this.$set(this, fieldPath, $event.target.value); }, }, watch: { clear(data) { this.$emit("input", data); }, input(value) { this.input = value.substr(0, this.maxLength); const pos = this.$refs.input.selectionStart; this.$nextTick(() => { this.$refs.input.selectionEnd = pos; }); } }, render(h) { let visibleInput = h("input", { class: this.classNames, attrs: { id: this.id ? this.id : null, name: this.name, placeholder: this.placeholder, autocomplete: this.autocomplete }, domProps: { value: this.input, disabled: this.disabled, }, on: { input: $event => { $event.preventDefault(); this.__inputHandler($event); this.__inputProxy($event, "input"); }, focus: $event => { this.needClearOnFocus ? this.__clearOnFocus() : null; }, blur: $event => { this.needFillOnBlur ? this.__fillPattern($event) : null; }, paste: $event => { this.__copyPasteHandler($event); }, }, ref: "input" }); let hiddenInput = h("input", { attrs: {type: this.hideFieldType, hidden: true}, }); let slotShowHiddenAddon = this.showHelperAddon ? h(InputAddon, { props: { icon: "icon", label: "Show", activeLabel: "Hide", active: false, }, on: { mousedown: () => { this.__unFilled(); }, mouseup: () => { this.__fillPattern(); }, }, }) : null; return h("div", {class: {[this.wrapClassName]: true}}, [ visibleInput, hiddenInput, this.$slots.additional ? this.$slots.additional : null, this.$slots.error ? this.$slots.error : null, this.$slots.hiddenAddon ? this.$slots.hiddenAddon : slotShowHiddenAddon, ]); }, }; </script>