2017-12-19 19:12:32 +08:00

275 lines
6.9 KiB
Vue

<template>
<div class="van-address-edit">
<cell-group>
<field
maxlength="15"
:placeholder="$t('placeholder.name')"
:label="$t('label.name', computedAddressText)"
v-model="currentInfo.name"
:error="errorInfo.name"
@focus="onFocus('name')"
/>
<field
type="tel"
:label="$t('label.tel')"
:placeholder="$t('placeholder.tel')"
v-model="currentInfo.tel"
:error="errorInfo.tel"
@focus="onFocus('tel')"
/>
<cell class="van-address-edit__area" :title="$t('areaTitle')" @click="showAreaSelect = true">
<span>{{ currentInfo.province || $t('placeholder.province') }}</span>
<span>{{ currentInfo.city || $t('placeholder.city') }}</span>
<span>{{ currentInfo.county || $t('placeholder.county') }}</span>
</cell>
<address-edit-detail
:value="currentInfo.address_detail"
:isError="errorInfo.address_detail"
:showSearchResult="showSearchResult"
:searchResult="searchResult"
@focus="onFocus('address_detail')"
@blur="onDetailBlur"
@input="onChangeDetail"
@select-search="$emit('select-search', $event)"
/>
<field
v-if="showPostal"
v-show="!hideBottomFields"
type="tel"
:label="$t('label.postal')"
:placeholder="$t('placeholder.postal')"
v-model="currentInfo.postal_code"
maxlength="6"
class="van-hairline--top"
:error="errorInfo.postal_code"
@focus="onFocus('postal_code')"
/>
<switch-cell
v-if="showSetDefault"
v-show="!hideBottomFields"
v-model="currentInfo.is_default"
:title="$t('defaultAddress', computedAddressText)"
/>
</cell-group>
<div v-show="!hideBottomFields" class="van-address-edit__buttons">
<van-button block :loading="isSaving" @click="onSaveAddress" type="primary">
{{ $t('save') }}
</van-button>
<van-button block :loading="isDeleting" @click="onDeleteAddress" v-if="isEdit">
{{ $t('deleteAddress', computedAddressText) }}
</van-button>
</div>
<popup v-model="showAreaSelect" position="bottom">
<van-area
ref="area"
:value="currentInfo.area_code"
:areaList="areaList"
@confirm="onAreaConfirm"
@cancel="showAreaSelect = false"
/>
</popup>
</div>
</template>
<script>
/* eslint-disable camelcase */
import { create } from '../utils';
import Field from '../field';
import Cell from '../cell';
import CellGroup from '../cell-group';
import VanButton from '../button';
import Popup from '../popup';
import Toast from '../toast';
import Dialog from '../dialog';
import VanArea from '../area';
import AddressEditDetail from './Detail';
import SwitchCell from '../switch-cell';
import validateMobile from '../utils/validate/mobile';
export default create({
name: 'van-address-edit',
components: {
Field,
Cell,
CellGroup,
SwitchCell,
VanButton,
Popup,
VanArea,
AddressEditDetail
},
props: {
isSaving: Boolean,
isDeleting: Boolean,
areaList: Object,
showPostal: Boolean,
showSetDefault: Boolean,
showSearchResult: Boolean,
addressText: String,
addressInfo: {
type: Object,
default: () => ({
name: '',
tel: '',
province: '',
city: '',
county: '',
area_code: '',
postal_code: '',
address_detail: '',
is_default: false
})
},
searchResult: {
type: Array,
default: () => []
}
},
data() {
return {
showAreaSelect: false,
currentInfo: this.addressInfo,
isEdit: !!this.addressInfo.id,
detailFocused: false,
errorInfo: {
name: false,
tel: false,
address_detail: false,
postal_code: false
}
};
},
watch: {
addressInfo: {
handler(val) {
this.currentInfo = val;
this.isEdit = !!val.id;
},
deep: true
}
},
computed: {
// hide bottom field when use search && detail get focused
hideBottomFields() {
return this.searchResult.length && this.detailFocused;
},
computedAddressText() {
return this.addressText || this.$t('addressText');
}
},
methods: {
onFocus(key) {
this.errorInfo[key] = false;
this.detailFocused = key === 'address_detail';
this.$emit('focus', key);
},
onDetailBlur() {
this.detailFocused = false;
},
onChangeDetail(val) {
this.currentInfo.address_detail = val;
this.$emit('change-detail', val);
},
onAreaConfirm(values) {
if (values.length !== 3 || +values[0].code === -1 || +values[1].code === -1 || +values[2].code === -1) {
return Toast(this.$t('areaWrong'));
}
this.assignAreaValues(values);
this.showAreaSelect = false;
this.$emit('change-area', values);
},
assignAreaValues(values) {
Object.assign(this.currentInfo, {
province: values[0].name,
city: values[1].name,
county: values[2].name,
area_code: values[2].code
});
},
onSaveAddress() {
const items = [
'name',
'tel',
'area_code',
'address_detail'
];
if (this.showPostal) {
items.push('postal_code');
}
const isValid = items.every(item => {
const msg = this.getErrorMessageByKey(item);
if (msg) {
this.errorInfo[item] = true;
Toast(msg);
}
return !msg;
});
if (isValid && !this.isSaving) {
this.$emit('save', this.currentInfo);
}
},
getErrorMessageByKey(key) {
const value = this.currentInfo[key];
const { $t } = this;
switch (key) {
case 'name':
return value ? value.length <= 15 ? '' : $t('nameOverlimit') : $t('nameEmpty');
case 'tel':
return validateMobile(value) ? '' : $t('telWrong');
case 'area_code':
return value ? +value !== -1 ? '' : $t('areaWrong') : $t('areaEmpty');
case 'address_detail':
return value ? value.length <= 200 ? '' : $t('addressOverlimit') : $t('addressEmpty');
case 'postal_code':
return value && !/^\d{6}$/.test(value) ? $t('postalEmpty') : '';
}
},
onDeleteAddress() {
if (this.isDeleting) {
return;
}
Dialog.confirm({
message: this.$t('confirmDelete', this.computedAddressText)
}).then(() => {
this.$emit('delete', this.currentInfo);
});
},
// get values of area component
getArea() {
const { area } = this.$refs;
return area ? area.getValues() : [];
},
// set area code to area component
setAreaCode(code) {
this.currentInfo.area_code = code;
this.$nextTick(() => {
const { area } = this.$refs;
if (area) {
this.assignAreaValues(area.getValues());
}
});
}
}
});
</script>