diff --git a/demo/MonthView.html b/demo/MonthView.html
index 01ca47e6..ef3ee8a3 100644
--- a/demo/MonthView.html
+++ b/demo/MonthView.html
@@ -306,7 +306,7 @@
不可用状态
var test1Ipt3 = document.getElementById('test1-ipt3');
test1Btn3.onclick = function() {
var range = test1Ipt3.value;
- multiMonthView.setProperties({
+ singleMonthView.setProperties({
range: range
});
}
diff --git a/demo/assets/themes/standard.css b/demo/assets/themes/standard.css
index 5cf03048..bc9a3200 100644
--- a/demo/assets/themes/standard.css
+++ b/demo/assets/themes/standard.css
@@ -3305,6 +3305,7 @@ span.ui-crumb-node {
display: inline-block;
}
.ui-rangecalendar-layer {
+ position: absolute;
background: #fbfbfb;
border-top: 3px solid #fbfbfb;
border-bottom: none;
diff --git a/src/MonthView.js b/src/MonthView.js
index e60c7c0a..fb5182c8 100644
--- a/src/MonthView.js
+++ b/src/MonthView.js
@@ -47,16 +47,11 @@ define(
* 默认选项配置
*/
var properties = {
- range: {
- begin: new Date(1982, 10, 4),
- end: new Date(2046, 10, 4)
- },
- dateFormat: 'YYYY-MM-DD',
- paramFormat: 'YYYY-MM-DD',
viewValue: {},
- mode: 'single'
+ mode: 'single',
+ dateItemRender: null
};
- u.extend(properties, options);
+ u.extend(properties, MonthView.defaultProperties, options);
this.setProperties(properties);
},
@@ -68,8 +63,12 @@ define(
* @protected
*/
setProperties: function (properties) {
+ var format = properties.paramFormat || this.paramFormat;
if (properties.range) {
- properties.range = rangeAdapter(properties.range);
+ properties.range = rangeAdapter(
+ properties.range,
+ format
+ );
}
// 如果么设置rawValue
@@ -79,7 +78,7 @@ define(
// 从value转
if (properties.value) {
properties.rawValue
- = parseValueByMode(properties.value, mode);
+ = parseValueByMode(properties.value, mode, format);
}
// 都没设
else {
@@ -141,6 +140,7 @@ define(
var changes
= Control.prototype.setProperties.apply(this, arguments);
+ // yankun:真的需要在这里触发change吗?
if (changes.hasOwnProperty('rawValue')) {
this.fire('change');
}
@@ -174,45 +174,55 @@ define(
var monthBack = this.getChild('monthBack');
monthBack.on(
'click',
- lib.curry(goToPrevMonth, this)
+ u.partial(goToPrevMonth, this)
);
// 向前按钮
var monthForward = this.getChild('monthForward');
monthForward.on(
'click',
- lib.curry(goToNextMonth, this)
+ u.partial(goToNextMonth, this)
);
// 月份选择
var monthSel = this.getChild('monthSel');
monthSel.on(
'change',
- lib.curry(changeMonth, this, monthSel)
+ u.partial(changeMonth, this, monthSel)
);
// 给layer人肉增加class命名空间
monthSel.on(
'layerrendered',
- lib.curry(addCustomClassesForSelectLayer, this, 'month-select')
+ u.partial(addCustomClassesForSelectLayer, this, 'month-select')
);
// 年份选择
var yearSel = this.getChild('yearSel');
yearSel.on(
'change',
- lib.curry(changeYear, this, yearSel)
+ u.partial(changeYear, this, yearSel)
);
yearSel.on(
'layerrendered',
- lib.curry(addCustomClassesForSelectLayer, this, 'year-select')
+ u.partial(addCustomClassesForSelectLayer, this, 'year-select')
);
var controlHelper = this.helper;
- // 为日期绑定点击事件
- var monthMain = controlHelper.getPart('monthMain');
- controlHelper.addDOMEvent(monthMain, 'click', monthViewClick);
+ var selectors = [
+ '.' + controlHelper.getPartClassName('month-item'),
+ '.' + controlHelper.getPartClassName('month-select-all'),
+ '.' + controlHelper.getPartClassName('month-title'),
+ '.' + controlHelper.getPartClassName('month-row-select')
+ ];
+
+ controlHelper.addDOMEvent(
+ controlHelper.getPart('monthMain'),
+ 'click',
+ selectors.join(','),
+ monthViewClick
+ );
},
/**
@@ -320,8 +330,9 @@ define(
* @return {string}
*/
stringifyValue: function (rawValue) {
+ var paramFormat = this.paramFormat;
if (this.mode === 'single') {
- return lib.date.format(rawValue, this.paramFormat) || '';
+ return m(rawValue).format(this.paramFormat) || '';
}
var dateStrs = [];
@@ -329,27 +340,21 @@ define(
for (var i = 0; i < rawValue.length; i++) {
if (i === 0) {
dateStrs.push(
- lib.date.format(rawValue[i], this.paramFormat)
+ m(rawValue[i]).format(paramFormat)
);
}
else {
if ((rawValue[i] - rawValue[i - 1]) > oneDay) {
dateStrs.push(
- lib.date.format(
- rawValue[i - 1], this.paramFormat
- )
+ m(rawValue[i - 1]).format(paramFormat)
);
dateStrs.push(
- lib.date.format(
- rawValue[i], this.paramFormat
- )
+ m(rawValue[i]).format(paramFormat)
);
}
else if (i === (rawValue.length - 1)) {
dateStrs.push(
- lib.date.format(
- rawValue[i], this.paramFormat
- )
+ m(rawValue[i]).format(paramFormat)
);
}
else {
@@ -361,7 +366,7 @@ define(
},
parseValue: function (value) {
- return parseValueByMode(value, this.mode);
+ return parseValueByMode(value, this.mode, this.paramFormat);
},
setRawValueWithoutFireChange: function (value) {
@@ -375,6 +380,17 @@ define(
}
);
+ MonthView.defaultProperties = {
+ range: {
+ begin: new Date(1982, 10, 4),
+ end: new Date(2046, 10, 4)
+ },
+ paramFormat: 'YYYY-MM-DD',
+ dayNamesMin: ['一', '二', '三', '四', '五', '六', '日'],
+ monthSelectLabel: '月',
+ yearSelectLabel: '年'
+ };
+
/**
* 获取可选择的年列表
*
@@ -447,7 +463,7 @@ define(
' id:${yearSelId};">',
'',
'',
- ' 年 ',
+ '${yearSelectLabel} ',
' | ',
'',
'',
' | ',
'',
- ' 月 ',
+ '${monthSelectLabel} ',
' | ',
'',
' 0) {
updateMultiRawValue(monthView);
@@ -1059,24 +1061,21 @@ define(
var controlHelper = monthView.helper;
var rowTagId = controlHelper.getId('row-select');
var selectAllTag = lib.g(controlHelper.getId('month-title-0'));
- var rowSelectedClasses
- = controlHelper.getPartClasses('month-row-select-selected');
+ var rowSelectedClass
+ = controlHelper.getPartClassName('month-row-select-selected');
var selectedRowNum = 0;
for (var i = 0; i < rowTagNum; i++) {
var rowTag = lib.g(rowTagId + '-' + i);
- if (lib.hasClass(rowTag, rowSelectedClasses[0])) {
+ if ($(rowTag).hasClass(rowSelectedClass)) {
selectedRowNum++;
}
}
- if (selectedRowNum === rowTagNum) {
- controlHelper.addPartClasses(
- 'month-select-all-selected', selectAllTag);
- }
- else {
- controlHelper.removePartClasses(
- 'month-select-all-selected', selectAllTag);
- }
+ setTagSelected(
+ selectAllTag,
+ selectedRowNum === rowTagNum,
+ rowSelectedClass
+ );
}
/**
@@ -1084,18 +1083,26 @@ define(
*
* @inner
* @param {MonthView} monthView MonthView控件实例
+ * @param {Object} $tar 点击的全选DOM节点的JQuery对象
*/
- function selectAll(monthView) {
+ function selectAll(monthView, $tar) {
// 获取横向选择状态
var controlHelper = monthView.helper;
var rowTagNum = monthView.rowTagNum;
var rowTagId = controlHelper.getId('row-select');
+ var rowSelctedClass
+ = controlHelper.getPartClassName('month-row-select-selected');
+ var rowTag;
+ var slected = $tar.hasClass(rowSelctedClass);
for (var i = 0; i < rowTagNum; i++) {
- var rowTag = lib.g(rowTagId + '-' + i);
+ rowTag = lib.g(rowTagId + '-' + i);
// 先移除所有的选择
- controlHelper.removePartClasses(
- 'month-row-select-selected', rowTag
- );
+ if (slected) {
+ $(rowTag).addClass(rowSelctedClass);
+ }
+ else {
+ $(rowTag).removeClass(rowSelctedClass);
+ }
selectByTagClick(monthView, rowTag);
}
}
@@ -1150,12 +1157,9 @@ define(
for (var i = 0; i < dLength; i++) {
id = controlHelper.getId(dates[i]);
item = lib.g(id);
- if (item) {
- lib.removeClasses(
- item,
- controlHelper.getPartClasses('month-item-selected')
- );
- }
+ $(item).removeClass(
+ controlHelper.getPartClassName('month-item-selected')
+ );
}
}
@@ -1175,12 +1179,9 @@ define(
for (var i = 0; i < dLength; i++) {
id = controlHelper.getId(dates[i]);
item = lib.g(id);
- if (item) {
- lib.addClasses(
- item,
- controlHelper.getPartClasses('month-item-selected')
- );
- }
+ $(item).addClass(
+ controlHelper.getPartClassName('month-item-selected')
+ );
}
}
@@ -1198,13 +1199,14 @@ define(
if (!item) {
return false;
}
- var classes = controlHelper.getPartClasses(className);
- if (lib.hasClass(item, classes[0])) {
- controlHelper.removePartClasses(className, item);
+ var $item = $(item);
+ var cls = controlHelper.getPartClassName(className);
+ if ($item.hasClass(cls)) {
+ $item.removeClass(cls);
return false;
}
- controlHelper.addPartClasses(className, item);
+ $item.addClass(cls);
return true;
}
@@ -1237,16 +1239,15 @@ define(
repaintAllSelectTag(monthView);
}
else {
- var itemSelectClasses
- = monthView.helper.getPartClasses('month-item-selected');
- if (lib.hasClass(item, itemSelectClasses[0])) {
+ var itemSelectClass
+ = monthView.helper.getPartClassName('month-item-selected');
+ if ($(item).hasClass(itemSelectClass)) {
return;
}
var newDate = new Date(year, month, date);
updateSingleSelectState(monthView, monthView.rawValue, newDate);
monthView.rawValue = newDate;
monthView.fire('change');
- monthView.fire('itemclick');
}
}
@@ -1454,14 +1455,14 @@ define(
updateSelectStateByValue(monthView);
}
- function rangeAdapter(range) {
+ function rangeAdapter(range, format) {
var begin;
var end;
// range类型如果是string
if (typeof range === 'string') {
var beginAndEnd = range.split(',');
- begin = parseToDate(beginAndEnd[0]);
- end = parseToDate(beginAndEnd[1]);
+ begin = m(beginAndEnd[0], format).toDate();
+ end = m(beginAndEnd[1], format).toDate();
}
else {
begin = range.begin;
@@ -1481,56 +1482,25 @@ define(
};
}
- /**
- * 字符串日期转换为Date对象
- *
- * @inner
- * @param {string} dateStr 字符串日期
- * @return {Date} parse过的日期
- */
- function parseToDate(dateStr) {
- function parse(source) {
- var dates = source.split('-');
- if (dates) {
- return new Date(
- parseInt(dates[0], 10),
- parseInt(dates[1], 10) - 1,
- parseInt(dates[2], 10)
- );
- }
- return null;
- }
-
- dateStr = dateStr + '';
- var dateAndHour = dateStr.split(' ');
- var date = parse(dateAndHour[0]);
- if (dateAndHour[1]) {
- var clock = dateAndHour[1].split(':');
- date.setHours(clock[0]);
- date.setMinutes(clock[1]);
- date.setSeconds(clock[2]);
- }
- return date;
- }
-
/**
* 根据不同模式将字符串值解析为rawValue
*
* @inner
* @param {string} value 字符串日期
* @param {string} mode 日历模式 multi | single
+ * @param {string} format 日期格式
* @return {Date | Array}
*/
- function parseValueByMode(value, mode) {
+ function parseValueByMode(value, mode, format) {
if (mode === 'single') {
- return parseToDate(value);
+ return m(value, format).toDate();
}
var dateStrs = value.split(',');
var dates = [];
for (var i = 0; i < dateStrs.length - 1; i += 2) {
- var begin = parseToDate(dateStrs[i]);
- var end = parseToDate(dateStrs[i + 1]);
+ var begin = m(dateStrs[i], format).toDate();
+ var end = m(dateStrs[i + 1], format).toDate();
var temp;
if (!begin || !end) {
continue;
diff --git a/src/Pager.js b/src/Pager.js
index a004633c..36afea00 100644
--- a/src/Pager.js
+++ b/src/Pager.js
@@ -6,16 +6,360 @@
* @file 翻页控件
* @author shenbin
*/
+
define(
function (require) {
var u = require('underscore');
var lib = require('./lib');
- var ui = require('./main');
+ var esui = require('./main');
var Control = require('./Control');
-
+ var painters = require('./painters');
+ var eoo = require('eoo');
require('./Select');
+ /**
+ * 翻页控件
+ *
+ * 翻页控件包含2部分:
+ *
+ * - 一个显示页码的横条,根据各个属性配置显示当前页和前后若干页
+ * - 一个选择“每页显示数量”的{@link Select}控件
+ *
+ * @extends Control
+ * @requires Select
+ * @constructor
+ */
+ var Pager = eoo.create(
+ Control,
+ {
+ /**
+ * 控件类型,始终为`"Pager"`
+ *
+ * @type {string}
+ * @readonly
+ * @override
+ */
+ type: 'Pager',
+
+ /**
+ * 初始化参数
+ *
+ * @param {Object} [options] 构造函数传入的参数
+ * @protected
+ * @override
+ */
+ initOptions: function (options) {
+ var properties = {
+ pageType: 'anchor',
+ count: 0,
+ page: 1,
+ backCount: 3,
+ forwardCount: 3,
+
+ urlTemplate: '',
+ layout: 'alignLeft'
+ };
+
+ u.extend(
+ properties,
+ Pager.defaultProperties,
+ options
+ );
+ this.setProperties(properties);
+ },
+
+ /**
+ * 初始化DOM结构
+ *
+ * @protected
+ * @override
+ */
+ initStructure: function () {
+ // 填充主元素代码
+ this.main.innerHTML = getMainHTML(this);
+ // 创建控件树
+ this.helper.initChildren();
+
+ // 当初始化pageSizes属性不存在或为空数组时,隐藏控件显示
+ var select = this.getChild('select');
+ if (!this.pageSizes || !this.pageSizes.length) {
+ select.hide();
+ }
+ else {
+ var properties = {
+ datasource: getPageSizes(this.pageSizes),
+ value: this.pageSize + ''
+ };
+ select.setProperties(properties);
+
+ // 同步一次状态
+ changePageSize.call(this);
+ }
+ },
+
+ /**
+ * 初始化事件交互
+ *
+ * @protected
+ * @override
+ */
+ initEvents: function () {
+ // 每页显示的select控件
+ var select = this.getChild('select');
+ select.on('change', changePageSize, this);
+
+ // pager主元素绑定事件
+ this.helper.addDOMEvent('main', 'click', pagerClick);
+ },
+
+ /**
+ * 批量设置控件的属性值
+ *
+ * @param {Object} properties 属性值集合
+ * @override
+ */
+ setProperties: function (properties) {
+ properties = u.clone(properties);
+
+ // `pageIndex`提供从0开始的页码,但是以`page`为准
+ if (properties.hasOwnProperty('pageIndex')
+ && !properties.hasOwnProperty('page')
+ ) {
+ /**
+ * @property {number} pageIndex
+ *
+ * 以0为起始的页码,其值始终为{@link Pager#page}减1
+ *
+ * 如果与{@link Pager#page}属性同时存在,
+ * 则优先使用{@link Pager#page}属性
+ */
+ properties.page = +properties.pageIndex + 1;
+ }
+
+ var digitalProperties = [
+ 'count', 'page', 'backCount',
+ 'forwardCount', 'pageSize'
+ ];
+
+ u.each(
+ digitalProperties,
+ function (name) {
+ var value = properties[name];
+ if (u.isString(value)) {
+ properties[name] = +value;
+ }
+ }
+ );
+
+ var changes
+ = Control.prototype.setProperties.apply(this, arguments);
+
+ if (changes.hasOwnProperty('page')) {
+ // 触发页码变更事件
+ /**
+ * @event changepage
+ *
+ * 页码变化时触发
+ *
+ * @member Pager
+ * @deprecated 使用{@link Pager#pagechange}代替
+ */
+ this.fire('changepage');
+
+ /**
+ * @event pagechange
+ *
+ * 页码变化时触发
+ *
+ * @member Pager
+ */
+ this.fire('pagechange');
+ }
+ },
+
+ /**
+ * 重渲染
+ *
+ * @method
+ * @protected
+ * @override
+ */
+ repaint: painters.createRepaint(
+ Control.prototype.repaint,
+ {
+ /**
+ * @property {number[]} pageSizes
+ *
+ * 可用的“每页条数”列表
+ */
+ name: 'pageSizes',
+ paint: function (pager, value) {
+ var select = pager.getChild('select');
+ // 当`pageSizes`属性不存在或为空数组时,隐藏控件显示
+ if (!value || !value.length) {
+ select.hide();
+ }
+ else {
+ var properties = {
+ datasource: getPageSizes(value),
+ value: pager.pageSize + ''
+ };
+ select.setProperties(properties);
+ select.show();
+ }
+ }
+ },
+ {
+ /**
+ * @property {string} [layout="alignLeft"]
+ *
+ * 指定控件的布局方式,可以使用以下值:
+ *
+ * - `alignLeft`:整体靠左对齐,页码在左,选择框在右
+ * - `alignLeftReversed`:整体靠左对齐,而码在右,选择框在左
+ * - `alignRight`:整体靠右对齐,页码在左,选择框在右
+ * - `alignRightReversed`:整体靠右对齐,而码在右,选择框在左
+ * - `distributed`:页码靠左对齐,选择框靠右对齐
+ * - `distributedReversed`:页码靠右对齐,选择框靠左对齐
+ */
+ name: 'layout',
+ paint: repaintLayout
+ },
+ {
+ name: [
+ /**
+ * @property {string} [pageType="anchor"]
+ *
+ * 页码元素类型,可以为:
+ *
+ * - `plain`:页码为普通文本,点击后不跳转链接,
+ * 仅触发{@link Pager#pagechange}事件
+ * - `anchor`:页码为` `元素,点击后直接跳转
+ */
+
+ 'pageType',
+
+ /**
+ * @property {number} [count=0]
+ *
+ * 总条目数量
+ */
+ 'count',
+
+ /**
+ * @property {number} pageSize
+ *
+ * 每页显示条目数量
+ */
+ 'pageSize',
+
+ /**
+ * @property {number} [page=1]
+ *
+ * 当前页码,以1为起始,即1表示第1页
+ */
+ 'page',
+
+ /**
+ * @property {number} backCount
+ *
+ * 在当前页前面显示的页数
+ *
+ * 如{@link Pager#page}值为5,`backCount`为3,
+ * 则显示`[2] [3] [4] [5]`
+ */
+ 'backCount',
+
+ /**
+ * @property {number} forwardCount
+ *
+ * 在当前页后面显示的页数
+ *
+ * 如{@link Pager#page}值为5,`forwardCount`为3,
+ * 则显示`[5] [6] [7] [8]`
+ */
+ 'forwardCount',
+ /**
+ * @property {string} firstText
+ *
+ * “首页”元素的显示文字
+ */
+ 'firstText',
+ /**
+ * @property {string} lastText
+ *
+ * “末页”元素的显示文字
+ */
+ 'lastText',
+ /**
+ * @property {string} backText
+ *
+ * “下一页”元素的显示文字
+ */
+ 'backText',
+ /**
+ * @property {string} pagePattern
+ *
+ * 分页模式,默认中间分页模式'middlePattern',不显示“首页”与“末页”标签。
+ * 可选完整模式'fullPattern',后继会增加简化模式'simplePattern'与
+ * 极简模式'verySimplePattern'
+ */
+ 'pagePattern',
+ /**
+ * @property {string} forwardText
+ *
+ * “上一页”元素的显示文字
+ */
+ 'forwardText',
+
+ /**
+ * @property {string} urlTemplate
+ *
+ * 用于生成链接地址的URL模板
+ *
+ * 模板中可以使用以下占位符:
+ *
+ * - `page`:当前页码
+ * - `pageSize`:每页显示条目数
+ */
+ 'urlTemplate'
+ ],
+ paint: repaintPager
+ }
+ ),
+
+ /**
+ * 获取从0开始的页码
+ *
+ * @return {number} 其值始终为{@link Pager#page}减去1
+ */
+ getPageIndex: function () {
+ return this.get('page') - 1;
+ }
+ }
+ );
+ /**
+ * @cfg defaultProperties
+ *
+ * 默认属性值
+ *
+ * @cfg {number[]} [defaultProperties.pageSizes] 默认每页数量可选项
+ * @cfg {number} [defaultProperties.pageSize=15] 默认每页数量
+ * @static
+ */
+ Pager.defaultProperties = {
+ // 这里不加任何属性,不然会覆盖掉实例上的那个`defaultProperties`出问题,
+ // 如果使用者直接改这个,自然是要覆盖的就没关系
+ pagerLabelText: '每页显示',
+ firstText: '首页',
+ lastText: '末页',
+ backText: '上一页',
+ forwardText: '下一页',
+ pageSizes: [15, 30, 50, 100],
+ pageSize: 15
+ };
+
/**
* 获取控件主元素HTML
*
@@ -36,21 +380,22 @@ define(
'',
' '
];
+ var controlHelper = pager.helper;
return lib.format(
template.join(''),
{
- pagerWrapperId: pager.helper.getId('pager-wrapper'),
- pagerWrapperClass: pager.helper.getPartClasses(pager.layout)[0],
- selectWrapperId: pager.helper.getId('select-wrapper'),
- selectWrapperClass: pager.helper.getPartClassName('select-wrapper'),
- labelId: pager.helper.getId('label'),
- labelClass: pager.helper.getPartClassName('label'),
- labelText: '每页显示',
- selectPagerId: pager.helper.getId('selectPager'),
- selectClass: pager.helper.getPartClassName('select'),
- mainId: pager.helper.getId('main'),
- mainClass: pager.helper.getPartClassName('main')
+ pagerWrapperId: controlHelper.getId('pager-wrapper'),
+ pagerWrapperClass: controlHelper.getPartClassName(pager.layout),
+ selectWrapperId: controlHelper.getId('select-wrapper'),
+ selectWrapperClass: controlHelper.getPartClassName('select-wrapper'),
+ labelId: controlHelper.getId('label'),
+ labelClass: controlHelper.getPartClassName('label'),
+ labelText: pager.pagerLabelText,
+ selectPagerId: controlHelper.getId('selectPager'),
+ selectClass: controlHelper.getPartClassName('select'),
+ mainId: controlHelper.getId('main'),
+ mainClass: controlHelper.getPartClassName('main')
}
);
}
@@ -69,6 +414,7 @@ define(
var anchorTpl = ''
+ '${text}';
var omitTpl = '…';
+ var html = [];
/**
* 根据模板拼接url
@@ -98,8 +444,12 @@ define(
* @ignore
*/
function getTplObj(className, num, id, text) {
+ var cls = [];
+ u.each(className.split(' '), function (name) {
+ cls.push(pager.helper.getPartClassName(name));
+ });
var obj = {
- className: pager.helper.getPartClassName(className)
+ className: cls.join(' ')
};
if (arguments.length > 1) {
@@ -157,12 +507,12 @@ define(
// 计算得到的总页码数
var totalPage = Math.ceil(pager.count / pager.pageSize);
// 数组html用于存储页码区域的元素代码
- var html = [];
+
if (page > 1) {
if (pagePattern === 'fullPattern') {
// 首页
var objFirst = getTplObj(
- 'item-extend ui-pager-item-first',
+ 'item-extend item-first',
0,
'page-first',
pager.firstText
@@ -171,13 +521,14 @@ define(
}
// 上一页
- var obj = getTplObj(
- 'item-extend',
- page - 1,
- 'page-back',
- pager.backText
+ addSegmentToHTML(
+ getTplObj(
+ 'item-extend',
+ page - 1,
+ 'page-back',
+ pager.backText
+ )
);
- addSegmentToHTML(obj);
}
// 前缀页码
@@ -186,8 +537,7 @@ define(
// 前缀...符号
if (page > backCount + 2) {
- var obj = getTplObj('item-omit');
- addSegmentToHTML(obj, omitTpl);
+ addSegmentToHTML(getTplObj('item-omit'), omitTpl);
}
}
@@ -201,28 +551,29 @@ define(
}
// 当前页码
- var obj = getTplObj(
- 'item-current',
- page,
- 'page-' + page,
- page
+ addSegmentToHTML(
+ getTplObj(
+ 'item-current',
+ page,
+ 'page-' + page,
+ page
+ ),
+ plainTpl
);
- addSegmentToHTML(obj, plainTpl);
// 后置页码
- var len = totalPage - page > forwardCount
+ var len2 = totalPage - page > forwardCount
? forwardCount
: totalPage - page;
- for (var i = page + 1; i < page + len + 1; i++) {
- addSegmentToHTML(i);
+ for (var j = page + 1; j < page + len2 + 1; j++) {
+ addSegmentToHTML(j);
}
// 后缀页码
if (page < totalPage - forwardCount) {
// 后缀...符号
if (page < totalPage - forwardCount - 1) {
- var obj = getTplObj('item-omit');
- addSegmentToHTML(obj, omitTpl);
+ addSegmentToHTML(getTplObj('item-omit'), omitTpl);
}
addSegmentToHTML(totalPage);
@@ -230,22 +581,24 @@ define(
if (page < totalPage) {
// 下一页
- var obj = getTplObj(
- 'item-extend',
- page + 1,
- 'page-forward',
- pager.forwardText
+ addSegmentToHTML(
+ getTplObj(
+ 'item-extend',
+ page + 1,
+ 'page-forward',
+ pager.forwardText
+ )
);
- addSegmentToHTML(obj);
if (pagePattern === 'fullPattern') {
// 末页
- var objLast = getTplObj(
- 'item-extend ui-pager-item-last',
- Math.ceil(pager.count / pager.pageSize),
- 'page-last',
- pager.lastText
+ addSegmentToHTML(
+ getTplObj(
+ 'item-extend item-last',
+ Math.ceil(pager.count / pager.pageSize),
+ 'page-last',
+ pager.lastText
+ )
);
- addSegmentToHTML(objLast);
}
}
return html.join('');
@@ -284,6 +637,7 @@ define(
* @ignore
*/
function repaintLayout(pager, style) {
+
/**
* 获取class的集合
*
@@ -294,22 +648,21 @@ define(
function getClasses() {
var classes = [];
for (var i = 0, len = arguments.length; i < len; i++) {
- classes.push(pager.helper.getPartClasses(arguments[i])[0]);
+ classes.push(pager.helper.getPartClassName(arguments[i]));
}
- return classes;
+ return classes.join(' ');
}
- var pagerWrapper = pager.helper.getPart('pager-wrapper');
- lib.removeClasses(
- pagerWrapper,
+ var $pagerWrapper = $(pager.helper.getPart('pager-wrapper'));
+ $pagerWrapper.removeClass(
getClasses(
'alignLeft', 'alignLeftReversed',
'alignRight', 'alignRightReversed',
'distributed', 'distributedReversed'
)
);
- lib.addClass(pagerWrapper, pager.helper.getPartClasses(style)[0]);
+ $pagerWrapper.addClass(pager.helper.getPartClassName(style));
}
/**
@@ -320,14 +673,15 @@ define(
*/
function pagerClick(e) {
var target = e.target;
- var lastId = this.helper.getId('page-last');
- var backId = this.helper.getId('page-back');
- var forwardId = this.helper.getId('page-forward');
- var firstId = this.helper.getId('page-first');
+ var controlHelper = this.helper;
+ var lastId = controlHelper.getId('page-last');
+ var backId = controlHelper.getId('page-back');
+ var forwardId = controlHelper.getId('page-forward');
+ var firstId = controlHelper.getId('page-first');
var page = this.page;
- if (this.helper.isPart(target, 'item')
- || this.helper.isPart(target, 'item-extend')
+ if (controlHelper.isPart(target, 'item')
+ || controlHelper.isPart(target, 'item-extend')
) {
if (target.id === backId) {
page--;
@@ -361,7 +715,7 @@ define(
var datasource = u.map(
pageSizes,
function (size) {
- return { text: size + '', value: size + '' };
+ return {text: size + '', value: size + ''};
}
);
@@ -402,384 +756,7 @@ define(
this.fire('pagesizechange');
}
- /**
- * 显示`Select`控件及对应的label元素
- *
- * @param {Pager} pager 控件实例
- * @ignore
- */
- function showSelect(pager) {
- var selectWrapper = pager.helper.getPart('select-wrapper');
- pager.helper.removePartClasses('select-wrapper-hidden', selectWrapper);
- }
-
- /**
- * 隐藏`Select`控件及对应的label元素
- *
- * @param {Pager} pager 控件实例
- * @ignore
- */
- function hideSelect(pager) {
- var selectWrapper = pager.helper.getPart('select-wrapper');
- pager.helper.addPartClasses('select-wrapper-hidden', selectWrapper);
- }
-
- /**
- * 翻页控件
- *
- * 翻页控件包含2部分:
- *
- * - 一个显示页码的横条,根据各个属性配置显示当前页和前后若干页
- * - 一个选择“每页显示数量”的{@link Select}控件
- *
- * @extends Control
- * @requires Select
- * @constructor
- */
- function Pager(options) {
- Control.apply(this, arguments);
- }
-
-
- /**
- * @cfg defaultProperties
- *
- * 默认属性值
- *
- * @cfg {number[]} [defaultProperties.pageSizes] 默认每页数量可选项
- * @cfg {number} [defaultProperties.pageSize=15] 默认每页数量
- * @static
- */
- Pager.defaultProperties = {
- // 这里不加任何属性,不然会覆盖掉实例上的那个`defaultProperties`出问题,
- // 如果使用者直接改这个,自然是要覆盖的就没关系
- };
-
-
- Pager.prototype = {
- /**
- * 控件类型,始终为`"Pager"`
- *
- * @type {string}
- * @readonly
- * @override
- */
- type: 'Pager',
-
- /**
- * 默认属性
- *
- * @type {Object}
- * @deprecated 使用构造函数上的{@link Pager#cfg-defaultProperties}代替
- */
- defaultProperties: {
- pageSizes: [15, 30, 50, 100],
- pageSize: 15
- },
-
- /**
- * 初始化参数
- *
- * @param {Object} [options] 构造函数传入的参数
- * @protected
- * @override
- */
- initOptions: function (options) {
- var properties = {
- pageType: 'anchor',
- count: 0,
- page: 1,
- backCount: 3,
- forwardCount: 3,
- firstText: '首页',
- lastText: '末页',
- backText: '上一页',
- forwardText: '下一页',
- urlTemplate: '',
- layout: 'alignLeft'
- };
-
- u.extend(
- properties,
- this.defaultProperties, // 这么是向后兼容,以后准备去掉
- Pager.defaultProperties,
- options
- );
- this.setProperties(properties);
- },
-
- /**
- * 初始化DOM结构
- *
- * @protected
- * @override
- */
- initStructure: function () {
- // 填充主元素代码
- this.main.innerHTML = getMainHTML(this);
- // 创建控件树
- this.helper.initChildren();
-
- // 当初始化pageSizes属性不存在或为空数组时,隐藏控件显示
- var select = this.getChild('select');
- if (!this.pageSizes || !this.pageSizes.length) {
- hideSelect(this);
- }
- else {
- var properties = {
- datasource: getPageSizes(this.pageSizes),
- value: this.pageSize + ''
- };
- select.setProperties(properties);
-
- // 同步一次状态
- changePageSize.call(this);
- }
- },
-
- /**
- * 初始化事件交互
- *
- * @protected
- * @override
- */
- initEvents: function () {
- // 每页显示的select控件
- var select = this.getChild('select');
- select.on('change', changePageSize, this);
-
- // pager主元素绑定事件
- this.helper.addDOMEvent('main', 'click', pagerClick);
- },
-
- /**
- * 批量设置控件的属性值
- *
- * @param {Object} properties 属性值集合
- * @override
- */
- setProperties: function (properties) {
- properties = u.clone(properties);
-
- // `pageIndex`提供从0开始的页码,但是以`page`为准
- if (properties.hasOwnProperty('pageIndex')
- && !properties.hasOwnProperty('page')
- ) {
- /**
- * @property {number} pageIndex
- *
- * 以0为起始的页码,其值始终为{@link Pager#page}减1
- *
- * 如果与{@link Pager#page}属性同时存在,
- * 则优先使用{@link Pager#page}属性
- */
- properties.page = +properties.pageIndex + 1;
- }
-
- var digitalProperties = [
- 'count', 'page', 'backCount',
- 'forwardCount', 'pageSize'
- ];
-
- u.each(
- digitalProperties,
- function (name) {
- var value = properties[name];
- if (u.isString(value)) {
- properties[name] = +value;
- }
- }
- );
-
- var changes =
- Control.prototype.setProperties.apply(this, arguments);
-
- if (changes.hasOwnProperty('page')) {
- // 触发页码变更事件
- /**
- * @event changepage
- *
- * 页码变化时触发
- *
- * @member Pager
- * @deprecated 使用{@link Pager#pagechange}代替
- */
- this.fire('changepage');
-
- /**
- * @event pagechange
- *
- * 页码变化时触发
- *
- * @member Pager
- */
- this.fire('pagechange');
- }
- },
-
- /**
- * 重渲染
- *
- * @method
- * @protected
- * @override
- */
- repaint: require('./painters').createRepaint(
- Control.prototype.repaint,
- {
- /**
- * @property {number[]} pageSizes
- *
- * 可用的“每页条数”列表
- */
- name: 'pageSizes',
- paint: function (pager, value) {
- var select = pager.getChild('select');
- // 当`pageSizes`属性不存在或为空数组时,隐藏控件显示
- if (!value || !value.length) {
- hideSelect(pager);
- }
- else {
- var properties = {
- datasource: getPageSizes(value),
- value: pager.pageSize + ''
- };
- select.setProperties(properties);
- showSelect(pager);
- }
- }
- },
- {
- /**
- * @property {string} [layout="alignLeft"]
- *
- * 指定控件的布局方式,可以使用以下值:
- *
- * - `alignLeft`:整体靠左对齐,页码在左,选择框在右
- * - `alignLeftReversed`:整体靠左对齐,而码在右,选择框在左
- * - `alignRight`:整体靠右对齐,页码在左,选择框在右
- * - `alignRightReversed`:整体靠右对齐,而码在右,选择框在左
- * - `distributed`:页码靠左对齐,选择框靠右对齐
- * - `distributedReversed`:页码靠右对齐,选择框靠左对齐
- */
- name: 'layout',
- paint: repaintLayout
- },
- {
- name: [
- /**
- * @property {string} [pageType="anchor"]
- *
- * 页码元素类型,可以为:
- *
- * - `plain`:页码为普通文本,点击后不跳转链接,
- * 仅触发{@link Pager#pagechange}事件
- * - `anchor`:页码为``元素,点击后直接跳转
- */
-
- 'pageType',
-
- /**
- * @property {number} [count=0]
- *
- * 总条目数量
- */
- 'count',
-
- /**
- * @property {number} pageSize
- *
- * 每页显示条目数量
- */
- 'pageSize',
-
- /**
- * @property {number} [page=1]
- *
- * 当前页码,以1为起始,即1表示第1页
- */
- 'page',
-
- /**
- * @property {number} backCount
- *
- * 在当前页前面显示的页数
- *
- * 如{@link Pager#page}值为5,`backCount`为3,
- * 则显示`[2] [3] [4] [5]`
- */
- 'backCount',
-
- /**
- * @property {number} forwardCount
- *
- * 在当前页后面显示的页数
- *
- * 如{@link Pager#page}值为5,`forwardCount`为3,
- * 则显示`[5] [6] [7] [8]`
- */
- 'forwardCount',
- /**
- * @property {string} firstText
- *
- * “首页”元素的显示文字
- */
- 'firstText',
- /**
- * @property {string} lastText
- *
- * “末页”元素的显示文字
- */
- 'lastText',
- /**
- * @property {string} backText
- *
- * “下一页”元素的显示文字
- */
- 'backText',
- /**
- * @property {string} pagePattern
- *
- * 分页模式,默认中间分页模式'middlePattern',不显示“首页”与“末页”标签。
- * 可选完整模式'fullPattern',后继会增加简化模式'simplePattern'与
- * 极简模式'verySimplePattern'
- */
- 'pagePattern',
- /**
- * @property {string} forwardText
- *
- * “上一页”元素的显示文字
- */
- 'forwardText',
-
- /**
- * @property {string} urlTemplate
- *
- * 用于生成链接地址的URL模板
- *
- * 模板中可以使用以下占位符:
- *
- * - `page`:当前页码
- * - `pageSize`:每页显示条目数
- */
- 'urlTemplate'
- ],
- paint: repaintPager
- }
- ),
-
- /**
- * 获取从0开始的页码
- *
- * @return {number} 其值始终为{@link Pager#page}减去1
- */
- getPageIndex: function () {
- return this.get('page') - 1;
- }
- };
-
- lib.inherits(Pager, Control);
- ui.register(Pager);
+ esui.register(Pager);
return Pager;
}
);
diff --git a/src/Panel.js b/src/Panel.js
index ec04aee3..18c49fcf 100644
--- a/src/Panel.js
+++ b/src/Panel.js
@@ -9,8 +9,10 @@
define(
function (require) {
var u = require('underscore');
- var lib = require('./lib');
var Control = require('./Control');
+ var eoo = require('eoo');
+ var painters = require('./painters');
+ var esui = require('./main');
/**
* 通用面板
@@ -24,113 +26,158 @@ define(
* @extends Control
* @constructor
*/
- function Panel() {
- Control.apply(this, arguments);
- }
+ var Panel = eoo.create(
+ Control,
+ {
+ /**
+ * 控件类型,始终为`"Panel"`
+ *
+ * @type {string}
+ * @readonly
+ * @override
+ */
+ type: 'Panel',
- /**
- * 控件类型,始终为`"Panel"`
- *
- * @type {string}
- * @readonly
- * @override
- */
- Panel.prototype.type = 'Panel';
+ /**
+ * 获取控件的分类
+ *
+ * @return {string} 始终返回`"container"`
+ * @override
+ */
+ getCategory: function () {
+ return 'container';
+ },
- /**
- * 获取控件的分类
- *
- * @return {string} 始终返回`"container"`
- * @override
- */
- Panel.prototype.getCategory = function () {
- return 'container';
- };
+ /**
+ * 创建控件主元素
+ *
+ * 如果初始化时提供{@link Panel#tagName}属性,则以此创建元素,
+ * 默认使用``元素
+ *
+ * @param {Object} options 构造函数传入的参数
+ * @return {HTMLElement}
+ * @protected
+ * @override
+ */
+ createMain: function (options) {
+ if (!options.tagName) {
+ return this.$super([options]);
+ }
+ return document.createElement(options.tagName);
+ },
- /**
- * 创建控件主元素
- *
- * 如果初始化时提供{@link Panel#tagName}属性,则以此创建元素,
- * 默认使用` `元素
- *
- * @param {Object} options 构造函数传入的参数
- * @return {HTMLElement}
- * @protected
- * @override
- */
- Panel.prototype.createMain = function (options) {
- if (!options.tagName) {
- return Control.prototype.createMain.call(this);
- }
- return document.createElement(options.tagName);
- };
+ /**
+ * 初始化参数
+ *
+ * 如果初始化时提供了主元素,则使用主元素的标签名作为{@link Panel#tagName}属性
+ *
+ * @param {Object} [options] 构造函数传入的参数
+ * @protected
+ * @override
+ */
+ initOptions: function (options) {
+ var properties = {};
+ u.extend(properties, options);
+ /**
+ * @property {string} tagName
+ *
+ * 指定主元素标签名
+ *
+ * 此属性仅在初始化时生效,运行期不能修改
+ *
+ * @readonly
+ */
+ properties.tagName = this.main.nodeName.toLowerCase();
+ this.setProperties(properties);
+ },
- /**
- * 初始化参数
- *
- * 如果初始化时提供了主元素,则使用主元素的标签名作为{@link Panel#tagName}属性
- *
- * @param {Object} [options] 构造函数传入的参数
- * @protected
- * @override
- */
- Panel.prototype.initOptions = function (options) {
- var properties = {};
- u.extend(properties, options);
- /**
- * @property {string} tagName
- *
- * 指定主元素标签名
- *
- * 此属性仅在初始化时生效,运行期不能修改
- *
- * @readonly
- */
- properties.tagName = this.main.nodeName.toLowerCase();
- this.setProperties(properties);
- };
+ /**
+ * 重渲染
+ *
+ * @method
+ * @protected
+ * @override
+ */
+ repaint: painters.createRepaint(
+ Control.prototype.repaint,
+ {
+ /**
+ * @property {string} content
+ *
+ * 面板的内容,为一个HTML片段
+ *
+ * 此属性中可包含ESUI相关的属性,在设置内容后,
+ * 会使用{@link Helper#initChildren}进行内部控件的初始化
+ */
+ name: 'content',
+ paint: function (panel, content) {
+ // 第一次刷新的时候是可能没有`content`的,
+ // 这时在`innerHTML`上就地创建控件,不要刷掉内容,
+ // 后续有要求`content`是字符串,所以不管非字符串的后果
+ if (content != null) {
+ panel.helper.disposeChildren();
+ panel.main.innerHTML = content;
+ }
+ panel.helper.initChildren();
+ }
+ }
+ ),
- /**
- * 重渲染
- *
- * @method
- * @protected
- * @override
- */
- Panel.prototype.repaint = require('./painters').createRepaint(
- Control.prototype.repaint,
- {
/**
- * @property {string} content
+ * 设置内容
*
- * 面板的内容,为一个HTML片段
+ * @param {string} html 内容HTML,具体参考{@link Panel#content}属性的说明
+ */
+ setContent: function (html) {
+ this.setProperties({content: html});
+ },
+
+ /**
+ * 在面板最前面追加内容
+ *
+ * @param {string} html 追加内容的HTML代码
+ */
+ prependContent: function (html) {
+ addContent.call(this, html, true);
+ },
+
+ /**
+ * 在面板最后面追加内容
+ *
+ * @param {string} html 追加内容的HTML代码
+ */
+ appendContent: function (html) {
+ addContent.call(this, html, false);
+ },
+
+ /**
+ * 获取样式,仅获取设置的样式,不包含外部CSS给定的
+ *
+ * @param {string} name 样式名称
+ * @return {string}
+ */
+ getStyle: function (name) {
+ name = normalizeStyleName(name);
+ return this.main
+ ? this.main.style[name]
+ : '';
+ },
+
+ /**
+ * 设置样式
*
- * 此属性中可包含ESUI相关的属性,在设置内容后,
- * 会使用{@link Helper#initChildren}进行内部控件的初始化
+ * @param {string} name 样式名称,如果只有这一个参数,则表示为整串样式
+ * @param {string} [value=""] 样式值
*/
- name: 'content',
- paint: function (panel, content) {
- // 第一次刷新的时候是可能没有`content`的,
- // 这时在`innerHTML`上就地创建控件,不要刷掉内容,
- // 后续有要求`content`是字符串,所以不管非字符串的后果
- if (content != null) {
- panel.helper.disposeChildren();
- panel.main.innerHTML = content;
+ setStyle: function (name, value) {
+ name = normalizeStyleName(name);
+ if (this.main) {
+ this.main.style[name] = value || '';
}
- panel.helper.initChildren();
}
}
);
- /**
- * 设置内容
- *
- * @param {string} html 内容HTML,具体参考{@link Panel#content}属性的说明
- */
- Panel.prototype.setContent = function (html) {
- this.setProperties({ content: html });
- };
-
/**
* 追加内容
*
@@ -154,7 +201,6 @@ define(
children.push(childNodes[i]);
}
- var ui = require('./main');
u.each(children, function (child) {
if (isPrepend) {
main.insertBefore(child, main.firstChild);
@@ -162,28 +208,10 @@ define(
else {
main.appendChild(child);
}
- ui.init(main, options);
+ esui.init(main, options);
});
}
- /**
- * 在面板最前面追加内容
- *
- * @param {string} html 追加内容的HTML代码
- */
- Panel.prototype.prependContent = function (html) {
- addContent.call(this, html, true);
- };
-
- /**
- * 在面板最后面追加内容
- *
- * @param {string} html 追加内容的HTML代码
- */
- Panel.prototype.appendContent = function (html) {
- addContent.call(this, html, false);
- };
-
/**
* 统一化样式名
*
@@ -204,34 +232,7 @@ define(
return name;
}
- /**
- * 获取样式,仅获取设置的样式,不包含外部CSS给定的
- *
- * @param {string} name 样式名称
- * @return {string}
- */
- Panel.prototype.getStyle = function (name) {
- name = normalizeStyleName(name);
- return this.main
- ? this.main.style[name]
- : '';
- };
-
- /**
- * 设置样式
- *
- * @param {string} name 样式名称,如果只有这一个参数,则表示为整串样式
- * @param {string} [value=""] 样式值
- */
- Panel.prototype.setStyle = function (name, value) {
- name = normalizeStyleName(name);
- if (this.main) {
- this.main.style[name] = value || '';
- }
- };
-
- lib.inherits(Panel, Control);
- require('./main').register(Panel);
+ esui.register(Panel);
return Panel;
}
);
diff --git a/src/main.js b/src/main.js
index 97d3f40e..8644a81d 100644
--- a/src/main.js
+++ b/src/main.js
@@ -322,7 +322,7 @@ define(
options = options || {};
var defaultValueParser = function (value) {
- var coreNumber = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/;
+ var coreNumber = /^[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)$/;
if (value === 'true') {
value = true;
}
@@ -392,7 +392,7 @@ define(
);
}
else {
- optionObject[joinCamelCase(terms)] = valueReplacer(value);
+ optionObject[joinCamelCase(terms)] = valueReplacer(valueParser(value));
}
}
diff --git a/src/painters.js b/src/painters.js
index 93d5cf03..c97bc977 100644
--- a/src/painters.js
+++ b/src/painters.js
@@ -9,7 +9,6 @@
define(
function (require) {
var u = require('underscore');
- var lib = require('./lib');
/**
* @class painters
@@ -247,7 +246,7 @@ define(
* - `{Control} control`:当前的控件实例
* - `{Mixed} args...`:根据`name`配置指定的属性,依次将属性的最新值作为参数
*
- * @param {Object... | Function...} args `painter`对象
+ * @param {...Object | Function} args `painter`对象
* @return {Function} `repaint`方法的实现
*/
painters.createRepaint = function () {
@@ -255,7 +254,7 @@ define(
return function (changes, changesIndex) {
// 临时索引,不能直接修改`changesIndex`,会导致子类的逻辑错误
- var index = lib.extend({}, changesIndex);
+ var index = u.extend({}, changesIndex);
for (var i = 0; i < painters.length; i++) {
var painter = painters[i];
@@ -288,29 +287,13 @@ define(
// 收集所有属性的值
var properties = [this];
- for (var j = 0; j < propertyNames.length; j++) {
- var name = propertyNames[j];
- properties.push(this[name]);
+ for (var k = 0; k < propertyNames.length; k++) {
+ var name2 = propertyNames[k];
+ properties.push(this[name2]);
// 从索引中删除,为了后续构建`unpainted`数组
- delete index[name];
+ delete index[name2];
}
- // 绘制
- try {
- painter.paint.apply(painter, properties);
- }
- catch (ex) {
- var paintingPropertyNames =
- '"' + propertyNames.join('", "') + '"';
- var error = new Error(
- 'Failed to paint [' + paintingPropertyNames + '] '
- + 'for control "' + (this.id || 'anonymous')+ '" '
- + 'of type ' + this.type + ' '
- + 'because: ' + ex.message
- );
- error.actualError = ex;
- throw error;
- }
-
+ painter.paint.apply(painter, properties);
}
// 构建出未渲染的属性集合
|