Authored by yyq

地址三级联动

... ... @@ -6,13 +6,30 @@
'use strict';
const _ = require('lodash');
const pinyin = require('pinyin');
const crypto = global.yoho.crypto;
const addressApi = require('../models/address-api');
const worldSort = 'abcdefghtjklmnopqrstuvwxyz';
const getAreaListData = (id) => {
return addressApi.getAreaListAsync(id);
return addressApi.getAreaListAsync(id).then(result => {
let list = _.get(result, 'data', []);
if (id * 1 === 0 && list.length) {
_.forEach(list, value => {
value.initial = _.get(pinyin(value.caption, {
style: pinyin.STYLE_FIRST_LETTER
}), '[0][0]', 'w');
value.pySort = _.indexOf(worldSort, value.initial);
});
result.data = list;
}
return result;
});
};
const getAddressListData = (uid) => {
... ...
... ... @@ -2,48 +2,59 @@
<script id="address-tpl" type="text/html">
<div class="title">\{{title}}</div>
<p class="prompt">电话为选填项,其他均为必填项</p>
<p class="prompt">\{{title}}、电话为选填项,其他均为必填项</p>
<ul class="info-wrap">
<li>
<span class="left-rd"><i class="red">*</i>收货人:</span>
<input type="text" name="consignee" value="\{{name}}" placeholder="请输入您的姓名">
<span class="caveat-tip"></span>
<p class="caveat-tip"></p>
</li>
<li>
<span class="left-rd"><i class="red">*</i>所在区域:</span>
<div class="area-box">
<select class="province">
<option value="0">请选择省</option>
</select>
<select class="city">
<option value="0">请选择市</option>
</select>
<select class="country">
<option value="0">请选择县</option>
</select>
<span>请选择省市区</span>
<span class="area-text"></span>
<div class="area-select">
<ul class="clearfix">
<li class="area-sel-tab tab-on">
省份
<div class="province-list opt-list"></div>
</li>
<li class="area-sel-tab">
城市
<div class="city-list opt-list">
</div>
</li>
<li class="area-sel-tab">
区县
<div class="area-list opt-list">
</div>
</li>
</ul>
</div>
</div>
<span>注:标“*”的为支持加急送的地区</span>
<span class="caveat-tip"></span>
<p class="caveat-tip"></p>
</li>
<li>
<span class="left-rd"><i class="red">*</i>详细地址:</span>
<input type="text" name="address" value="\{{name}}" placeholder="街道名称或小区名称">
<span class="caveat-tip"></span>
<p class="caveat-tip"></p>
</li>
<li>
<span class="left-rd"><i class="red">*</i>手机号码:</span>
<input type="text" name="mobile" value="\{{name}}" placeholder="请输入手机号码(重要必填)">
<span class="caveat-tip"></span>
<p class="caveat-tip"></p>
</li>
<li>
<span class="left-rd">电话号码:</span>
<input type="text" name="tel" value="\{{name}}" placeholder="请输入电话号码(选填)">
<span class="caveat-tip"></span>
<p class="caveat-tip"></p>
</li>
<li>
<span class="left-rd"></span>
<label class="radio-btn">设置为默认收货地址</label>
</li>
</ul>
</script>
... ...
... ... @@ -55,6 +55,7 @@
"passport-sina": "^0.1.0",
"passport-strategy": "1.x.x",
"passport-weixin": "^0.1.0",
"pinyin": "^2.8.0",
"request-ip": "^1.2.2",
"request-promise": "^3.0.0",
"serve-favicon": "^2.3.0",
... ...
... ... @@ -6,6 +6,7 @@
var $ = require('yoho-jquery');
var hbs = require('yoho-handlebars');
var area = require('./areaSelect');
var dialog = require('../../common/dialog');
var Dialog = dialog.Dialog;
... ... @@ -142,8 +143,6 @@ function newEditAddress(info) {
}
console.log(data);
// window.open(myCouponUrl);
}
}, {
id: 'cancel',
... ... @@ -152,6 +151,7 @@ function newEditAddress(info) {
}]
}).show();
area.init(addDia.$el, 0);
bindOperateEvent(addDia.$el);
}
... ...
/**
* 三级地址联动
* @author: yyq<yanqing.yang@yoho.cn>
* @date: 2016/12/22
*/
var $ = require('yoho-jquery');
var areaSelect = {
init: function($el, area) {
this.$el = $el;
this.$areaText = $el.find('.area-text');
this.$provinceList = $el.find('.province-list');
this.$cityList = $el.find('.city-list');
this.$areaList = $el.find('.area-list');
this.bindEvent();
this.getAreaList(area || 0);
},
bindEvent: function() {
var that = this;
this.$el.on('click', '.area-sel-tab', function(event) {
var $this = $(event.target);
if (!$this.hasClass('area-sel-tab') || $this.hasClass('tab-on')) {
return;
}
$this.siblings('.area-sel-tab').removeClass('tab-on');
$this.addClass('tab-on');
}).on('click', '.area-box > span', function() {
that.$areaText.addClass('on-edit');
});
this.$provinceList.on('click', 'span', function() {
var $this = $(this),
data = $this.data();
if ($this.hasClass('on')) {
return;
}
that.$provinceList.find('.on').removeClass('on');
$this.addClass('on');
that.setOptionList('city');
that.setOptionList('area');
that.getAreaList(data.id || 0);
that.province = data;
that.$areaText.text(data.text || '');
});
this.$cityList.on('click', 'span', function() {
var $this = $(this),
data = $this.data();
if ($this.hasClass('on')) {
return;
}
$this.siblings('.on').removeClass('on');
$this.addClass('on');
that.setOptionList('area');
that.getAreaList(data.id || 0);
that.city = data;
that.$areaText.text((that.province.text || '') + ' / ' + (data.text || ''));
});
this.$areaList.on('click', 'span', function() {
var $this = $(this),
data = $this.data();
that.$areaText.removeClass('on-edit');
if ($this.hasClass('on')) {
return;
}
$this.siblings('.on').removeClass('on');
$this.addClass('on');
that.area = data;
that.$areaText.text((that.province.text || '') + ' / ' + (that.city.text || '') +
' / ' + (data.text || ''));
});
},
getAreaList: function(id, select) {
var that = this;
if (id === 0 && this.provinceGroup) {
return this.setOptionList('province', this.provinceGroup, select);
}
$.ajax({
type: 'GET',
url: '/cart/address/area',
data: {
id: id
}
}).then(function(data) {
var info = data.data,
type = 'province';
var i, idString;
if (data.code !== 200) {
return;
}
idString = id.toString();
if (idString.length === 2) {
type = 'city';
} else if (idString.length === 4) {
type = 'area';
}
info = data.data;
if (id === 0) {
that.provinceGroup = {
'A-G': [],
'H-K': [],
'L-S': [],
'T-Z': []
};
for (i = 0; i < info.length; i++) {
if (info[i].pySort < 7) {
that.provinceGroup['A-G'].push(info[i]);
} else if (info[i].pySort < 11) {
that.provinceGroup['H-K'].push(info[i]);
} else if (info[i].pySort < 19) {
that.provinceGroup['L-S'].push(info[i]);
} else {
that.provinceGroup['T-Z'].push(info[i]);
}
}
return that.setOptionList(type, that.provinceGroup, select);
}
return that.setOptionList(type, info, select);
});
},
setOptionList: function(type, data) {
var _h = '', i, j;
if (type === 'province') {
data = data || {};
for (i in data) {
if (data.hasOwnProperty(i)) {
_h += '<p><label class="group-title">' + i + '</label>';
for (j = 0; j < data[i].length; j++) {
_h += '<span class="ai-' + data[i][j].id + '" data-id="' + data[i][j].id +
'" data-text="' + data[i][j].caption + '">' +
(data[i][j].is_support_express === 'Y' ? '*' : '') + data[i][j].caption + '</span>';
}
_h += '</p>';
}
}
this.$provinceList.html(_h);
} else {
data = data || [];
for (j = 0; j < data.length; j++) {
_h += '<span class="ai-' + data[j].id + '" data-id="' + data[j].id +
'" data-text="' + data[j].caption + '">' +
(data[j].is_support_express === 'Y' ? '*' : '') + data[j].caption + '</span>';
}
if (type === 'city') {
this.city = {};
this.$cityList.html(_h);
} else {
this.area = {};
this.$areaList.html(_h);
}
}
}
};
module.exports = areaSelect;
... ...
... ... @@ -517,35 +517,41 @@
}
.ope-address-dialog {
width: 610px;
height: 410px;
$red: #d0021b;
width: 450px;
height: 460px;
text-align: left;
font-size: 14px;
color: #444;
background-color: #fff;
> .close {
display: none;
}
top: 10px;
right: 12px;
.iconfont {
font-size: 32px;
}
}
> .content {
text-align: left;
}
.title {
padding-bottom: 26px;
font-size: 18px;
padding-bottom: 10px;
border-bottom: 1px solid #e8e8e8;
}
.prompt {
line-height: 54px;
font-size: 12px;
color: #444;
}
.info-wrap {
font-size: 12px;
color: #aaa;
.radio-btn {
font-size: 14px;
color: #444;
&:before {
... ... @@ -566,18 +572,18 @@
}
}
li {
padding-bottom: 20px;
> li {
padding-bottom: 30px;
input {
width: 180px;
border: 1px solid #e8e8e8;
width: 208px;
border: 1px solid #b0b0b0;
padding: 5px;
margin-right: 10px;
}
input[name="address"] {
width: 270px;
width: 330px;
}
}
... ... @@ -596,9 +602,11 @@
.caveat-tip {
color: #ce0b24;
display: none;
position: absolute;
padding-left: 94px;
line-height: 1.5;
&:before {
/* &:before {
content: '';
width: 16px;
height: 16px;
... ... @@ -607,23 +615,118 @@
display: inline-block;
position: relative;
top: 4px;
}
}*/
}
.area-box {
width: 340px;
height: 26px;
display: inline-block;
border: 1px solid #e8e8e8;
border: 1px solid #b0b0b0;
background: #fff;
padding-right: 3px;
margin-right: 10px;
vertical-align: middle;
position: relative;
z-index: 1;
> span {
width: 98%;
font-size: 12px;
line-height: 26px;
padding-left: 5px;
display: inline-block;
cursor: pointer;
}
.area-text {
width: 98%;
background: #fff;
color: #444;
position: absolute;
left: 0;
top: 0;
}
}
.area-select {
width: 100%;
position: absolute;
left: -1px;
background-color: #fff;
border: 1px solid #b0b0b0;
display: none;
li {
width: 112px;
float: left;
line-height: 26px;
color: #999;
border-left: 1px solid #e0e0e0;
background-color: #f8f8f8;
text-align: center;
cursor: pointer;
}
> select {
width: 90px;
height: 26px;
li:first-child {
width: 114px;
border: 0;
background: none;
color: #aaa;
}
.opt-list {
width: 100%;
position: absolute;
left: -1px;
background: #fff;
border: 1px solid #b0b0b0;
padding: 10px 0;
text-align: left;
display: none;
color: #444;
> p {
padding-left: 60px;
}
.group-title {
position: absolute;
left: 20px;
}
span {
display: inline-block;
padding: 4px 6px;
margin: 0 5px;
line-height: 1;
cursor: pointer;
}
.on {
background-color: $red;
color: #fff;
}
}
}
.on-edit + .area-select {
display: block;
}
.area-select .tab-on {
background-color: #fff;
color: $red;
&:after {
content: '';
width: 100%;
height: 4px;
background-color: #fff;
display: block;
position: relative;
top: -2px;
}
.opt-list {
display: block;
}
}
}
... ...