import { use, isObj } from '../utils'; import { isMobile } from '../utils/validate/mobile'; import Area from '../area'; import Field from '../field'; import Popup from '../popup'; import Toast from '../toast'; import Button from '../button'; import Dialog from '../dialog'; import Detail from './Detail'; import SwitchCell from '../switch-cell'; const [sfc, bem, t] = use('address-edit'); const defaultData = { name: '', tel: '', country: '', province: '', city: '', county: '', areaCode: '', postalCode: '', addressDetail: '', isDefault: false }; export default sfc({ props: { areaList: Object, isSaving: Boolean, isDeleting: Boolean, validator: Function, showDelete: Boolean, showPostal: Boolean, searchResult: Array, showSetDefault: Boolean, showSearchResult: Boolean, saveButtonText: String, deleteButtonText: String, showArea: { type: Boolean, default: true }, showDetail: { type: Boolean, default: true }, detailRows: { type: Number, default: 1 }, addressInfo: { type: Object, default: () => ({ ...defaultData }) }, telValidator: { type: Function, default: isMobile }, areaColumnsPlaceholder: { type: Array, default: () => [] } }, data() { return { data: {}, showAreaPopup: false, detailFocused: false, errorInfo: { tel: false, name: false, postalCode: false, addressDetail: false } }; }, computed: { areaListLoaded() { return isObj(this.areaList) && Object.keys(this.areaList).length; }, areaText() { const { country, province, city, county, areaCode } = this.data; if (areaCode) { const arr = [country, province, city, county]; if (province && province === city) { arr.splice(1, 1); } return arr.filter(text => text).join('/'); } return ''; } }, watch: { addressInfo: { handler(val) { this.data = { ...defaultData, ...val }; this.setAreaCode(val.areaCode); }, deep: true, immediate: true }, areaList() { this.setAreaCode(this.data.areaCode); } }, methods: { onFocus(key) { this.errorInfo[key] = false; this.detailFocused = key === 'addressDetail'; this.$emit('focus', key); }, onChangeDetail(val) { this.data.addressDetail = val; this.$emit('change-detail', val); }, onAreaConfirm(values) { this.showAreaPopup = false; this.assignAreaValues(); this.$emit('change-area', values); }, assignAreaValues() { const { area } = this.$refs; if (area) { const detail = area.getArea(); detail.areaCode = detail.code; delete detail.code; Object.assign(this.data, detail); } }, onSave() { const items = ['name', 'tel', 'areaCode', 'addressDetail']; if (this.showPostal) { items.push('postalCode'); } const isValid = items.every(item => { const msg = this.getErrorMessage(item); if (msg) { this.errorInfo[item] = true; Toast(msg); } return !msg; }); if (isValid && !this.isSaving) { this.$emit('save', this.data); } }, getErrorMessage(key) { const value = String(this.data[key] || '').trim(); if (this.validator) { const message = this.validator(key, value); if (message) { return message; } } switch (key) { case 'name': return value ? '' : t('nameEmpty'); case 'tel': return this.telValidator(value) ? '' : t('telInvalid'); case 'areaCode': return value ? '' : t('areaEmpty'); case 'addressDetail': return value ? '' : t('addressEmpty'); case 'postalCode': return value && !/^\d{6}$/.test(value) ? t('postalEmpty') : ''; } }, onDelete() { Dialog.confirm({ title: t('confirmDelete') }) .then(() => { this.$emit('delete', this.data); }) .catch(() => { this.$emit('cancel-delete', this.data); }); }, // get values of area component getArea() { return this.$refs.area ? this.$refs.area.getValues() : []; }, // set area code to area component setAreaCode(code) { this.data.areaCode = code || ''; if (code) { this.$nextTick(this.assignAreaValues); } }, setAddressDetail(value) { this.data.addressDetail = value; }, onDetailBlur() { // await for click search event setTimeout(() => { this.detailFocused = false; }); } }, render(h) { const { data, errorInfo } = this; const onFocus = name => () => this.onFocus(name); // hide bottom field when use search && detail get focused const hideBottomFields = this.searchResult.length && this.detailFocused; return (