Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
TerryZ committed Nov 25, 2018
1 parent fe517ac commit d9b11b3
Show file tree
Hide file tree
Showing 12 changed files with 265 additions and 41 deletions.
2 changes: 1 addition & 1 deletion dist/v-region.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/v-region.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "v-region",
"description": "A simple region selector, provide Chinese administrative division data",
"version": "2.0.0",
"version": "2.1.0",
"author": "TerryZ <[email protected]>",
"license": "MIT",
"main": "dist/v-region.js",
Expand All @@ -10,7 +10,7 @@
"build": "cross-env NODE_ENV=production webpack --progress --hide-modules"
},
"dependencies": {
"v-dropdown": "^1.0.3",
"v-dropdown": "1.0.4",
"vue": "^2.5.11"
},
"keywords": [
Expand Down
198 changes: 198 additions & 0 deletions src/CityPicker.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
<template>
<div>
<div class="rg-caller-container" @click.stop.prevent="open" ref="caller">
<slot>
<!-- default region selector caller button -->
<button type="button" :class="['rg-default-btn', {'rg-opened': show}]">
{{selectedText?selectedText:lang.pleaseSelect}}
<span class="rg-iconfont icon-clear rg-clear-btn" :title="lang.clear" v-if="selectedText" @click.stop.prevent="clear"></span>
<span class="rg-caret-down" v-else></span>
</button>
</slot>
</div>
<v-drop-down ref="drop" @show-change="showChange" :re-open="false">
<!-- search bar -->
<div class="rg-search-bar" >
<input type="text" autocomplete="off" ref="input" v-model.trim="query" class="rg-input" placeholder="">
</div>
<div class="rg-picker">
<div class="rg-picker__row" v-for="item in list">
<dl>
<dt v-text="item.province.value"></dt>
<dd>
<ul>
<li v-for="city in item.citys"
@click="pick(city)"
:class="{selected: picked.includes(city)}"
v-text="city.value"></li>
</ul>
</dd>
</dl>
</div>
</div>
</v-drop-down>
</div>
</template>

<script>
import {srcProvince, srcCity} from "./region.js";
import selector from './mixins/selector';
import language from './language';
import dropDown from 'v-dropdown';
export default {
name: "CityPicker",
mixins: [selector],
inheritAttrs: false,
components: {
'v-drop-down': dropDown
},
props: {
selected: Array
},
data(){
return {
/**
* [{
* province: { key: '', value: ''},
* citys: [
* {key: '', value: ''},
* {key: '', value: ''},
* ...
* ]
* }]
*/
list: [],
listBuild: [],
query: '',
picked: [],
lang: {}
};
},
beforeMount(){
this.lang = language['cn'];
this.prepared();
this.list = this.listBuild.concat();
},
computed: {
selectedText(){
return this.picked.map(val=>val.value).join(',');
}
},
watch: {
/**
* region search
* search region description first, if no result, then search region key
* @param value
*/
query(value){
if(!value) this.list = this.listBuild.concat();
else{
let list = [];
this.list = this.listBuild.filter(val=>{
let citys = val.citys.filter(city=> city.value.includes(value));
if(citys.length) list.push({ province: val.province,citys: citys });
});
this.list = list;
}
},
/**
* initialize region selected
*/
selected(value){
if(value && Array.isArray(value) && value.length) {
let tmp = srcProvince.filter(val=> value.includes(val.key));
this.picked = [...tmp, ...srcCity.filter(val => value.includes(val.key))];
}
}
},
methods: {
prepared(){
//beijing, tianjin, shanghai, chongqing
const municipalitys = ['110000', '120000', '310000', '500000'], municipality = '000000',
//hongkong, macao
specials = ['810000', '820000'], special = '000010';
let listTmp = [],
municipalityObj = {
province: { key: municipality, value: '直辖市' },
citys: []
},
specialObj = {
province: { key: special, value: '特别行政区' },
citys: []
};
//set provinces
srcProvince.forEach(val=>{
if(municipalitys.includes(val.key)) municipalityObj.citys.push(val);
else if(specials.includes(val.key)) specialObj.citys.push(val);
else listTmp.push({ province: val,citys: [] });
});
listTmp.forEach(val=>{
val.citys = srcCity.filter(value=>{
let num = Number.parseInt(val.province.key);
return (value.key - num) < 1e4 && (value.key%num) < 1e4;
});
});
this.listBuild = [...[municipalityObj], ...listTmp, ...[specialObj]];
},
open(){
this.$refs.drop.$emit('show', this.$refs.caller);
this.inputFocus();
},
inputFocus(){
this.$nextTick(()=>{
//fix open drop down list and set input focus, the page will scroll to top
//that.$refs.search.focus({preventScroll:true}); only work on Chrome and EDGE
if(this.isChrome() || this.isEdge()) this.$refs.input.focus({preventScroll:true});
else{
let x = window.pageXOffset, y = window.pageYOffset;
this.$refs.input.focus();
if(window.pageYOffset !== y) setTimeout(function() { window.scrollTo(x, y); }, 0);
}
});
},
clear(){
this.picked.splice(0, this.picked.length);
this.close();
},
pick(item){
if(!this.picked.includes(item)) this.picked.push(item);
else this.picked.splice(this.picked.findIndex(val=>val.key === item.key), 1);
this.$emit('values', this.picked);
}
}
}
</script>

<style lang="scss">
div.rg-search-bar{
padding: 10px;
input.rg-input {
background-color: #fafafa;
&:focus{ background-color: white; }
}
}
div.rg-picker{
width: 400px;max-height: 340px;overflow-y: auto;padding: 0 0 0 10px;
div.rg-picker__row{
margin-bottom: 15px;clear: both;
dl{
margin: 0;padding: 0;overflow: hidden;
dt {
float: left;width: 60px;clear: left;text-align: right;
font-weight: bold;font-size: 14px;color: #888;
}
dd {
margin-left: 75px;font-size: 13px;color: #666;
ul {
margin: 0;padding: 0;list-style: none;
li {
margin-right: 10px;display: inline-block;cursor: pointer;
&.selected { color: #2A94EE;font-weight: bold; }
}
}
}
}
}
}
</style>
2 changes: 1 addition & 1 deletion src/ColumnGroup.vue
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
},
methods: {
open(){
this.$refs.drop.$emit('show', true, this.$refs.caller);
this.$refs.drop.$emit('show', this.$refs.caller);
},
provinceChange(newVal, oldVal){
this.baseProvinceChange(newVal, oldVal);
Expand Down
64 changes: 40 additions & 24 deletions src/Region.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,17 @@
<!-- select elements mode -->
<v-select-group v-if="!text && !ui" v-bind="$attrs" v-on="$listeners"></v-select-group>
<!-- selector mode -->
<v-tab-selector v-if="ui && !column" v-bind="$attrs" v-on="$listeners"></v-tab-selector>
<v-tab-selector v-if="ui && !column && !cityPicker" v-bind="$attrs" v-on="$listeners">
<slot></slot>
</v-tab-selector>
<!-- column group mode -->
<v-column-group v-if="ui && column" v-bind="$attrs" v-on="$listeners"></v-column-group>
<v-column-group v-if="ui && column && !cityPicker" v-bind="$attrs" v-on="$listeners">
<slot></slot>
</v-column-group>
<!-- city picker -->
<v-city-picker v-if="ui && !column && cityPicker" v-bind="$attrs" v-on="$listeners">
<slot></slot>
</v-city-picker>
</div>
</template>

Expand All @@ -16,13 +24,15 @@
import tabSelector from './TabSelector';
import columnGroup from './ColumnGroup';
import textRegion from './TextRegion';
import cityPicker from './CityPicker';
export default {
name: "v-region",
components: {
'v-select-group': selectGroup,
'v-text-region': textRegion,
'v-tab-selector': tabSelector,
'v-column-group': columnGroup
'v-column-group': columnGroup,
'v-city-picker': cityPicker
},
props:{
ui: {
Expand All @@ -36,6 +46,10 @@
text: {
type: Boolean,
default: false
},
cityPicker: {
type: Boolean,
default: false
}
},
mounted(){
Expand Down Expand Up @@ -154,32 +168,34 @@
div.rg-search {
padding: 2px 10px 10px;
background-color: $darkBg;
.rg-input {
display: block;
background-color: white;
margin: 0 !important;
width: 100%;
}
.rg-input {
display: block;
background-color: white;
margin: 0 !important;
width: 100%;
font-size: 14px;
line-height: 20px;
min-height: 20px;
padding: 4px 6px;
vertical-align: middle;
box-sizing: border-box;
font-size: 14px;
line-height: 20px;
min-height: 20px;
padding: 4px 6px;
vertical-align: middle;
box-sizing: border-box;
outline: none !important;
height: 30px;
outline: none !important;
height: 30px;
border-radius: 2px;
border: 1px solid #dddddd;
-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075);
-moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.075);
box-shadow: inset 0 1px 1px rgba(0,0,0,.075);
border-radius: 2px;
border: 1px solid #dddddd;
-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075);
-moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.075);
box-shadow: inset 0 1px 1px rgba(0,0,0,.075);
transition: border-color .15s ease-in-out,box-shadow .15s ease-in-out;
&:focus { border: 1px solid #bbbbbb;box-shadow: 0 0 0 3px rgba(150,150,150, 0.2); }
}
transition: border-color .15s ease-in-out,box-shadow .15s ease-in-out;
&:focus { border: 1px solid #bbbbbb;box-shadow: 0 0 0 3px rgba(150,150,150, 0.2); }
}
/* group type */
div.rg-level-tabs {
padding: 0 10px;border-bottom: 1px solid #E6E7E7;
Expand Down
5 changes: 3 additions & 2 deletions src/SelectElement.vue
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,11 @@
this.close();
},
open(){
if(!this.disabled) this.$refs.drop.$emit('show', true, this.$refs.caller);
if(!this.disabled) this.$refs.drop.$emit('show', this.$refs.caller);
},
close(){
this.$nextTick(()=>{
this.$refs.drop.$emit('show', false);
this.$refs.drop.$emit('show');
});
},
showChange(val){
Expand Down Expand Up @@ -133,6 +133,7 @@ ul.rg-select__list{
cursor: pointer;
min-width: 80px;
color: #888;
font-size: 13px;
&:hover{ background-color: #F5F7FA; }
&.selected{
background-color: #57A0E2;
Expand Down
8 changes: 1 addition & 7 deletions src/TabSelector.vue
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@
},
methods: {
open(){
this.$refs.drop.$emit('show', true, this.$refs.caller);
this.$refs.drop.$emit('show', this.$refs.caller);
this.inputFocus();
},
inputFocus(){
Expand Down Expand Up @@ -198,12 +198,6 @@
this.dProvince = null;
this.level = PROVINCE_LEVEL;
},
isChrome(){
return navigator.vendor !== undefined && navigator.vendor.indexOf("Google") !== -1;
},
isEdge(){
return navigator.userAgent.indexOf("Edge") >= 0;
},
provinceChange(newVal, oldVal){
this.baseProvinceChange(newVal, oldVal);
},
Expand Down
3 changes: 2 additions & 1 deletion src/mixins/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,8 @@ export default {
if(this.city && ini.city) count++;
if(this.area && ini.area) count++;
if(this.town && ini.town) count++;
if(level === count) this.init = null;
//level number start with 0
if((level + 1) === count) this.init = null;
}
return init;
},
Expand Down
Loading

0 comments on commit d9b11b3

Please sign in to comment.