123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652 |
- "use strict";
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
- exports.__esModule = true;
- exports.default = void 0;
- var _babelHelperVueJsxMergeProps = _interopRequireDefault(require("@vue/babel-helper-vue-jsx-merge-props"));
- var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
- var _resetScroll = require("../utils/dom/reset-scroll");
- var _number = require("../utils/format/number");
- var _event = require("../utils/dom/event");
- var _scroll = require("../utils/dom/scroll");
- var _utils = require("../utils");
- var _icon = _interopRequireDefault(require("../icon"));
- var _cell = _interopRequireDefault(require("../cell"));
- var _shared = require("../cell/shared");
- // Utils
- // Components
- var _createNamespace = (0, _utils.createNamespace)('field'),
- createComponent = _createNamespace[0],
- bem = _createNamespace[1];
- var _default = createComponent({
- inheritAttrs: false,
- provide: function provide() {
- return {
- vanField: this
- };
- },
- inject: {
- vanForm: {
- default: null
- }
- },
- props: (0, _extends2.default)({}, _shared.cellProps, {
- name: String,
- rules: Array,
- disabled: {
- type: Boolean,
- default: null
- },
- readonly: {
- type: Boolean,
- default: null
- },
- autosize: [Boolean, Object],
- leftIcon: String,
- rightIcon: String,
- clearable: Boolean,
- formatter: Function,
- maxlength: [Number, String],
- labelWidth: [Number, String],
- labelClass: null,
- labelAlign: String,
- inputAlign: String,
- placeholder: String,
- errorMessage: String,
- errorMessageAlign: String,
- showWordLimit: Boolean,
- value: {
- type: [Number, String],
- default: ''
- },
- type: {
- type: String,
- default: 'text'
- },
- error: {
- type: Boolean,
- default: null
- },
- colon: {
- type: Boolean,
- default: null
- },
- clearTrigger: {
- type: String,
- default: 'focus'
- },
- formatTrigger: {
- type: String,
- default: 'onChange'
- }
- }),
- data: function data() {
- return {
- focused: false,
- validateFailed: false,
- validateMessage: ''
- };
- },
- watch: {
- value: function value() {
- this.updateValue(this.value);
- this.resetValidation();
- this.validateWithTrigger('onChange');
- this.$nextTick(this.adjustSize);
- }
- },
- mounted: function mounted() {
- this.updateValue(this.value, this.formatTrigger);
- this.$nextTick(this.adjustSize);
- if (this.vanForm) {
- this.vanForm.addField(this);
- }
- },
- beforeDestroy: function beforeDestroy() {
- if (this.vanForm) {
- this.vanForm.removeField(this);
- }
- },
- computed: {
- showClear: function showClear() {
- var readonly = this.getProp('readonly');
- if (this.clearable && !readonly) {
- var hasValue = (0, _utils.isDef)(this.value) && this.value !== '';
- var trigger = this.clearTrigger === 'always' || this.clearTrigger === 'focus' && this.focused;
- return hasValue && trigger;
- }
- },
- showError: function showError() {
- if (this.error !== null) {
- return this.error;
- }
- if (this.vanForm && this.vanForm.showError && this.validateFailed) {
- return true;
- }
- },
- listeners: function listeners() {
- return (0, _extends2.default)({}, this.$listeners, {
- blur: this.onBlur,
- focus: this.onFocus,
- input: this.onInput,
- click: this.onClickInput,
- keypress: this.onKeypress
- });
- },
- labelStyle: function labelStyle() {
- var labelWidth = this.getProp('labelWidth');
- if (labelWidth) {
- return {
- width: (0, _utils.addUnit)(labelWidth)
- };
- }
- },
- formValue: function formValue() {
- if (this.children && (this.$scopedSlots.input || this.$slots.input)) {
- return this.children.value;
- }
- return this.value;
- }
- },
- methods: {
- // @exposed-api
- focus: function focus() {
- if (this.$refs.input) {
- this.$refs.input.focus();
- }
- },
- // @exposed-api
- blur: function blur() {
- if (this.$refs.input) {
- this.$refs.input.blur();
- }
- },
- runValidator: function runValidator(value, rule) {
- return new Promise(function (resolve) {
- var returnVal = rule.validator(value, rule);
- if ((0, _utils.isPromise)(returnVal)) {
- return returnVal.then(resolve);
- }
- resolve(returnVal);
- });
- },
- isEmptyValue: function isEmptyValue(value) {
- if (Array.isArray(value)) {
- return !value.length;
- }
- if (value === 0) {
- return false;
- }
- return !value;
- },
- runSyncRule: function runSyncRule(value, rule) {
- if (rule.required && this.isEmptyValue(value)) {
- return false;
- }
- if (rule.pattern && !rule.pattern.test(value)) {
- return false;
- }
- return true;
- },
- getRuleMessage: function getRuleMessage(value, rule) {
- var message = rule.message;
- if ((0, _utils.isFunction)(message)) {
- return message(value, rule);
- }
- return message;
- },
- runRules: function runRules(rules) {
- var _this = this;
- return rules.reduce(function (promise, rule) {
- return promise.then(function () {
- if (_this.validateFailed) {
- return;
- }
- var value = _this.formValue;
- if (rule.formatter) {
- value = rule.formatter(value, rule);
- }
- if (!_this.runSyncRule(value, rule)) {
- _this.validateFailed = true;
- _this.validateMessage = _this.getRuleMessage(value, rule);
- return;
- }
- if (rule.validator) {
- return _this.runValidator(value, rule).then(function (result) {
- if (result === false) {
- _this.validateFailed = true;
- _this.validateMessage = _this.getRuleMessage(value, rule);
- }
- });
- }
- });
- }, Promise.resolve());
- },
- validate: function validate(rules) {
- var _this2 = this;
- if (rules === void 0) {
- rules = this.rules;
- }
- return new Promise(function (resolve) {
- if (!rules) {
- resolve();
- }
- _this2.resetValidation();
- _this2.runRules(rules).then(function () {
- if (_this2.validateFailed) {
- resolve({
- name: _this2.name,
- message: _this2.validateMessage
- });
- } else {
- resolve();
- }
- });
- });
- },
- validateWithTrigger: function validateWithTrigger(trigger) {
- if (this.vanForm && this.rules) {
- var defaultTrigger = this.vanForm.validateTrigger === trigger;
- var rules = this.rules.filter(function (rule) {
- if (rule.trigger) {
- return rule.trigger === trigger;
- }
- return defaultTrigger;
- });
- if (rules.length) {
- this.validate(rules);
- }
- }
- },
- resetValidation: function resetValidation() {
- if (this.validateFailed) {
- this.validateFailed = false;
- this.validateMessage = '';
- }
- },
- updateValue: function updateValue(value, trigger) {
- if (trigger === void 0) {
- trigger = 'onChange';
- }
- value = (0, _utils.isDef)(value) ? String(value) : ''; // native maxlength have incorrect line-break counting
- // see: https://github.com/vant-ui/vant/issues/5033
- var maxlength = this.maxlength;
- if ((0, _utils.isDef)(maxlength) && value.length > maxlength) {
- if (this.value && this.value.length === +maxlength) {
- value = this.value;
- } else {
- value = value.slice(0, maxlength);
- }
- }
- if (this.type === 'number' || this.type === 'digit') {
- var isNumber = this.type === 'number';
- value = (0, _number.formatNumber)(value, isNumber, isNumber);
- }
- if (this.formatter && trigger === this.formatTrigger) {
- value = this.formatter(value);
- }
- var input = this.$refs.input;
- if (input && value !== input.value) {
- input.value = value;
- }
- if (value !== this.value) {
- this.$emit('input', value);
- }
- },
- onInput: function onInput(event) {
- // not update v-model when composing
- if (event.target.composing) {
- return;
- }
- this.updateValue(event.target.value);
- },
- onFocus: function onFocus(event) {
- this.focused = true;
- this.$emit('focus', event); // https://github.com/vant-ui/vant/issues/9715
- this.$nextTick(this.adjustSize); // readonly not work in legacy mobile safari
- /* istanbul ignore if */
- if (this.getProp('readonly')) {
- this.blur();
- }
- },
- onBlur: function onBlur(event) {
- if (this.getProp('readonly')) {
- return;
- }
- this.focused = false;
- this.updateValue(this.value, 'onBlur');
- this.$emit('blur', event);
- this.validateWithTrigger('onBlur');
- this.$nextTick(this.adjustSize);
- (0, _resetScroll.resetScroll)();
- },
- onClick: function onClick(event) {
- this.$emit('click', event);
- },
- onClickInput: function onClickInput(event) {
- this.$emit('click-input', event);
- },
- onClickLeftIcon: function onClickLeftIcon(event) {
- this.$emit('click-left-icon', event);
- },
- onClickRightIcon: function onClickRightIcon(event) {
- this.$emit('click-right-icon', event);
- },
- onClear: function onClear(event) {
- (0, _event.preventDefault)(event);
- this.$emit('input', '');
- this.$emit('clear', event);
- },
- onKeypress: function onKeypress(event) {
- var ENTER_CODE = 13;
- if (event.keyCode === ENTER_CODE) {
- var submitOnEnter = this.getProp('submitOnEnter');
- if (!submitOnEnter && this.type !== 'textarea') {
- (0, _event.preventDefault)(event);
- } // trigger blur after click keyboard search button
- if (this.type === 'search') {
- this.blur();
- }
- }
- this.$emit('keypress', event);
- },
- adjustSize: function adjustSize() {
- var input = this.$refs.input;
- if (!(this.type === 'textarea' && this.autosize) || !input) {
- return;
- }
- var scrollTop = (0, _scroll.getRootScrollTop)();
- input.style.height = 'auto';
- var height = input.scrollHeight;
- if ((0, _utils.isObject)(this.autosize)) {
- var _this$autosize = this.autosize,
- maxHeight = _this$autosize.maxHeight,
- minHeight = _this$autosize.minHeight;
- if (maxHeight) {
- height = Math.min(height, maxHeight);
- }
- if (minHeight) {
- height = Math.max(height, minHeight);
- }
- }
- if (height) {
- input.style.height = height + 'px'; // https://github.com/vant-ui/vant/issues/9178
- (0, _scroll.setRootScrollTop)(scrollTop);
- }
- },
- genInput: function genInput() {
- var h = this.$createElement;
- var type = this.type;
- var disabled = this.getProp('disabled');
- var readonly = this.getProp('readonly');
- var inputSlot = this.slots('input');
- var inputAlign = this.getProp('inputAlign');
- if (inputSlot) {
- return h("div", {
- "class": bem('control', [inputAlign, 'custom']),
- "on": {
- "click": this.onClickInput
- }
- }, [inputSlot]);
- }
- var inputProps = {
- ref: 'input',
- class: bem('control', inputAlign),
- domProps: {
- value: this.value
- },
- attrs: (0, _extends2.default)({}, this.$attrs, {
- name: this.name,
- disabled: disabled,
- readonly: readonly,
- placeholder: this.placeholder
- }),
- on: this.listeners,
- // add model directive to skip IME composition
- directives: [{
- name: 'model',
- value: this.value
- }]
- };
- if (type === 'textarea') {
- return h("textarea", (0, _babelHelperVueJsxMergeProps.default)([{}, inputProps]));
- }
- var inputType = type;
- var inputMode; // type="number" is weird in iOS, and can't prevent dot in Android
- // so use inputmode to set keyboard in modern browsers
- if (type === 'number') {
- inputType = 'text';
- inputMode = 'decimal';
- }
- if (type === 'digit') {
- inputType = 'tel';
- inputMode = 'numeric';
- }
- return h("input", (0, _babelHelperVueJsxMergeProps.default)([{
- "attrs": {
- "type": inputType,
- "inputmode": inputMode
- }
- }, inputProps]));
- },
- genLeftIcon: function genLeftIcon() {
- var h = this.$createElement;
- var showLeftIcon = this.slots('left-icon') || this.leftIcon;
- if (showLeftIcon) {
- return h("div", {
- "class": bem('left-icon'),
- "on": {
- "click": this.onClickLeftIcon
- }
- }, [this.slots('left-icon') || h(_icon.default, {
- "attrs": {
- "name": this.leftIcon,
- "classPrefix": this.iconPrefix
- }
- })]);
- }
- },
- genRightIcon: function genRightIcon() {
- var h = this.$createElement;
- var slots = this.slots;
- var showRightIcon = slots('right-icon') || this.rightIcon;
- if (showRightIcon) {
- return h("div", {
- "class": bem('right-icon'),
- "on": {
- "click": this.onClickRightIcon
- }
- }, [slots('right-icon') || h(_icon.default, {
- "attrs": {
- "name": this.rightIcon,
- "classPrefix": this.iconPrefix
- }
- })]);
- }
- },
- genWordLimit: function genWordLimit() {
- var h = this.$createElement;
- if (this.showWordLimit && this.maxlength) {
- var count = (this.value || '').length;
- return h("div", {
- "class": bem('word-limit')
- }, [h("span", {
- "class": bem('word-num')
- }, [count]), "/", this.maxlength]);
- }
- },
- genMessage: function genMessage() {
- var h = this.$createElement;
- if (this.vanForm && this.vanForm.showErrorMessage === false) {
- return;
- }
- var message = this.errorMessage || this.validateMessage;
- if (message) {
- var errorMessageAlign = this.getProp('errorMessageAlign');
- return h("div", {
- "class": bem('error-message', errorMessageAlign)
- }, [message]);
- }
- },
- getProp: function getProp(key) {
- if ((0, _utils.isDef)(this[key])) {
- return this[key];
- }
- if (this.vanForm && (0, _utils.isDef)(this.vanForm[key])) {
- return this.vanForm[key];
- }
- },
- genLabel: function genLabel() {
- var h = this.$createElement;
- var colon = this.getProp('colon') ? ':' : '';
- if (this.slots('label')) {
- return [this.slots('label'), colon];
- }
- if (this.label) {
- return h("span", [this.label + colon]);
- }
- }
- },
- render: function render() {
- var _bem;
- var h = arguments[0];
- var slots = this.slots;
- var disabled = this.getProp('disabled');
- var labelAlign = this.getProp('labelAlign');
- var scopedSlots = {
- icon: this.genLeftIcon
- };
- var Label = this.genLabel();
- if (Label) {
- scopedSlots.title = function () {
- return Label;
- };
- }
- var extra = this.slots('extra');
- if (extra) {
- scopedSlots.extra = function () {
- return extra;
- };
- }
- return h(_cell.default, {
- "attrs": {
- "icon": this.leftIcon,
- "size": this.size,
- "center": this.center,
- "border": this.border,
- "isLink": this.isLink,
- "required": this.required,
- "clickable": this.clickable,
- "titleStyle": this.labelStyle,
- "valueClass": bem('value'),
- "titleClass": [bem('label', labelAlign), this.labelClass],
- "arrowDirection": this.arrowDirection
- },
- "scopedSlots": scopedSlots,
- "class": bem((_bem = {
- error: this.showError,
- disabled: disabled
- }, _bem["label-" + labelAlign] = labelAlign, _bem['min-height'] = this.type === 'textarea' && !this.autosize, _bem)),
- "on": {
- "click": this.onClick
- }
- }, [h("div", {
- "class": bem('body')
- }, [this.genInput(), this.showClear && h(_icon.default, {
- "attrs": {
- "name": "clear"
- },
- "class": bem('clear'),
- "on": {
- "touchstart": this.onClear
- }
- }), this.genRightIcon(), slots('button') && h("div", {
- "class": bem('button')
- }, [slots('button')])]), this.genWordLimit(), this.genMessage()]);
- }
- });
- exports.default = _default;
|