smart-admin/rc-busness/components/addressInput.vue
2022-01-23 16:50:49 +08:00

524 lines
13 KiB
Vue

<template>
<div class="ts-area-picker-container">
<input class="ts-area-picker-value-displayer" placeholder="请选择收货地址" @focus="popAddress" v-model="displayValue"></input>
<input type="hidden" :value="returnValue">
<div class="ts-area-picker-desktop" v-if="show">
<div class="ts-area-picker-tmp-value">
<ul>
<li class="active" @click="switchTab(0)">{{ returnValueArr[0]?returnValueArr[0].name:'请选择' }}</li>
<li @click="switchTab(1)">{{ returnValueArr[1]?returnValueArr[1].name:'请选择' }}</li>
<li @click="switchTab(2)">{{ returnValueArr[2]?returnValueArr[2].name:'请选择' }}</li>
</ul>
<div class="close" @click="pcHideAddress"></div>
</div>
<div class="ts-area-picker-values">
<ul>
<li v-for="(item, index) in curDisplayingCol" :key="item.id" @click="pickValue(item.id,item.name)" v-bind:class="{ active:(returnValueArr[curDisplayingColIndex]?returnValueArr[curDisplayingColIndex].id==item.id:false) }">
<span>{{ item.name }}</span>
</li>
</ul>
</div>
</div>
<div class="ts-area-picker-mobile ts-mask" v-if="show">
<div class="ts-mask-bg"></div>
<van-picker
show-toolbar
title="选择地区"
:columns="columns"
value-key="name"
@confirm="onConfirm"
@cancel="onCancel"
@change="onChange"
class="ts-area-picker-mobile-component"
/>
</div>
</div>
</template>
<script>
import {
areaData
} from "~/config/area.js";
export default {
props:["defaultValues"],
data(){
return{
animationTimer:undefined,
displayValue:"",
returnValue:"",
returnValueArr:[],
show:false,
columns:areaData,
curDisplayingColIndex:0,
curDisplayingCol:[]
}
},
methods:{
initAddress(){
//Initilizing
// defaultValues : array[{id:"_ID_IN_columns_of_province",name:"_NAME_IN_columns"},{id:"_ID_IN_columns_of_city",name:"_NAME_IN_columns"},{id:"_ID_IN_columns_of_area",name:"_NAME_IN_columns"}]
let defaultValues = [{id:this.columns[0].values[0].id, name:this.columns[0].values[0].name},{id:this.columns[1].values[0].id, name:this.columns[1].values[0].name},{id:this.columns[2].values[0].id, name:this.columns[2].values[0].name}];
if(this.defaultValues && this.defaultValues.length>0)
{
defaultValues = this.defaultValues;
this.onConfirm(defaultValues);
} else {
this.defaultValues = defaultValues;
}
//Initilizing end
},
pickValue(pickId,pickName){
let areaObj={id:pickId,name:pickName};
console.log(pickId,pickName);
this.returnValueArr[this.curDisplayingColIndex]=areaObj;
this.validatePickedValues();
//Submit to value displaying
let tmpDisplayValueEle = document.querySelectorAll(".ts-area-picker-tmp-value li");
tmpDisplayValueEle[this.curDisplayingColIndex].innerText=this.returnValueArr[this.curDisplayingColIndex].name;
//Submit to value displaying end
//Moving to next tab
this.curDisplayingColIndex++;
if(this.curDisplayingColIndex>2 || this.curDisplayingColIndex<0)
this.curDisplayingColIndex = 0;
if(this.returnValueArr.length>=3)
{
this.onConfirm(this.returnValueArr);
}
else
this.switchTab(this.curDisplayingColIndex);
//Moving to next tab end
},
// For van picker
onChange(picker,values) { //values = [{id:this.columns[0].id, name:this.columns[0].name},{id:this.columns[1].id, name:this.columns[1].name},{id:this.columns[3].id, name:this.columns[3].name}];
//Support single choice only , index = 0 province, index = 1 city, index = 2 area
let curSelection={'province':'','city':'','area':''};
// console.log(picker,values);
this.$emit('getmenu',values)
this.$emit("closeDialog");
if(!values)
return;
let _self=this;
values.forEach(function(ele,index){
switch(index){
case 0:
//Handling Province
curSelection.province=ele.id;
//Handling Province end
break;
case 1:
//Handling City
let matchedCity=_self.fitlerValuesInArray(curSelection.province,_self.columns[index].values);
picker.setColumnValues(index,matchedCity);
if(_self.inArray(ele,matchedCity))
{
curSelection.city=ele.id;
}
else
{
console.log('502 : Invalid City Options');
curSelection.city=matchedCity[0].id;
}
//Handling City end
break;
default:
//Handling Area
let matchedArea=_self.fitlerValuesInArray(curSelection.city,_self.columns[index].values);
picker.setColumnValues(index,matchedArea);
if(_self.inArray(ele,matchedArea))
{
curSelection.area=ele.id;
}
else if(matchedArea.length)
{
console.log('503 : Invalid Area Options');
curSelection.area=matchedArea[0].id;
}
//Handling Area end
break;
}
});
},
inArray(needle,haystack){
if(!needle || !needle.id)
return false;
if(!haystack || haystack.length<haystack)
return false;
for(var i in haystack){
if(haystack[i].id==needle.id){
return i;
}
}
return false;
},
validatePickedValues(){
let _self=this;
let provinceId='';
let areaId=undefined;
let validatedIndex=-1;
this.returnValueArr.forEach(function(obj,index){
switch(index){
case 0:
//Skipping province checking
provinceId = obj.id;
validatedIndex = 0;
break;
case 1:
//Checking City
if(obj.id.toString().indexOf(provinceId)<0)
{
console.log('500 : error via checking validatePickedValues');
_self.returnValueArr.splice(index,1);
}
else
{
areaId = _self.returnValueArr[index].id;
validatedIndex=index;
}
//Checking City end
break;
case 2:
//Checking Area
if(areaId && obj.id.toString().indexOf(areaId)<0)
{
console.log('501 : error via checking validatePickedValues');
_self.returnValueArr.splice(index,1);
}
else{
validatedIndex=index;
}
//Checking Area end
break;
default:
break;
}
});
return validatedIndex;
},
onConfirm(values) {
//Get columns structure array here : values
let _self=this;
let returnVal=[];
let tmpArr = [];
this.displayValue='';
values.forEach(function(ele,index){
if(!ele || !ele.name)
{
ele={id:'',name:''};
}
_self.displayValue = _self.displayValue + ele.name + " ";
tmpArr.push(ele.id);
returnVal.push(ele);
});
this.returnValueArr=returnVal;
this.returnValue=tmpArr.join("|");
this.$emit('getmenu',this.returnValueArr);
this.hideAddress();
},
onCancel() {
},
fitlerValuesInArray(stringStartWith,dataColArea){
stringStartWith=stringStartWith+"-";
let result=[];
dataColArea.forEach(function(ele){
if(ele.id.toString().indexOf(stringStartWith)===0)
{
result.push(ele);
}
});
return result;
},
popAddress() {
this.show=true;
let _self=this;
//mobile
//const picker = this.selectComponent('.ts-area-picker-mobile-component');
if(this.defaultValues && this.defaultValues.length>0)
{
this.defaultValues.forEach(function(ele,index){
let tmpPointer=parseInt(_self.inArray(ele,_self.columns[index].values));
if(tmpPointer)
{
_self.columns[index].defaultIndex = tmpPointer;
}
});
}
// setTimeout(function(){
// //debugger;
// _self.$children.forEach(function(vueComponent){
// if(vueComponent._name=="<VanPicker>")
// {
// _self.onChange(vueComponent,_self.returnValueArr); //Important
// }
// });
// },500);
//mobile end
//PC
this.curDisplayingColIndex=0;
this.switchTab(this.curDisplayingColIndex);
//PC end
},
pcHideAddress() {
this.onConfirm(this.returnValueArr);
},
hideAddress() {
this.show=false;
},
switchTab(tabIndex){
let areaTabLi=document.querySelectorAll(".ts-area-picker-tmp-value li");
if(tabIndex==0){
this.curDisplayingCol = this.columns[tabIndex].values;
}
//Check can switch to next tab
let lastValidatedTabIndex=this.validatePickedValues();
if(lastValidatedTabIndex<(tabIndex-1))
{
let errorEle=document.querySelector(".ts-area-picker-values");
errorEle.classList.add("error");
let _self = this;
if(!this.animationTimer)
{
this.animationTimer = setTimeout(function(){
errorEle.classList.remove("error");
clearTimeout(_self.animationTimer);
_self.animationTimer=undefined;
},2000);
}
tabIndex=lastValidatedTabIndex+1;
}
//Check can switch to next tab end
//Building column values for current
this.curDisplayingColIndex=tabIndex;
let filteredData=this.columns[tabIndex].values;
if(tabIndex>0 && this.returnValueArr[tabIndex-1]) //pass
{
let pickedId = this.returnValueArr[tabIndex-1].id;
filteredData=this.fitlerValuesInArray(pickedId,this.columns[tabIndex].values);
}
this.curDisplayingCol=filteredData;
if(this.curDisplayingCol && this.curDisplayingCol.length<=0)
{
this.onConfirm(this.returnValueArr);
}
//Building column values for current end
//Filling style
areaTabLi.forEach(function(ele,index){
if(tabIndex==index){
ele.classList.add('active');
}
else
ele.classList.remove('active');
})
//Filling style end
}
},
mounted(){
this.initAddress();
},
components:{
},
}
</script>
<style lang="less" scoped>
.ts-area-picker-container{display:inline-block;position:relative;}
.ts-area-picker-value-displayer{
}
.ts-area-picker-tmp-value{
border-bottom:1px solid #D7D7D7;
padding:0;
box-sizing: border-box;
position:relative;
ul{
padding:0;
margin:0;
display: flex;
li{
display:inline-block;
color:#333333;
width:8rem;
padding: 1.25rem 0;
margin-right:.75rem;
cursor: pointer;
text-align: center;
&.active{
color:#E2001A;
border-bottom:4px solid #E2001A;
}
}
}
.close{
position:absolute;
position: absolute;
right: 3rem;
top: 1.5rem;
cursor: pointer;
&:before,&:after{
background-color: #333;
}
}
}
.ts-area-picker-values{
width:100%;
height:78%;
overflow:auto;
&.error{
position:relative;
width:100%;
height:78%;
&:after{
content: " ";
position:absolute;
width:100%;
height:100%;
left:0;
top:0;
animation-name: flash-error;
animation-iteration-count: 2;
animation-duration: .5s;
animation-direction: forwards;
}
}
ul{
padding:1rem .5rem 2rem 2.5rem;
margin:0;
}
li{
display:inline-block;
margin-top:1rem;
margin-right:.875rem;
color:#333;
width:8rem;
cursor:pointer;
&:nth-child(4n){
margin-right:0;
}
&.active{
color:#E2001A;
span{
display:inline-block;
border-bottom: 4px solid #E2001A;
}
}
}
}
/deep/.van-picker__confirm,.close{
text-indent:-999rem;
position:relative;
&:after{
transform: rotate(45deg);
}
&:before{
transform: rotate(-45deg);
}
&:before,
&:after {
position: absolute;
content: ' ';
background-color: #E1001A;
left: 1.25rem;
bottom:-0.875rem;
width: 1px;
height: 1.375rem;
}
}
@media screen and (max-width:768px)
{
/deep/.van-picker__cancel
{
display:none;
}
/deep/.van-picker__title{
font-size:1.375rem;
color:#E1001A;
}
/deep/.van-picker__toolbar{
padding:1.5rem 1.25rem;
box-sizing: border-box;
border-bottom:1px solid #D8D8D8;
}
/deep/.van-picker__confirm{
display:block;
}
.ts-area-picker-container { width:100%; }
.ts-area-picker-value-displayer {
border: none;
border-bottom: 1px solid #808285;
color: #999999;
font-size: 16px;
margin-left: 2px;
width:100%;
padding-bottom:.5rem;
background:url("../assets/image/ico-location.png") no-repeat 98% center;
background-size:16px;
position:relative;
top:.45rem;
padding-left:.875rem;
}
.ts-area-picker-mobile{
display:flex;
flex-direction: column;
justify-content: flex-end;
.ts-area-picker-mobile-component{
height:40vh;
width:100%;
}
}
.ts-area-picker-desktop{
display:none;
}
}
@media screen and (min-width:769px)
{
/deep/.van-picker__confirm{
display:none;
}
.ts-area-picker-mobile{
display:none;
}
.ts-area-picker-container,.ts-area-picker-value-displayer{
width:42.25rem;
}
.ts-area-picker-value-displayer{
padding-left:1rem;
height:2.8rem;
background:url("../assets/image/arr-down.jpg") no-repeat 98% center;
background-size:20px;
border: 1px solid #808285;
}
.ts-area-picker-desktop{
position:absolute;
top:0;
left:0;
display:block;
width:100%;
height:19.25rem;
border:1px solid #808285;
overflow:hidden;
background:#fff;
z-index:1;
}
}
@keyframes flash-error
{
from {
opacity:0;
background-color:#fff;
}
to {
opacity:.3;
background-color:#E2001A;
}
}
</style>