Authored by 姜枫

mrege from develop

... ... @@ -100,16 +100,6 @@
<p class="title">9. 分页组件</p>
<div style="border: 1px solid #000; height: 200px; padding: 5px;">
<pre>
全局安装json-server
npm i -g json-server
启动
json-server --watch mock/address.json
</pre>
{{{ pagination paginationOpts }}}
</div>
... ... @@ -161,6 +151,7 @@
<p style="margin-top: 20px;">14. 区域/选择地址组件</p>
<div style="padding: 5px; height: 300px;">
<p>使用手册详见yohoblk/public/js/plugins/README.md</p>
<div id="address"></div>
</div>
... ...
... ... @@ -71,6 +71,7 @@ change.click(function() {
// check
$('.input-radio').check({
type: 'radio',
group: 'gender',
onChange: function(ele, checked, value) {
$('.check-msg').html((checked ? '选中' : '取消选中') + ': ' + value);
}
... ... @@ -78,8 +79,11 @@ $('.input-radio').check({
$('.input-checkbox').check({
type: 'checkbox',
onChange: function(ele, checked, value) {
$('.check-msg').html((checked ? '选中' : '取消选中') + ': ' + value);
group: 'gender2',
onChange: function() {
var checked = $('.input-checkbox').check('getChecked');
$('.check-msg').html('选中: ' + JSON.stringify(checked.values));
}
});
... ...
### 组件使用手册
1. 地址选择组件
全局安装json-server模拟服务端返回数据
npm i -g json-server
启动
json-server --watch mock/address.json
API使用:
var address = cascadingAddress({
el: '#address',
url: 'http://localhost:3000/areas/0',
resource: 'areas'
});
获取选择地址文本:
address.getAreaLabels()
获取选择地址areaId:
address.getAreaIds()
设置地址:
address.setAddress({
province: '32', // 省
city: '3201', // 市
dist: '320102' // 区县
});
开发者: 董金虎
... ...
... ... @@ -78,6 +78,14 @@ function toggleDistItem() {
}
}
// 设置请求URL
function setRequestUrl(config, areaId) {
var urlArr = config.url.split(config.resources + '/');
urlArr[1] = areaId;
return urlArr.join(config.resources + '/');
}
// 重置下一级文本显示和值
function resetNextLevel(level, config) {
$('#level_' + level + '_panel').empty()
... ... @@ -88,23 +96,57 @@ function resetNextLevel(level, config) {
.next().val('');
}
// 选择特定省份,城市,或区县
function selectDistItem(options) {
var level = options.level, // 当前级别
distElement = options.target, // 选择特定项
currAreaId = distElement.attr('id').split('_')[1], // 当前选择areaId
distItem = $('#level_' + level + '_panel').prev(), // 请选择...
currPanel = options.panel, // 当前区域列表项
distItemAreaId = options.distItemAreaId, // 当前选中areaId
config = options.config;
if (distElement.hasClass('checked')) {
// TODO
// distElement.removeClass('checked');
} else {
currPanel.find('span.checked').removeClass('checked').prev().hide();
distElement.addClass('checked').prev().show();
distItem.find('.indicator-name')
.html(distElement.text())
.next()
.val(currAreaId);
// 填充下一级
if (level < 0) {
level = distElement.parents('.items-panel').attr('id').split('_')[1];
}
config.url = setRequestUrl(config, currAreaId);
// 选择之后关闭当前panel
// distItem.trigger('click');
// 当前点击的和已选择的不同,再渲染下一级目录
if (level && distItemAreaId !== currAreaId) {
resetNextLevel(level - 1, config);
$(config.el).trigger('ca.afterInit', [config, level - 1]);
}
}
}
// 获取初始化数据
function fetchInitialData(evt, config, level) {
var distItem, // 请选择...
distItemAreaId = $('.items-indicator .open input').val(),
var distItemAreaId = $('.items-indicator .open input').val(),
ajaxSettings = $.extend({}, config.ajaxSettings, {
url: config.url
});
var ulElement = $('<ul/>'),
liElement,
distElement;
liElement;
var urlArr;
// 当前选中区域id
var currAreaId,
currPanel;
// 当前选中区域列表
var currPanel;
$.ajax(ajaxSettings).done(function(res) {
// 渲染后台区域信息列表
... ... @@ -130,40 +172,85 @@ function fetchInitialData(evt, config, level) {
// 选择区域
currPanel.off('click', '.dist-name').on('click', '.dist-name', function() {
distElement = $(this);
currAreaId = distElement.attr('id').split('_')[1];
distItem = $('#level_' + level + '_panel').prev();
selectDistItem({
level: level,
target: $(this),
panel: currPanel,
distItemAreaId: distItemAreaId,
config: config
});
});
}).fail(function() {
// 如果出错,将下级所有都重置
var from = level;
while (from >= 0) {
resetNextLevel(from, config);
from--;
}
});
}
// 设置地址
function setAddress(evt, config, level, areaId) {
var ajaxSettings = $.extend({}, config.ajaxSettings, {
url: config.url
}),
liElement,
ulElement = $('<ul/>'),
currPanel,
label,
distVal,
distItemAreaId = $('.items-indicator .open input').val();
$.ajax(ajaxSettings).done(function(res) {
$(res.data).each(function(index, item) {
liElement = $('<li/>');
if (distElement.hasClass('checked')) {
// TODO
// distElement.removeClass('checked');
// 设置目标区域check状态
if (item.value === areaId) {
label = item.text;
distVal = item.value;
$('<span class="check-icon iconfont" style="display: inline;">&#xe60b;</span>').appendTo(liElement);
$('<span/>', {
class: 'dist-name checked',
title: label,
text: label,
id: 'area_' + item.value
}).appendTo(liElement);
} else {
currPanel.find('span.checked').removeClass('checked').prev().hide();
distElement.addClass('checked').prev().show();
distItem.find('.indicator-name')
.html(distElement.text())
.next()
.val(currAreaId);
// 填充下一级
if (level < 0) {
level = distElement.parents('.items-panel').attr('id').split('_')[1];
}
urlArr = config.url.split(config.resources + '/');
urlArr[1] = currAreaId;
config.url = urlArr.join(config.resources + '/');
// 选择之后关闭当前panel
// distItem.trigger('click');
// 当前点击的和已选择的不同,再渲染下一级目录
if (level && distItemAreaId !== currAreaId) {
resetNextLevel(level - 1, config);
$(config.el).trigger('ca.afterInit', [config, level - 1]);
}
$('<span class="check-icon iconfont">&#xe60b;</span>').appendTo(liElement);
$('<span/>', {
class: 'dist-name',
title: item.text,
text: item.text,
id: 'area_' + item.value
}).appendTo(liElement);
}
liElement.appendTo(ulElement);
ulElement.appendTo($(config.el).find('#level_' + level + '_panel').empty().removeClass('empty'));
});
// 设置label文本 和 设置areaId
currPanel = $('#level_' + level + '_panel');
currPanel.prev().find('.indicator-name').text(label)
.next().val(distVal);
// 侦听选择
currPanel.off('click', '.dist-name').on('click', '.dist-name', function() {
selectDistItem({
level: level,
target: $(this),
panel: currPanel,
distItemAreaId: distItemAreaId,
config: config
});
});
}).fail(function() {
// 如果出错,将下级所有都重置
var from = level;
... ... @@ -185,6 +272,7 @@ function CascadingAddress(options) {
element.on('ca.afterInit', fetchInitialData);
element.on('click', '.dist-item', toggleDistItem);
element.on('ca.setAddr', setAddress);
// 绑定自定义事件处理
$.each(widget.config, function(key, value) {
... ... @@ -274,6 +362,83 @@ CascadingAddress.prototype.init = function() {
el.trigger('ca.onCreated');
};
// 获取地址文本
CascadingAddress.prototype.getAreaLabels = function() {
var el = $(this.config.el),
result = [];
el.find('.indicator-name').each(function() {
if ($(this).next().val() !== '') {
result.push($(this).text());
}
});
return result.join(',');
};
// 获取地址ID
CascadingAddress.prototype.getAreaIds = function() {
var el = $(this.config.el),
result = [],
target;
el.find('input').each(function() {
target = $(this);
if (target.val() !== '') {
result.push($(this).val());
}
});
if (result.length) {
return result.join(',');
} else {
return '';
}
};
// 设置区域
// {
// "province": "32",
// "city": "3201",
// "dist": "320102"
// }
CascadingAddress.prototype.setAddress = function(targetAddr) {
var key,
distIds = ['0'], // 省份请求areaId=0
distLen,
cursor, // 游标
currentLevels = $('.items-indicator>li').length, // 目前存在几级
areaId, // 请求areaId
defaultId, // 设置areaId
config = this.config,
$el = $(config.el);
if (typeof targetAddr === 'object') {
for (key in targetAddr) {
if (targetAddr.hasOwnProperty(key)) {
distIds.push(targetAddr[key]);
}
}
// 标识需要渲染几级
distLen = distIds.sort().length;
cursor = distLen;
// 最后一个level是0
while (distLen > 1) {
// 请求从array[0], 判断值从array[1]
areaId = distIds[cursor - distLen];
defaultId = distIds[cursor - distLen + 1];
config.url = setRequestUrl(config, areaId);
$el.trigger('ca.setAddr', [config, currentLevels - 1, defaultId]);
distLen--;
currentLevels--;
}
} else {
console.error('target address must be a json object');
}
};
module.exports = function(options) {
return new CascadingAddress(options);
};
... ...
... ... @@ -5,11 +5,13 @@ var jQuery = require('yoho-jquery');
var defaultsHtml = {
radio: {
uncheckedHtml: '&#xe604;',
checkedHtml: '&#xe603;'
checkedHtml: '&#xe603;',
single: true
},
checkbox: {
uncheckedHtml: '&#xe601;',
checkedHtml: '&#xe602;'
checkedHtml: '&#xe602;',
single: false
}
};
... ... @@ -25,24 +27,50 @@ var jQuery = require('yoho-jquery');
options = $.extend({}, defaults, defaultsHtml[type], options);
if (options.group) {
$(this).addClass('check-group-' + options.group);
}
$(this).data('options', options);
$(this).off().on('click', function() {
var icon = $(this).find('.' + options.type);
var icon = $(ele).find('.' + options.type);
var checked = $(icon).hasClass('checked');
if (checked) {
$(icon).removeClass('checked');
$(icon).html(options.uncheckedHtml);
if (options.group) {
if (options.single) {
if (!checked) {
check.unCheckGroup(ele, options);
check.doChange(checked, ele, options);
}
} else {
check.doChange(checked, ele, options);
}
} else {
$(icon).addClass('checked');
$(icon).html(options.checkedHtml);
check.doChange(checked, ele, options);
}
if (typeof options.onChange === 'function') {
options.onChange(ele, !checked, $(ele).data('value'));
}
});
},
doChange: function(checked, ele, options) {
var icon = $(ele).find('.' + options.type);
if (checked) {
$(icon).removeClass('checked');
$(icon).html(options.uncheckedHtml);
} else {
$(icon).addClass('checked');
$(icon).html(options.checkedHtml);
}
if (typeof options.onChange === 'function') {
options.onChange(ele, !checked, $(ele).data('value'));
}
},
unCheckGroup: function(ele, options) {
var groupClass = 'check-group-' + options.group;
check.unCheckAll.call($('.' + groupClass));
},
checkAll: function() {
$(this).each(function() {
var options = $(this).data('options');
... ... @@ -57,6 +85,23 @@ var jQuery = require('yoho-jquery');
check._unCheck(this, options);
});
},
getChecked: function() {
var checkedEle = [];
var checkedValues = [];
$(this).each(function() {
var options = $(this).data('options');
if ($('.' + options.type, this).hasClass('checked')) {
checkedEle.push(this);
checkedValues.push($(this).data('value'));
}
});
return {
documents: checkedEle,
values: checkedValues
};
},
_check: function(ele, options) {
var icon = $(ele).find('.' + options.type);
var checked = $(icon).hasClass('checked');
... ...