mirror of
https://gitee.com/lab1024/smart-admin.git
synced 2025-10-02 02:06:38 +08:00
507 lines
12 KiB
Vue
507 lines
12 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);
|
|
}
|
|
//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.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.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.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');
|
|
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-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;
|
|
}
|
|
.ts-area-picker-value-displayer{
|
|
width: 258px;
|
|
height: 34px;
|
|
border: none;
|
|
border-bottom: 1px
|
|
solid #808285;
|
|
color: #999999;
|
|
font-size: 16px;
|
|
margin-left: 2px;
|
|
padding-left: 0;
|
|
}
|
|
}
|
|
@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:40rem;
|
|
}
|
|
.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;
|
|
}
|
|
}
|
|
@keyframes flash-error
|
|
{
|
|
from {
|
|
opacity:0;
|
|
background-color:#fff;
|
|
}
|
|
to {
|
|
opacity:.3;
|
|
background-color:#E2001A;
|
|
}
|
|
}
|
|
</style> |