├── yarn.lock
├── .npmignore
├── snippets
├── knockout
│ ├── demo
│ │ └── 1-bind
│ │ │ ├── 说明.md
│ │ │ ├── widget.html
│ │ │ └── widget.js
│ └── base.md
├── gettingstarted
│ ├── demo
│ │ └── 1-helloworld
│ │ │ ├── 说明.md
│ │ │ ├── widget.html
│ │ │ └── widget.js
│ └── base.md
├── dataTableUse
│ ├── demo
│ │ ├── 2-time
│ │ │ ├── 说明.md
│ │ │ ├── widget.html
│ │ │ └── widget.js
│ │ ├── 1-helloworld
│ │ │ ├── 说明.md
│ │ │ ├── widget.html
│ │ │ └── widget.js
│ │ └── 3-alert
│ │ │ ├── 说明.md
│ │ │ ├── widget.html
│ │ │ └── widget.js
│ └── base.md
├── validateapi
│ ├── demo
│ │ └── 1-validateapi
│ │ │ ├── 说明.md
│ │ │ ├── widget.js
│ │ │ └── widget.html
│ └── base.md
├── SUMMARY.md
├── install
│ └── base.md
├── arch
│ └── base.md
├── overview
│ └── base.md
└── datatable
│ └── base.md
├── vendor
├── uui
│ ├── images
│ │ ├── close.png
│ │ ├── diy
│ │ │ ├── 2.png
│ │ │ ├── 3.png
│ │ │ ├── 4.png
│ │ │ ├── 5.png
│ │ │ ├── 6.png
│ │ │ ├── 7.png
│ │ │ ├── 8.png
│ │ │ ├── 9.png
│ │ │ ├── 1_close.png
│ │ │ └── 1_open.png
│ │ ├── loading.gif
│ │ ├── itemcancel.png
│ │ ├── line_conn.gif
│ │ ├── zTreeStandard.gif
│ │ └── zTreeStandard.png
│ ├── assets
│ │ ├── images
│ │ │ ├── close.png
│ │ │ ├── diy
│ │ │ │ ├── 2.png
│ │ │ │ ├── 3.png
│ │ │ │ ├── 4.png
│ │ │ │ ├── 5.png
│ │ │ │ ├── 6.png
│ │ │ │ ├── 7.png
│ │ │ │ ├── 8.png
│ │ │ │ ├── 9.png
│ │ │ │ ├── 1_close.png
│ │ │ │ └── 1_open.png
│ │ │ ├── line_conn.gif
│ │ │ ├── loading.gif
│ │ │ ├── itemcancel.png
│ │ │ ├── zTreeStandard.gif
│ │ │ └── zTreeStandard.png
│ │ └── fonts
│ │ │ └── font-awesome
│ │ │ └── fonts
│ │ │ ├── FontAwesome.otf
│ │ │ ├── fontawesome-webfont.eot
│ │ │ ├── fontawesome-webfont.ttf
│ │ │ ├── fontawesome-webfont.woff
│ │ │ └── fontawesome-webfont.woff2
│ ├── fonts
│ │ └── font-awesome
│ │ │ └── fonts
│ │ │ ├── FontAwesome.otf
│ │ │ ├── fontawesome-webfont.eot
│ │ │ ├── fontawesome-webfont.ttf
│ │ │ ├── fontawesome-webfont.woff
│ │ │ └── fontawesome-webfont.woff2
│ └── js
│ │ └── u-polyfill.min.js
├── font-awesome
│ └── fonts
│ │ ├── FontAwesome.otf
│ │ ├── fontawesome-webfont.eot
│ │ ├── fontawesome-webfont.ttf
│ │ ├── fontawesome-webfont.woff
│ │ └── fontawesome-webfont.woff2
├── requirejs
│ └── css.min.js
└── ace
│ ├── theme-xcode.js
│ └── theme-github.js
├── _config.yml
├── .github
├── PULL_REQUEST_TEMPLATE.md
├── ISSUE_TEMPLATE.md
└── CONTRIBUTING.md
├── test
└── test.html
├── .travis.yml
├── .babelrc
├── docs
├── SUMMARY.md
├── knockout.md
├── gettingstarted.md
├── install.md
├── arch.md
├── overview.md
├── dataTableUseBackend.md
└── datatable.md
├── bin
├── utool.js
└── docMutilLang.sh
├── lib
├── indexEvents.js
├── getParam.js
├── index.js
├── page-getMeta.js
├── getFocus.js
├── rowCurrent.js
├── row-simpleData.js
├── page-meta.js
├── getPage.js
├── param.js
├── getCurrent.js
├── row-rowSelect.js
├── indexPage.js
├── util.js
├── row-getMeta.js
├── copyRow.js
├── enable.js
├── getMeta.js
├── removeRow.js
├── rowDelete.js
├── page-data.js
├── row-meta.js
├── row-init.js
├── page-removeRow.js
├── getSimpleData.js
├── rowFocus.js
├── row-getSimpleData.js
├── simpleData.js
├── getSelect.js
├── row-getData.js
└── page-getData.js
├── src
├── indexEvents.js
├── getParam.js
├── index.js
├── getFocus.js
├── page-getMeta.js
├── row-simpleData.js
├── rowCurrent.js
├── getPage.js
├── param.js
├── page-meta.js
├── getCurrent.js
├── row-rowSelect.js
├── util.js
├── indexPage.js
├── row-getMeta.js
├── copyRow.js
├── enable.js
├── getMeta.js
├── removeRow.js
├── rowDelete.js
├── page-data.js
├── row-meta.js
├── page-removeRow.js
├── row-init.js
├── getSimpleData.js
├── row-getSimpleData.js
├── rowFocus.js
├── simpleData.js
├── getSelect.js
├── row-getData.js
├── page-getData.js
└── indexRow.js
├── .gitignore
├── LICENSE
├── rollup.config.js
├── gulpfile.js
├── examples
├── dataTableUse1-helloworld.html
├── knockout1-bind.html
├── dataTableUse3-alert.html
├── gettingstarted1-helloworld.html
├── validateapi1-validateapi.html
└── dataTableUse2-time.html
├── package.json
├── README.md
├── README_CN.md
└── webpack.config.js
/yarn.lock:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | .babelrc
--------------------------------------------------------------------------------
/snippets/knockout/demo/1-bind/说明.md:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/snippets/gettingstarted/demo/1-helloworld/说明.md:
--------------------------------------------------------------------------------
1 | ### Hello World示例
2 |
--------------------------------------------------------------------------------
/snippets/dataTableUse/demo/2-time/说明.md:
--------------------------------------------------------------------------------
1 | ### 示例:时间、日期指定格式
2 |
3 | 输入指定格式
4 |
--------------------------------------------------------------------------------
/snippets/dataTableUse/demo/1-helloworld/说明.md:
--------------------------------------------------------------------------------
1 | ### 示例:input输入框
2 |
3 | 输入长度6-12字符之间
4 |
--------------------------------------------------------------------------------
/snippets/dataTableUse/demo/3-alert/说明.md:
--------------------------------------------------------------------------------
1 | ### 示例:input输入框
2 |
3 | input输入值变化后,弹框提示
4 |
--------------------------------------------------------------------------------
/snippets/gettingstarted/demo/1-helloworld/widget.html:
--------------------------------------------------------------------------------
1 |
2 |
45 | <!-- ko通过data-bind绑定数据 -->
46 | <p>First name: <input data-bind="value: firstName" /></p>
47 | <p>Last name: <input data-bind="value: lastName" /></p>
48 | <h2>Hello, <span data-bind="text: fullName"> </span>!</h2>
49 |
50 |
51 |
52 |
53 | // 定义ViewModel
54 | var ViewModel = function(first, last) {
55 | // ko.observable可实时监听数据,实现绑定
56 | this.firstName = ko.observable(first);
57 | this.lastName = ko.observable(last);
58 |
59 | this.fullName = ko.pureComputed(function() {
60 | // ko.pureComputed用于执行计算,实时返回改变后的结果
61 | return this.firstName() + " " + this.lastName();
62 | }, this);
63 | };
64 |
65 | ko.applyBindings(new ViewModel("Planet", "Earth")); // 通过ko.applyBindings执行knockout
66 |
67 |
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var gulp = require('gulp');
4 | var path = require('path');
5 | var envPath = process.cwd();
6 | const fs = require('fs');
7 | const jsdoc2md = require('jsdoc-to-markdown');
8 | /**
9 | * 根据源文件地址数组、输出目录产出最终api
10 | * @param {array} sourceArr 文件地址
11 | * @param {string} rsPath 输出目录地址
12 | */
13 | function produceAPI(sourceArr, rsPath) {
14 | var apidocsPath = path.join(envPath, 'docs');
15 | const output = jsdoc2md.renderSync({ files: sourceArr })
16 | var isexist = fs.existsSync(apidocsPath);
17 | if (!isexist) {
18 | fs.mkdirSync(apidocsPath);
19 | }
20 | fs.writeFileSync(path.join(apidocsPath, rsPath), output)
21 | }
22 |
23 | gulp.task('docs', function() {
24 | //dataTable 源文件
25 | var dtSrcPath = ['indexDataTable.js', 'copyRow.js', 'data.js','enable.js','getCurrent.js','getData.js','getFocus.js','getMeta.js','getParam.js','getSelect.js','getSimpleData.js','meta.js','param.js','ref.js','removeRow.js','row.js','rowDelete.js','rowSelect.js','rowFocus.js','simpleData.js','events.js'];
26 |
27 | var rowSrcPath = ['indexRow.js','row-data.js','row-getData.js','row-getSimpleData.js','row-simpleData.js','row-rowSelect.js','row-getMeta.js','row-meta.js','row-ref.js'];
28 | //dataTable和row 源文件绝对路径地址
29 | var dtAbsolutePath = [],rowAbsolutePath = [];
30 | for (var i = 0; i < dtSrcPath.length; i++) {
31 | dtAbsolutePath.push(path.join(envPath, 'src/' + dtSrcPath[i]));
32 | // console.log("dataTable--"+dtAbsolutePath[i]);
33 | }
34 |
35 | for (var i = 0; i < rowSrcPath.length; i++) {
36 | rowAbsolutePath.push(path.join(envPath, 'src/' + rowSrcPath[i]));
37 | // console.log("row-----"+rowAbsolutePath[i]);
38 | }
39 |
40 | produceAPI(dtAbsolutePath, 'udatatable.md');
41 | produceAPI(rowAbsolutePath,'row.md');
42 | })
43 |
--------------------------------------------------------------------------------
/vendor/ace/theme-xcode.js:
--------------------------------------------------------------------------------
1 | define("ace/theme/xcode",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!1,t.cssClass="ace-xcode",t.cssText=".ace-xcode .ace_gutter {background: #e8e8e8;color: #333}.ace-xcode .ace_print-margin {width: 1px;background: #e8e8e8}.ace-xcode {background-color: #FFFFFF;color: #000000}.ace-xcode .ace_cursor {color: #000000}.ace-xcode .ace_marker-layer .ace_selection {background: #B5D5FF}.ace-xcode.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px #FFFFFF;}.ace-xcode .ace_marker-layer .ace_step {background: rgb(198, 219, 174)}.ace-xcode .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid #BFBFBF}.ace-xcode .ace_marker-layer .ace_active-line {background: rgba(0, 0, 0, 0.071)}.ace-xcode .ace_gutter-active-line {background-color: rgba(0, 0, 0, 0.071)}.ace-xcode .ace_marker-layer .ace_selected-word {border: 1px solid #B5D5FF}.ace-xcode .ace_constant.ace_language,.ace-xcode .ace_keyword,.ace-xcode .ace_meta,.ace-xcode .ace_variable.ace_language {color: #C800A4}.ace-xcode .ace_invisible {color: #BFBFBF}.ace-xcode .ace_constant.ace_character,.ace-xcode .ace_constant.ace_other {color: #275A5E}.ace-xcode .ace_constant.ace_numeric {color: #3A00DC}.ace-xcode .ace_entity.ace_other.ace_attribute-name,.ace-xcode .ace_support.ace_constant,.ace-xcode .ace_support.ace_function {color: #450084}.ace-xcode .ace_fold {background-color: #C800A4;border-color: #000000}.ace-xcode .ace_entity.ace_name.ace_tag,.ace-xcode .ace_support.ace_class,.ace-xcode .ace_support.ace_type {color: #790EAD}.ace-xcode .ace_storage {color: #C900A4}.ace-xcode .ace_string {color: #DF0002}.ace-xcode .ace_comment {color: #008E00}.ace-xcode .ace_indent-guide {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==) right repeat-y}";var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)})
--------------------------------------------------------------------------------
/.github/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | ## CONTRIBUTING.md
2 |
3 | 感谢所有社区贡献者,为助力完善`Tinper`全系列产品,本篇针对*bug反馈* & *pull request流程*作出说明
4 |
5 | * [Bug反馈](#bug)
6 |
7 | * [Pull Request流程图示](#pull)
8 |
9 |
10 |
11 | Bug反馈
12 |
13 | 1.提交途径
14 |
15 | * 推荐使用issue,
16 |
17 | > 简单,拖拽即可上传截图,方便反馈存档,利于帮助其他存在问题的人,避免重复问题
18 |
19 | 2.提交内容
20 |
21 | 针对存在问题反馈不够明确,建议提交包含以下内容,目前提供了一个[在线模板可供参考](https://github.com/iuap-design/neoui/issues/new?title=Bug:%20&body=**%E9%97%AE%E9%A2%98%E6%8F%8F%E8%BF%B0**%0A%EF%BC%88%E6%8F%8F%E8%BF%B0%E4%B8%80%E4%B8%8B%E9%97%AE%E9%A2%98%EF%BC%89%0A%0A**%E7%94%9F%E4%BA%A7%E7%8E%AF%E5%A2%83**%20%0A-%20%E6%B5%8F%E8%A7%88%E5%99%A8%E5%8F%8A%E7%89%88%E6%9C%AC%EF%BC%9A%20%0A-%20%E6%BC%94%E7%A4%BA%E5%9C%B0%E5%9D%80:%20%0A-%20%E6%B5%8F%E8%A7%88%E5%99%A8%E6%8A%A5%E9%94%99:%20%0A-%20%E6%88%AA%E5%9B%BE:),个人填写建议包含以下内容:
22 |
23 | ```
24 | **问题描述**
25 | (描述一下问题)
26 |
27 | **生产环境**
28 | - 浏览器及版本:
29 | - 演示地址:
30 | - 浏览器报错:
31 | - 截图:
32 | ```
33 |
34 |
35 |
36 | Pull Request流程图示
37 |
38 | 以 [neoui](https://github.com/iuap-design/neoui) 仓库为例:
39 |
40 | 1. Fork仓库到个人Respository目录:进入仓库,点击`Fork`
41 |
42 | 
43 |
44 | 2. Clone到本地
45 |
46 | ```
47 | $ git clone git@github.com:onvno/neoui.git
48 | ```
49 |
50 | 3. 创建分支
51 |
52 | ```
53 | $ git checkout -b fixer
54 | ```
55 |
56 | 4. 修改后提交
57 |
58 | ```
59 | $ git add .
60 | $ git commit -m "fix:some bug"
61 | $ git push origin fixer
62 | ```
63 |
64 | 5. 提交`pull request`:登陆github,进入`fork`后的仓库,切换到新提交的`fixer`分支,点击右侧绿色按钮`Compare& pull request`
65 |
66 | 
67 |
68 | 6. 添加注释信息,确认提交
69 |
70 | 
71 |
--------------------------------------------------------------------------------
/docs/gettingstarted.md:
--------------------------------------------------------------------------------
1 | # 起步
2 |
3 | ## 引入Kero文件及相关依赖
4 |
5 | ```
6 |
7 |
8 |
9 |
10 | Kero Getting Started
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | ```
22 |
23 | ## 兼容IE8
24 |
25 | 如需兼容IE8,需要在引入其他JS文件之前加载`u-polyfill.js`
26 |
27 | ```javascript
28 |
31 | ```
32 |
33 | ## 快速上手
34 |
35 | 绑定数据
36 |
37 |
38 |
39 |
40 | ## Hello World示例
41 |
42 |
43 |
44 | <!-- HTML -->
45 | <div id="demo_div"></div>
46 |
47 |
48 |
49 |
50 | // JS
51 | var app,viewModel;
52 |
53 | /**
54 | * `viewModel = {...}`创建数据模型
55 | * `dt1` 创建名为`dt1`的`u.DataTable`数据集
56 | * `f1` 创建名为`f1`的字段,为`dt1`数据集的一个子集
57 | */
58 | viewModel = {
59 | dt1: new u.DataTable({
60 | meta:{
61 | f1:{
62 | type:'string',
63 | maxLength:12
64 | }
65 | }
66 | })
67 | };
68 |
69 | /**
70 | * `app = u.createApp({...})`,页面初始化,创建框架服务
71 | * `el` 指定服务对应的顶层DOM
72 | * `setValue`进行赋值操作
73 | */
74 | app = u.createApp({
75 | el:'body',
76 | model:viewModel
77 | });
78 |
79 | var r = viewModel.dt1.createEmptyRow();
80 | r.setValue('f1','Hello World');
81 |
82 | /**
83 | * getValue 获取字段对应的值
84 | */
85 | var demoDiv = document.getElementById('demo_div');
86 | var dtVal = viewModel.dt1.getValue('f1');
87 | demoDiv.innerHTML = dtVal;
88 |
89 |
--------------------------------------------------------------------------------
/docs/install.md:
--------------------------------------------------------------------------------
1 | # 获取 `Kero` 资源
2 |
3 | kero资源已打包在`u.js`中,配合`u.css` , 依赖`jquery`实现完整前端UI方案。
4 |
5 | 如需使用到grid,tree相关插件,可选择添加对应的`css`和`js`文件,页面结构如下:
6 |
7 | ```
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | Hi, iuap design
24 |
25 |
26 |
27 |
28 |
29 |
30 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 | ```
47 | 完整资源可通过以下方式获取
48 |
49 | ## 1.直接下载资源包
50 |
51 | 可通过官网首页点击下载资源,获得完整资源包(包含空页面及所需样式),下载地址
52 |
53 | ```
54 | http://design.yonyoucloud.com/static/download/iuap-design-3.1.12.zip
55 | ```
56 | 核心文件`u.js`可通过以下方式获取
57 |
58 | ## 1.通过CDN引用
59 |
60 | ```
61 |
62 | ```
63 |
64 | ## 2.获取Kero源码
65 |
66 | ```
67 | $ git clone git@github.com:iuap-design/kero.git
68 | ```
69 |
70 | ## 3.NPM
71 |
72 | ```
73 | $ npm install kero --save
74 | ```
75 |
--------------------------------------------------------------------------------
/snippets/install/base.md:
--------------------------------------------------------------------------------
1 | ## 获取 `Kero` 资源
2 |
3 | kero资源已打包在`u.js`中,配合`u.css` , 依赖`jquery`实现完整前端UI方案。
4 |
5 | 如需使用到grid,tree相关插件,可选择添加对应的`css`和`js`文件,页面结构如下:
6 |
7 | ```
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | Hi, iuap design
24 |
25 |
26 |
27 |
28 |
29 |
30 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 | ```
47 | 完整资源可通过以下方式获取
48 |
49 | ### 1.直接下载资源包
50 |
51 | 可通过官网首页点击下载资源,获得完整资源包(包含空页面及所需样式),下载地址
52 |
53 | ```
54 | http://design.yonyoucloud.com/static/download/iuap-design-3.1.12.zip
55 | ```
56 | 核心文件`u.js`可通过以下方式获取
57 |
58 | ### 1.通过CDN引用
59 |
60 | ```
61 |
62 | ```
63 |
64 | ### 2.获取Kero源码
65 |
66 | ```
67 | $ git clone git@github.com:iuap-design/kero.git
68 | ```
69 |
70 | ### 3.NPM
71 |
72 | ```
73 | $ npm install kero --save
74 | ```
75 |
--------------------------------------------------------------------------------
/src/removeRow.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module : kero dataTable removeRow
3 | * Author : liuyk(liuyk@yonyou.com)
4 | * Date : 2016-08-01 14:34:01
5 | */
6 | import {
7 | utilFunObj
8 | } from './util';
9 |
10 | /**
11 | * 根据rowId删除指定行
12 | * @memberof DataTable
13 | * @param {string} rowId 需要删除行的rowId
14 | * @example
15 | * datatable.removeRowByRowId('rowid1')
16 | */
17 | const removeRowByRowId = function(rowId) {
18 | var index = this.getIndexByRowId(rowId)
19 | if (index != -1)
20 | this.removeRow(index)
21 | }
22 |
23 | /**
24 | *根据索引删除指定行
25 | * @memberof DataTable
26 | * @param {number} index 需要删除行的索引
27 | * @example
28 | * datatable.removeRow(1)
29 | */
30 | const removeRow = function(index) {
31 | if (index instanceof Row) {
32 | index = this.getIndexByRowId(index.rowId)
33 | }
34 | this.removeRows([index]);
35 | }
36 |
37 | /**
38 | * 删除所有行
39 | * @memberof DataTable
40 | * @example
41 | * datatable.removeAllRows();
42 | */
43 | const removeAllRows = function() {
44 | this.rows([])
45 | this.selectedIndices([])
46 | this.focusIndex(-1)
47 | this.trigger(DataTable.ON_DELETE_ALL)
48 | this.updateCurrIndex();
49 | }
50 |
51 | /**
52 | * 根据索引数据删除多条数据行
53 | * @memberof DataTable
54 | * @param {array} indices 需要删除的数据行对应数组,数组中既可以是索引也可以是row对象
55 | * @example
56 | * datatable.removeRows([1,2])
57 | * datatable.removeRows([row1,row2])
58 | */
59 | const removeRows = function(indices, obj) {
60 | this.setRowsDelete(indices, obj)
61 | }
62 |
63 |
64 | /**
65 | * 清空datatable的所有数据以及分页数据以及index
66 | * @memberof DataTable
67 | * @example
68 | * datatable.clear()
69 | */
70 | const clear = function() {
71 | this.removeAllRows();
72 | this.cachedPages = [];
73 | this.totalPages(1);
74 | this.pageIndex(0);
75 | this.focusIndex(-1);
76 | this.selectedIndices([]);
77 | }
78 |
79 | export const removeRowFunObj = {
80 | removeRowByRowId: removeRowByRowId,
81 | removeRow: removeRow,
82 | removeAllRows: removeAllRows,
83 | removeRows: removeRows,
84 | clear: clear
85 | }
86 |
--------------------------------------------------------------------------------
/lib/removeRow.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module : kero dataTable removeRow
3 | * Author : liuyk(liuyk@yonyou.com)
4 | * Date : 2016-08-01 14:34:01
5 | */
6 | import { utilFunObj } from './util';
7 |
8 | /**
9 | * 根据rowId删除指定行
10 | * @memberof DataTable
11 | * @param {string} rowId 需要删除行的rowId
12 | * @example
13 | * datatable.removeRowByRowId('rowid1')
14 | */
15 | var removeRowByRowId = function removeRowByRowId(rowId) {
16 | var index = this.getIndexByRowId(rowId);
17 | if (index != -1) this.removeRow(index);
18 | };
19 |
20 | /**
21 | *根据索引删除指定行
22 | * @memberof DataTable
23 | * @param {number} index 需要删除行的索引
24 | * @example
25 | * datatable.removeRow(1)
26 | */
27 | var removeRow = function removeRow(index) {
28 | if (index instanceof Row) {
29 | index = this.getIndexByRowId(index.rowId);
30 | }
31 | this.removeRows([index]);
32 | };
33 |
34 | /**
35 | * 删除所有行
36 | * @memberof DataTable
37 | * @example
38 | * datatable.removeAllRows();
39 | */
40 | var removeAllRows = function removeAllRows() {
41 | this.rows([]);
42 | this.selectedIndices([]);
43 | this.focusIndex(-1);
44 | this.trigger(DataTable.ON_DELETE_ALL);
45 | this.updateCurrIndex();
46 | };
47 |
48 | /**
49 | * 根据索引数据删除多条数据行
50 | * @memberof DataTable
51 | * @param {array} indices 需要删除的数据行对应数组,数组中既可以是索引也可以是row对象
52 | * @example
53 | * datatable.removeRows([1,2])
54 | * datatable.removeRows([row1,row2])
55 | */
56 | var removeRows = function removeRows(indices, obj) {
57 | this.setRowsDelete(indices, obj);
58 | };
59 |
60 | /**
61 | * 清空datatable的所有数据以及分页数据以及index
62 | * @memberof DataTable
63 | * @example
64 | * datatable.clear()
65 | */
66 | var clear = function clear() {
67 | this.removeAllRows();
68 | this.cachedPages = [];
69 | this.totalPages(1);
70 | this.pageIndex(0);
71 | this.focusIndex(-1);
72 | this.selectedIndices([]);
73 | };
74 |
75 | export var removeRowFunObj = {
76 | removeRowByRowId: removeRowByRowId,
77 | removeRow: removeRow,
78 | removeAllRows: removeAllRows,
79 | removeRows: removeRows,
80 | clear: clear
81 | };
--------------------------------------------------------------------------------
/vendor/ace/theme-github.js:
--------------------------------------------------------------------------------
1 | define("ace/theme/github",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!1,t.cssClass="ace-github",t.cssText='.ace-github .ace_gutter {background: #e8e8e8;color: #AAA;}.ace-github {background: #fff;color: #000;}.ace-github .ace_keyword {font-weight: bold;}.ace-github .ace_string {color: #D14;}.ace-github .ace_variable.ace_class {color: teal;}.ace-github .ace_constant.ace_numeric {color: #099;}.ace-github .ace_constant.ace_buildin {color: #0086B3;}.ace-github .ace_support.ace_function {color: #0086B3;}.ace-github .ace_comment {color: #998;font-style: italic;}.ace-github .ace_variable.ace_language {color: #0086B3;}.ace-github .ace_paren {font-weight: bold;}.ace-github .ace_boolean {font-weight: bold;}.ace-github .ace_string.ace_regexp {color: #009926;font-weight: normal;}.ace-github .ace_variable.ace_instance {color: teal;}.ace-github .ace_constant.ace_language {font-weight: bold;}.ace-github .ace_cursor {color: black;}.ace-github.ace_focus .ace_marker-layer .ace_active-line {background: rgb(255, 255, 204);}.ace-github .ace_marker-layer .ace_active-line {background: rgb(245, 245, 245);}.ace-github .ace_marker-layer .ace_selection {background: rgb(181, 213, 255);}.ace-github.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px white;}.ace-github.ace_nobold .ace_line > span {font-weight: normal !important;}.ace-github .ace_marker-layer .ace_step {background: rgb(252, 255, 0);}.ace-github .ace_marker-layer .ace_stack {background: rgb(164, 229, 101);}.ace-github .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid rgb(192, 192, 192);}.ace-github .ace_gutter-active-line {background-color : rgba(0, 0, 0, 0.07);}.ace-github .ace_marker-layer .ace_selected-word {background: rgb(250, 250, 255);border: 1px solid rgb(200, 200, 250);}.ace-github .ace_invisible {color: #BFBFBF}.ace-github .ace_print-margin {width: 1px;background: #e8e8e8;}.ace-github .ace_indent-guide {background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==") right repeat-y;}';var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)})
--------------------------------------------------------------------------------
/examples/dataTableUse1-helloworld.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Title
7 |
8 |
9 |
10 |
11 |
12 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/src/rowDelete.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module : kero dataTable rowDelete
3 | * Desc: 不建议使用此库方法
4 | * Author : liuyk(liuyk@yonyou.com)
5 | * Date : 2016-08-01 14:34:01
6 | */
7 | import {
8 | utilFunObj
9 | } from './util';
10 |
11 | /***
12 | * 根据索引删除数据行
13 | * @param {number} index 需要删除数据行的索引
14 | */
15 | const setRowDelete = function(index) {
16 | if (index instanceof Row) {
17 | index = this.getIndexByRowId(index.rowId)
18 | }
19 | this.setRowsDelete([index])
20 | }
21 |
22 | /***
23 | * 删除所有数据行
24 | */
25 | const setAllRowsDelete = function() {
26 | var indices = new Array(this.rows().length)
27 | for (var i = 0; i < indices.length; i++) {
28 | indices[i] = i
29 | }
30 | this.setRowsDelete(indices)
31 | }
32 |
33 | /***
34 | * 根据索引数组删除数据行
35 | * @param {Array} indices 需要删除数据行的索引数组
36 | */
37 | const setRowsDelete = function(indices, obj) {
38 | var forceDel = obj ? obj.forceDel : false;
39 | indices = utilFunObj._formatToIndicesArray(this, indices)
40 | indices = indices.sort(function(a, b) {
41 | return b - a;
42 | });
43 | var rowIds = this.getRowIdsByIndices(indices)
44 | var rows = this.getRowsByIndices(indices);
45 | var ros = this.rows();
46 | for (var i = 0; i < indices.length; i++) {
47 | var row = this.getRow(indices[i]);
48 | if (row.status == Row.STATUS.NEW || this.forceDel || forceDel) {
49 | ros.splice(indices[i], 1);
50 | } else {
51 | row.setStatus(Row.STATUS.FALSE_DELETE);
52 | var temprows = ros.splice(indices[i], 1);
53 | ros.push(temprows[0]);
54 | }
55 | this.updateSelectedIndices(indices[i], '-');
56 | this.updateFocusIndex(indices[i], '-');
57 | }
58 | this.rows(ros);
59 | this.updateCurrIndex();
60 | this.trigger(DataTable.ON_DELETE, {
61 | falseDelete: true,
62 | indices: indices,
63 | rowIds: rowIds,
64 | rows: rows
65 | })
66 |
67 | }
68 |
69 | export const rowDeleteFunObj = {
70 | setRowDelete: setRowDelete,
71 | setAllRowsDelete: setAllRowsDelete,
72 | setRowsDelete: setRowsDelete
73 | }
74 |
--------------------------------------------------------------------------------
/lib/rowDelete.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module : kero dataTable rowDelete
3 | * Desc: 不建议使用此库方法
4 | * Author : liuyk(liuyk@yonyou.com)
5 | * Date : 2016-08-01 14:34:01
6 | */
7 | import { utilFunObj } from './util';
8 |
9 | /***
10 | * 根据索引删除数据行
11 | * @param {number} index 需要删除数据行的索引
12 | */
13 | var setRowDelete = function setRowDelete(index) {
14 | if (index instanceof Row) {
15 | index = this.getIndexByRowId(index.rowId);
16 | }
17 | this.setRowsDelete([index]);
18 | };
19 |
20 | /***
21 | * 删除所有数据行
22 | */
23 | var setAllRowsDelete = function setAllRowsDelete() {
24 | var indices = new Array(this.rows().length);
25 | for (var i = 0; i < indices.length; i++) {
26 | indices[i] = i;
27 | }
28 | this.setRowsDelete(indices);
29 | };
30 |
31 | /***
32 | * 根据索引数组删除数据行
33 | * @param {Array} indices 需要删除数据行的索引数组
34 | */
35 | var setRowsDelete = function setRowsDelete(indices, obj) {
36 | var forceDel = obj ? obj.forceDel : false;
37 | indices = utilFunObj._formatToIndicesArray(this, indices);
38 | indices = indices.sort(function (a, b) {
39 | return b - a;
40 | });
41 | var rowIds = this.getRowIdsByIndices(indices);
42 | var rows = this.getRowsByIndices(indices);
43 | var ros = this.rows();
44 | for (var i = 0; i < indices.length; i++) {
45 | var row = this.getRow(indices[i]);
46 | if (row.status == Row.STATUS.NEW || this.forceDel || forceDel) {
47 | ros.splice(indices[i], 1);
48 | } else {
49 | row.setStatus(Row.STATUS.FALSE_DELETE);
50 | var temprows = ros.splice(indices[i], 1);
51 | ros.push(temprows[0]);
52 | }
53 | this.updateSelectedIndices(indices[i], '-');
54 | this.updateFocusIndex(indices[i], '-');
55 | }
56 | this.rows(ros);
57 | this.updateCurrIndex();
58 | this.trigger(DataTable.ON_DELETE, {
59 | falseDelete: true,
60 | indices: indices,
61 | rowIds: rowIds,
62 | rows: rows
63 | });
64 | };
65 |
66 | export var rowDeleteFunObj = {
67 | setRowDelete: setRowDelete,
68 | setAllRowsDelete: setAllRowsDelete,
69 | setRowsDelete: setRowsDelete
70 | };
--------------------------------------------------------------------------------
/examples/knockout1-bind.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Title
7 |
8 |
9 |
10 |
11 |
12 |
14 |
15 |
16 |
17 | First name:
18 | Last name:
19 | Hello, !
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/lib/page-data.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module : kero dataTable page data
3 | * Author : liuyk(liuyk@yonyou.com)
4 | * Date : 2016-08-08 09:59:01
5 | */
6 |
7 | /**
8 | * 根据行序号设置字段值
9 | * @memberof Page
10 | * @param {number} rowIndex 行序号
11 | * @param {string} fieldName 字段名称
12 | * @param {string} value 字段值
13 | * @example
14 | * page.setRowValue(1,'field1','value1')
15 | */
16 | var setRowValue = function setRowValue(rowIndex, fieldName, value) {
17 | var row = this.rows[rowIndex];
18 | if (row) {
19 | row.data[fieldName]['value'] = value;
20 | if (row.status != Row.STATUS.NEW) row.setStatus(Row.STATUS.UPDATE);
21 | }
22 | };
23 |
24 | // 通过row对象更新row对象,不建议次方法
25 | var updateRow = function updateRow(originRow, newRow) {
26 | // originRow.status = originRow.status
27 | //this.rowId = data.rowId
28 | if (!newRow.data) return;
29 | for (var key in newRow.data) {
30 | if (originRow.data[key]) {
31 | var valueObj = newRow.data[key];
32 | if (typeof valueObj == 'string' || typeof valueObj == 'number' || valueObj === null) originRow.data[key]['value'] = valueObj;
33 | //this.setValue(key, this.formatValue(key, valueObj))
34 | else {
35 | // this.setValue(key, valueObj.value)
36 |
37 | if (valueObj.error) {
38 | if (u.showMessageDialog) u.showMessageDialog({
39 | title: "警告",
40 | msg: valueObj.error,
41 | backdrop: true
42 | });else alert(valueObj.error);
43 | } else {
44 | //this.setValue(key, this.formatValue(key, valueObj.value), null)
45 | originRow.data[key]['value'] = valueObj.value;
46 | for (var k in valueObj.meta) {
47 | originRow.data[key]['meta'] = originRow.data[key]['meta'] || {};
48 | originRow.data[key]['meta'][k] = valueObj.meta[k];
49 | }
50 | }
51 | }
52 | }
53 | }
54 | };
55 |
56 | export var pageDataFunObj = {
57 | setRowValue: setRowValue,
58 | updateRow: updateRow
59 | };
--------------------------------------------------------------------------------
/lib/row-meta.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module : kero dataTable row meta
3 | * Author : liuyk(liuyk@yonyou.com)
4 | * Date : 2016-08-08 13:54:01
5 | */
6 | import { rowUtilFunObj } from './row-util';
7 |
8 | /**
9 | * 设置meta信息
10 | * @memberof Row
11 | * @param {string} fieldName 需要设置meta信息的字段名
12 | * @param {string} key meta信息的key
13 | * @param {string} value meta信息的值
14 | * @example
15 | * row.setMeta('filed1','type','string')
16 | */
17 | var setMeta = function setMeta(fieldName, key, value) {
18 | var meta = rowUtilFunObj._getField(this, fieldName).meta;
19 | if (!meta) meta = rowUtilFunObj._getField(this, fieldName).meta = {};
20 | var oldValue = meta[key];
21 | if (rowUtilFunObj.eq(oldValue, value)) return;
22 | meta[key] = value;
23 | //this.metaChange(- this.metaChange())
24 | if (this.metaChange[fieldName + '.' + key]) {
25 | this.metaChange[fieldName + '.' + key](-this.metaChange[fieldName + '.' + key]());
26 | }
27 |
28 | if (key == 'enable') this.parent.enableChange(-this.parent.enableChange());
29 | if (this.parent.getCurrentRow() == this) {
30 | if (this.parent.metaChange[fieldName + '.' + key]) this.parent.metaChange[fieldName + '.' + key](-this.parent.metaChange[fieldName + '.' + key]());
31 | this.parent.trigger(fieldName + '.' + key + '.' + DataTable.ON_CURRENT_META_CHANGE, {
32 | eventType: 'dataTableEvent',
33 | dataTable: this.parent.id,
34 | oldValue: oldValue,
35 | newValue: value
36 | });
37 | //this.parent.metaChange(- this.parent.metaChange())
38 | }
39 | this.parent.trigger(DataTable.ON_ROW_META_CHANGE, {
40 | eventType: 'dataTableEvent',
41 | dataTable: this.parent.id,
42 | field: fieldName,
43 | meta: key,
44 | oldValue: oldValue,
45 | newValue: value,
46 | row: this
47 | });
48 |
49 | this.parent.trigger(fieldName + '.' + key + '.' + DataTable.ON_ROW_META_CHANGE, {
50 | eventType: 'dataTableEvent',
51 | dataTable: this.parent.id,
52 | field: fieldName,
53 | meta: key,
54 | oldValue: oldValue,
55 | newValue: value,
56 | row: this
57 | });
58 | };
59 |
60 | export var rowMetaFunObj = {
61 | setMeta: setMeta
62 | };
--------------------------------------------------------------------------------
/examples/dataTableUse3-alert.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Title
7 |
8 |
9 |
10 |
11 |
12 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/src/page-data.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module : kero dataTable page data
3 | * Author : liuyk(liuyk@yonyou.com)
4 | * Date : 2016-08-08 09:59:01
5 | */
6 |
7 | /**
8 | * 根据行序号设置字段值
9 | * @memberof Page
10 | * @param {number} rowIndex 行序号
11 | * @param {string} fieldName 字段名称
12 | * @param {string} value 字段值
13 | * @example
14 | * page.setRowValue(1,'field1','value1')
15 | */
16 | const setRowValue = function(rowIndex, fieldName, value) {
17 | var row = this.rows[rowIndex]
18 | if (row) {
19 | row.data[fieldName]['value'] = value
20 | if (row.status != Row.STATUS.NEW)
21 | row.setStatus(Row.STATUS.UPDATE)
22 | }
23 | }
24 |
25 |
26 |
27 | // 通过row对象更新row对象,不建议次方法
28 | const updateRow = function(originRow, newRow) {
29 | // originRow.status = originRow.status
30 | //this.rowId = data.rowId
31 | if (!newRow.data) return;
32 | for (var key in newRow.data) {
33 | if (originRow.data[key]) {
34 | var valueObj = newRow.data[key]
35 | if (typeof valueObj == 'string' || typeof valueObj == 'number' || valueObj === null)
36 | originRow.data[key]['value'] = valueObj
37 | //this.setValue(key, this.formatValue(key, valueObj))
38 | else {
39 | // this.setValue(key, valueObj.value)
40 |
41 | if (valueObj.error) {
42 | if (u.showMessageDialog)
43 | u.showMessageDialog({
44 | title: "警告",
45 | msg: valueObj.error,
46 | backdrop: true
47 | });
48 | else
49 | alert(valueObj.error)
50 | } else {
51 | //this.setValue(key, this.formatValue(key, valueObj.value), null)
52 | originRow.data[key]['value'] = valueObj.value
53 | for (var k in valueObj.meta) {
54 | originRow.data[key]['meta'] = originRow.data[key]['meta'] || {}
55 | originRow.data[key]['meta'][k] = valueObj.meta[k]
56 | }
57 | }
58 | }
59 | }
60 | }
61 | }
62 |
63 | export const pageDataFunObj = {
64 | setRowValue: setRowValue,
65 | updateRow: updateRow
66 | }
67 |
--------------------------------------------------------------------------------
/src/row-meta.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module : kero dataTable row meta
3 | * Author : liuyk(liuyk@yonyou.com)
4 | * Date : 2016-08-08 13:54:01
5 | */
6 | import {
7 | rowUtilFunObj
8 | } from './row-util';
9 |
10 | /**
11 | * 设置meta信息
12 | * @memberof Row
13 | * @param {string} fieldName 需要设置meta信息的字段名
14 | * @param {string} key meta信息的key
15 | * @param {string} value meta信息的值
16 | * @example
17 | * row.setMeta('filed1','type','string')
18 | */
19 | const setMeta = function(fieldName, key, value) {
20 | var meta = rowUtilFunObj._getField(this, fieldName).meta
21 | if (!meta)
22 | meta = rowUtilFunObj._getField(this, fieldName).meta = {}
23 | var oldValue = meta[key]
24 | if (rowUtilFunObj.eq(oldValue, value)) return;
25 | meta[key] = value
26 | //this.metaChange(- this.metaChange())
27 | if (this.metaChange[fieldName + '.' + key]) {
28 | this.metaChange[fieldName + '.' + key](-this.metaChange[fieldName + '.' + key]());
29 | }
30 |
31 | if (key == 'enable')
32 | this.parent.enableChange(-this.parent.enableChange())
33 | if (this.parent.getCurrentRow() == this) {
34 | if (this.parent.metaChange[fieldName + '.' + key])
35 | this.parent.metaChange[fieldName + '.' + key](-this.parent.metaChange[fieldName + '.' + key]());
36 | this.parent.trigger(fieldName + '.' + key + '.' + DataTable.ON_CURRENT_META_CHANGE, {
37 | eventType: 'dataTableEvent',
38 | dataTable: this.parent.id,
39 | oldValue: oldValue,
40 | newValue: value
41 | });
42 | //this.parent.metaChange(- this.parent.metaChange())
43 | }
44 | this.parent.trigger(DataTable.ON_ROW_META_CHANGE, {
45 | eventType: 'dataTableEvent',
46 | dataTable: this.parent.id,
47 | field: fieldName,
48 | meta: key,
49 | oldValue: oldValue,
50 | newValue: value,
51 | row: this
52 | });
53 |
54 | this.parent.trigger(fieldName + '.' + key + '.' + DataTable.ON_ROW_META_CHANGE, {
55 | eventType: 'dataTableEvent',
56 | dataTable: this.parent.id,
57 | field: fieldName,
58 | meta: key,
59 | oldValue: oldValue,
60 | newValue: value,
61 | row: this
62 | });
63 | }
64 |
65 |
66 | export const rowMetaFunObj = {
67 | setMeta: setMeta
68 | }
69 |
--------------------------------------------------------------------------------
/lib/row-init.js:
--------------------------------------------------------------------------------
1 | /***
2 | * Module : kero dataTable row init
3 | * Author : liuyk(liuyk@yonyou.com)
4 | * Date : 2016-08-08 13:54:01
5 | */
6 |
7 | // row的初始化方法
8 | var init = function init() {
9 | var meta = this.parent.meta;
10 |
11 | for (var key in meta) {
12 | var targetData;
13 | if (key.indexOf('.') > 0) {
14 | var keys = key.split('.');
15 | targetData = this.data[keys[0]] = this.data[keys[0]] || {};
16 | for (var i = 1; i < keys.length; i++) {
17 | targetData[keys[i]] = targetData[keys[i]] || {};
18 | targetData = targetData[keys[i]];
19 | }
20 | } else {
21 | this.data[key] = this.data[key] || {};
22 | targetData = this.data[key];
23 | }
24 | targetData.value = null;
25 | //this.data[key] = {}
26 | //处理子表
27 | if (meta[key]['type'] && meta[key]['type'] === 'child') {
28 | targetData.isChild = true;
29 | //ns 是多级数据时的空间名: 最顶层的dataTable没有ns。 f1.f2.f3
30 | var ns = this.parent.ns === '' ? key : this.parent.ns + '.' + key;
31 | targetData.value = new u.DataTable({
32 | root: this.parent.root,
33 | ns: ns,
34 | meta: meta[key]['meta']
35 | });
36 | }
37 | //添加默认值
38 | else if (meta[key]['default']) {
39 | var defaults = meta[key]['default'];
40 | if ((typeof defaults === 'undefined' ? 'undefined' : babelHelpers['typeof'](defaults)) === 'object') {
41 | for (var k in defaults) {
42 | if (k == 'value') {
43 | if (typeof defaults[k] === 'function') targetData.value = this.formatValue(key, defaults[k]());else targetData.value = this.formatValue(key, defaults[k]);
44 | } else {
45 | targetData.meta = targetData.meta || {};
46 | targetData.meta[k] = defaults[k];
47 | }
48 | }
49 | } else {
50 | if (typeof defaults === 'function') targetData.value = this.formatValue(key, defaults());else targetData.value = this.formatValue(key, defaults);
51 | }
52 | }
53 | }
54 | };
55 |
56 | export var rowInitFunObj = {
57 | init: init
58 | };
--------------------------------------------------------------------------------
/lib/page-removeRow.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module : kero dataTable page removeRow
3 | * Author : liuyk(liuyk@yonyou.com)
4 | * Date : 2016-08-08 09:59:01
5 | */
6 |
7 | import { isNumber } from 'tinper-sparrow/src/util';
8 |
9 | /**
10 | * 根据rowid删除行
11 | * @param {string} rowid 需要删除行的rowid
12 | * @example
13 | * page.removeRowByRowId('rowid1')
14 | */
15 | var removeRowByRowId = function removeRowByRowId(rowid) {
16 | for (var i = 0, count = this.rows.length; i < count; i++) {
17 | if (this.rows[i].rowId == rowid) {
18 | this.rows.splice(i, 1);
19 | count--;
20 | this.updateSelectedIndices(i, '-');
21 | this.updateFocusIndex(i, '-');
22 | }
23 | }
24 | };
25 |
26 | // 新增/删除行之后更新选中行的index
27 | var updateSelectedIndices = function updateSelectedIndices(index, type, num) {
28 | if (!isNumber(num)) {
29 | num = 1;
30 | }
31 | var selectedIndices = this.selectedIndices.slice();
32 | if (selectedIndices == null || selectedIndices.length == 0) return;
33 | for (var i = 0, count = selectedIndices.length; i < count; i++) {
34 | if (type == '+') {
35 | if (selectedIndices[i] >= index) selectedIndices[i] = parseInt(selectedIndices[i]) + num;
36 | } else if (type == '-') {
37 | if (selectedIndices[i] >= index && selectedIndices[i] <= index + num - 1) {
38 | selectedIndices.splice(i, 1);
39 | } else if (selectedIndices[i] > index + num - 1) selectedIndices[i] = selectedIndices[i] - num;
40 | }
41 | }
42 | this.selectedIndices = selectedIndices;
43 | };
44 |
45 | //新增/删除行之后更新焦点行
46 | var updateFocusIndex = function updateFocusIndex(opIndex, opType, num) {
47 | if (!isNumber(num)) {
48 | num = 1;
49 | }
50 | if (opIndex <= this.focus && this.focus != -1) {
51 | if (opType === '+') {
52 | this.focus = this.focus + num;
53 | } else if (opType === '-') {
54 | if (this.focus >= opIndex && this.focus <= opIndex + num - 1) {
55 | this.focus = this.focus - 1;
56 | } else if (this.focus > opIndex + num - 1) {
57 | this.focus = this.focus - num;
58 | }
59 | }
60 | }
61 | };
62 |
63 | export var pageRemoveRowFunObj = {
64 | removeRowByRowId: removeRowByRowId,
65 | updateSelectedIndices: updateSelectedIndices,
66 | updateFocusIndex: updateFocusIndex
67 | };
--------------------------------------------------------------------------------
/src/page-removeRow.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module : kero dataTable page removeRow
3 | * Author : liuyk(liuyk@yonyou.com)
4 | * Date : 2016-08-08 09:59:01
5 | */
6 |
7 | import {
8 | isNumber
9 | } from 'tinper-sparrow/src/util';
10 |
11 | /**
12 | * 根据rowid删除行
13 | * @param {string} rowid 需要删除行的rowid
14 | * @example
15 | * page.removeRowByRowId('rowid1')
16 | */
17 | const removeRowByRowId = function(rowid) {
18 | for (var i = 0, count = this.rows.length; i < count; i++) {
19 | if (this.rows[i].rowId == rowid) {
20 | this.rows.splice(i, 1);
21 | count--;
22 | this.updateSelectedIndices(i, '-')
23 | this.updateFocusIndex(i, '-')
24 | }
25 | }
26 | }
27 |
28 | // 新增/删除行之后更新选中行的index
29 | const updateSelectedIndices = function(index, type, num) {
30 | if (!isNumber(num)) {
31 | num = 1
32 | }
33 | var selectedIndices = this.selectedIndices.slice();
34 | if (selectedIndices == null || selectedIndices.length == 0)
35 | return
36 | for (var i = 0, count = selectedIndices.length; i < count; i++) {
37 | if (type == '+') {
38 | if (selectedIndices[i] >= index)
39 | selectedIndices[i] = parseInt(selectedIndices[i]) + num
40 | } else if (type == '-') {
41 | if (selectedIndices[i] >= index && selectedIndices[i] <= index + num - 1) {
42 | selectedIndices.splice(i, 1)
43 | } else if (selectedIndices[i] > index + num - 1)
44 | selectedIndices[i] = selectedIndices[i] - num
45 | }
46 | }
47 | this.selectedIndices = selectedIndices
48 | }
49 |
50 | //新增/删除行之后更新焦点行
51 | const updateFocusIndex = function(opIndex, opType, num) {
52 | if (!isNumber(num)) {
53 | num = 1
54 | }
55 | if (opIndex <= this.focus && this.focus != -1) {
56 | if (opType === '+') {
57 | this.focus = this.focus + num
58 | } else if (opType === '-') {
59 | if (this.focus >= opIndex && this.focus <= opIndex + num - 1) {
60 | this.focus = this.focus - 1
61 | } else if (this.focus > opIndex + num - 1) {
62 | this.focus = this.focus - num
63 | }
64 | }
65 | }
66 | }
67 |
68 |
69 | export const pageRemoveRowFunObj = {
70 | removeRowByRowId: removeRowByRowId,
71 | updateSelectedIndices: updateSelectedIndices,
72 | updateFocusIndex: updateFocusIndex
73 | }
74 |
--------------------------------------------------------------------------------
/src/row-init.js:
--------------------------------------------------------------------------------
1 | /***
2 | * Module : kero dataTable row init
3 | * Author : liuyk(liuyk@yonyou.com)
4 | * Date : 2016-08-08 13:54:01
5 | */
6 |
7 | // row的初始化方法
8 | const init = function() {
9 | var meta = this.parent.meta;
10 |
11 | for (var key in meta) {
12 | var targetData;
13 | if (key.indexOf('.') > 0) {
14 | var keys = key.split('.');
15 | targetData = this.data[keys[0]] = this.data[keys[0]] || {};
16 | for (var i = 1; i < keys.length; i++) {
17 | targetData[keys[i]] = targetData[keys[i]] || {};
18 | targetData = targetData[keys[i]];
19 | }
20 | } else {
21 | this.data[key] = this.data[key] || {}
22 | targetData = this.data[key];
23 | }
24 | targetData.value = null;
25 | //this.data[key] = {}
26 | //处理子表
27 | if (meta[key]['type'] && meta[key]['type'] === 'child') {
28 | targetData.isChild = true;
29 | //ns 是多级数据时的空间名: 最顶层的dataTable没有ns。 f1.f2.f3
30 | var ns = this.parent.ns === '' ? key : this.parent.ns + '.' + key
31 | targetData.value = new u.DataTable({
32 | root: this.parent.root,
33 | ns: ns,
34 | meta: meta[key]['meta']
35 | });
36 | }
37 | //添加默认值
38 | else if (meta[key]['default']) {
39 | var defaults = meta[key]['default']
40 | if (typeof defaults === 'object') {
41 | for (var k in defaults) {
42 | if (k == 'value') {
43 | if (typeof defaults[k] === 'function')
44 | targetData.value = this.formatValue(key, defaults[k]());
45 | else
46 | targetData.value = this.formatValue(key, defaults[k]);
47 | } else {
48 | targetData.meta = targetData.meta || {}
49 | targetData.meta[k] = defaults[k]
50 | }
51 | }
52 | } else {
53 | if (typeof defaults === 'function')
54 | targetData.value = this.formatValue(key, defaults());
55 | else
56 | targetData.value = this.formatValue(key, defaults);
57 | }
58 | }
59 | }
60 | }
61 |
62 |
63 | export const rowInitFunObj = {
64 | init: init
65 | }
66 |
--------------------------------------------------------------------------------
/examples/gettingstarted1-helloworld.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Title
7 |
8 |
9 |
10 |
11 |
12 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "kero",
3 | "version": "3.2.5",
4 | "description": "",
5 | "main": "src/index",
6 | "scripts": {
7 | "r-watch": "rollup -c -w",
8 | "r-build": "rollup -c",
9 | "build": "webpack --colors --progress --env.mode=build",
10 | "dev": "webpack --progress --colors --env.mode=dev",
11 | "test": "mocha --compilers js:babel-core/register --colors -w ./test/*.spec.js",
12 | "es": "babel src -d lib",
13 | "product": "npm run es && npm run r-build",
14 | "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0 ",
15 | "docs": "node bin/mdconcat.js",
16 | "makeAPI": "gulp docs && sh bin/docMutilLang.sh"
17 | },
18 | "directories": {
19 | "doc": "docs",
20 | "example": "examples"
21 | },
22 | "dependencies": {
23 | "tinper-sparrow": "^3.2.4"
24 | },
25 | "devDependencies": {
26 | "babel-cli": "^6.11.4",
27 | "babel-core": "^6.13.2",
28 | "babel-eslint": "^6.1.2",
29 | "babel-loader": "^6.2.0",
30 | "babel-plugin-add-module-exports": "^0.2.1",
31 | "babel-plugin-external-helpers": "^6.22.0",
32 | "babel-plugin-transform-es2015-modules-commonjs": "^6.11.5",
33 | "babel-plugin-transform-es2015-modules-umd": "^6.23.0",
34 | "babel-plugin-transform-es3-member-expression-literals": "^6.8.0",
35 | "babel-plugin-transform-es3-property-literals": "^6.8.0",
36 | "babel-polyfill": "^6.3.14",
37 | "babel-preset-es2015": "^6.3.13",
38 | "babel-preset-es2015-loose": "^8.0.0",
39 | "babel-preset-latest": "^6.24.1",
40 | "babel-preset-stage-0": "^6.5.0",
41 | "chai": "^3.5.0",
42 | "deepmerge": "^1.3.2",
43 | "eslint": "^3.2.2",
44 | "eslint-loader": "^1.5.0",
45 | "file": "^0.2.2",
46 | "fs-extra": "^2.0.0",
47 | "gulp": "^3.9.1",
48 | "jsdoc-to-markdown": "^3.0.0",
49 | "mocha": "^3.0.1",
50 | "rollup": "^0.41.6",
51 | "rollup-plugin-babel": "^2.7.1",
52 | "rollup-plugin-license": "^0.3.0",
53 | "rollup-plugin-multi-entry": "^2.0.1",
54 | "rollup-plugin-multidest": "^1.0.0",
55 | "rollup-plugin-node-resolve": "^3.0.0",
56 | "rollup-plugin-uglify": "^1.0.2",
57 | "rollup-watch": "^3.2.2",
58 | "webpack": "^2.2.1",
59 | "yargs": "^4.8.1"
60 | },
61 | "repository": {
62 | "type": "git",
63 | "url": "git+https://github.com/iuap-design/kero.git"
64 | },
65 | "author": "yonyou FED",
66 | "license": "ISC",
67 | "bugs": {
68 | "url": "https://github.com/iuap-design/kero/issues"
69 | },
70 | "homepage": "https://github.com/iuap-design/kero#readme"
71 | }
72 |
--------------------------------------------------------------------------------
/examples/validateapi1-validateapi.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Title
7 |
8 |
9 |
10 |
11 |
12 |
14 |
15 |
16 |
25 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/src/getSimpleData.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module : kero dataTable getSimpleData
3 | * Author : liuyk(liuyk@yonyou.com)
4 | * Date : 2016-08-01 14:34:01
5 | */
6 |
7 | /**
8 | * 获取数据信息,只获取字段名与字段值
9 | * @memberof DataTable
10 | * @param {object} [options] [description]
11 | * @param {string} [options.type=all] 获取数据的规则
12 | * all:所有数据
13 | * current:当前行数据
14 | * focus:焦点行数据
15 | * select:选中行数据
16 | * change:发生改变的数据
17 | * @param {array} [options.fields] 需要获取数据的字段名数组
18 | * @return {array} 获取到的数据信息
19 | * @example
20 | * datatable.getSimpleData() // 获取所有数据信息
21 | * datatable.getSimpleData({type:'current'}) // 获取当前行数据信息
22 | * datatable.getSimpleData({type:'current','fields':['filed1','field3']}) // 获取当前行field1和filed3数据信息
23 | */
24 | const getSimpleData = function(options) {
25 | options = options || {}
26 | var rows, _rowData = [],
27 | type = options['type'] || 'all',
28 | fields = options['fields'] || null;
29 |
30 | if (type === 'current') {
31 | var currRow = this.getCurrentRow();
32 | rows = currRow == null ? [] : [currRow];
33 | } else if (type === 'focus') {
34 | var focusRow = this.getFocusRow();
35 | rows = focusRow == null ? [] : [focusRow];
36 | } else {
37 | if (this.pageCache) {
38 | var pages = this.getPages();
39 | rows = []
40 | for (var i = 0; i < pages.length; i++) {
41 | var page = pages[i];
42 | if (page) {
43 | if (type === 'all') {
44 | rows = rows.concat(page.rows);
45 | } else if (type === 'select') {
46 | rows = rows.concat(page.getSelectRows());
47 | } else if (type === 'change') {
48 | rows = rows.concat(page.getChangedRows());
49 | }
50 | }
51 | }
52 | } else {
53 | if (type === 'all') {
54 | rows = this.rows.peek();
55 | } else if (type === 'select') {
56 | rows = this.getSelectedRows();
57 | } else if (type === 'change') {
58 | rows = this.getChangedRows();
59 | }
60 | }
61 | }
62 |
63 | for (var i = 0; i < rows.length; i++) {
64 | _rowData.push(rows[i].getSimpleData({
65 | fields: fields
66 | }));
67 | }
68 | if (_rowData.length == 0) {
69 | _rowData = this.setSimpleDataReal; //云采提的#需求
70 | }
71 | return _rowData;
72 | };
73 |
74 |
75 |
76 | export const getSimpleDataFunObj = {
77 | getSimpleData: getSimpleData
78 | }
79 |
--------------------------------------------------------------------------------
/examples/dataTableUse2-time.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Title
7 |
8 |
9 |
10 |
11 |
12 |
14 |
15 |
16 |
17 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/lib/getSimpleData.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module : kero dataTable getSimpleData
3 | * Author : liuyk(liuyk@yonyou.com)
4 | * Date : 2016-08-01 14:34:01
5 | */
6 |
7 | /**
8 | * 获取数据信息,只获取字段名与字段值
9 | * @memberof DataTable
10 | * @param {object} [options] [description]
11 | * @param {string} [options.type=all] 获取数据的规则
12 | * all:所有数据
13 | * current:当前行数据
14 | * focus:焦点行数据
15 | * select:选中行数据
16 | * change:发生改变的数据
17 | * @param {array} [options.fields] 需要获取数据的字段名数组
18 | * @return {array} 获取到的数据信息
19 | * @example
20 | * datatable.getSimpleData() // 获取所有数据信息
21 | * datatable.getSimpleData({type:'current'}) // 获取当前行数据信息
22 | * datatable.getSimpleData({type:'current','fields':['filed1','field3']}) // 获取当前行field1和filed3数据信息
23 | */
24 | var getSimpleData = function getSimpleData(options) {
25 | options = options || {};
26 | var rows,
27 | _rowData = [],
28 | type = options['type'] || 'all',
29 | fields = options['fields'] || null;
30 |
31 | if (type === 'current') {
32 | var currRow = this.getCurrentRow();
33 | rows = currRow == null ? [] : [currRow];
34 | } else if (type === 'focus') {
35 | var focusRow = this.getFocusRow();
36 | rows = focusRow == null ? [] : [focusRow];
37 | } else {
38 | if (this.pageCache) {
39 | var pages = this.getPages();
40 | rows = [];
41 | for (var i = 0; i < pages.length; i++) {
42 | var page = pages[i];
43 | if (page) {
44 | if (type === 'all') {
45 | rows = rows.concat(page.rows);
46 | } else if (type === 'select') {
47 | rows = rows.concat(page.getSelectRows());
48 | } else if (type === 'change') {
49 | rows = rows.concat(page.getChangedRows());
50 | }
51 | }
52 | }
53 | } else {
54 | if (type === 'all') {
55 | rows = this.rows.peek();
56 | } else if (type === 'select') {
57 | rows = this.getSelectedRows();
58 | } else if (type === 'change') {
59 | rows = this.getChangedRows();
60 | }
61 | }
62 | }
63 |
64 | for (var i = 0; i < rows.length; i++) {
65 | _rowData.push(rows[i].getSimpleData({
66 | fields: fields
67 | }));
68 | }
69 | if (_rowData.length == 0) {
70 | _rowData = this.setSimpleDataReal; //云采提的#需求
71 | }
72 | return _rowData;
73 | };
74 |
75 | export var getSimpleDataFunObj = {
76 | getSimpleData: getSimpleData
77 | };
--------------------------------------------------------------------------------
/docs/arch.md:
--------------------------------------------------------------------------------
1 | # Kero初衷
2 |
3 | Kero是希望基于NeoUI组件,快速实现数据绑定,提供完整前端解决方案。以下介绍前端发展,及流行的框架设计模式。
4 |
5 |
6 |
7 | ## 浏览器格局
8 |
9 | 20世纪90年代,网景公司发布了Navigator浏览器,实现了内容的展示。为满足市场更多需求,网景仓促发布了:Javascript。
10 |
11 | 浏览器的一时风靡,微软也很快推出自己的桌面浏览器Internet Exploer。凭借着承诺永久免费,率先支持CSS等新标准,IE迅速占领了市场,也宣告了网景浏览器的终结。
12 |
13 | 开源方面的后起之秀随之也获得了强势的发展和极高的拥趸,以下为目前浏览器情况。
14 |
15 | 
16 |
17 |
18 |
19 | ## jQuery
20 |
21 | 浏览器的纷争,对标准的实现也不尽相同,jQuery为我们实现了:
22 |
23 | * 解决跨浏览器兼容
24 | * DOM选择器
25 | * 链式表达式,让书写代码变得有趣
26 | * 简化AJAX操作
27 | * 生态完善,海量插件
28 |
29 | 总体就是降低了前端的学习成本,提高了项目的效率。
30 |
31 | JavaScript 过于灵活,代码的组织过于零散,一旦需求变得复杂, JavaScript 代码将变得难以维护。特别是崇尚快速开发、快速试错的开发模式,臃肿、难以组织和维护的 JavaScript 代码成了一个需要重要解决的问题。
32 |
33 |
34 |
35 | ## 设计模式
36 |
37 | 设计模式常见的有MVC,MVP,MVVM。有关他们的介绍,引用阮一峰的[MVC,MVP 和 MVVM 的图示](http://www.ruanyifeng.com/blog/2015/02/mvcmvp_mvvm.html):
38 |
39 | ### MVC
40 |
41 | MVC模式的意思是,软件可以分成三个部分。
42 |
43 | 
44 |
45 | > - 视图(View):用户界面。
46 | > - 控制器(Controller):业务逻辑
47 | > - 模型(Model):数据保存
48 |
49 | 各部分之间的通信方式如下。
50 |
51 | 
52 |
53 | > 1. View 传送指令到 Controller
54 | > 2. Controller 完成业务逻辑后,要求 Model 改变状态
55 | > 3. Model 将新的数据发送到 View,用户得到反馈
56 |
57 | 所有通信都是单向的。
58 |
59 | ### 互动模式
60 |
61 | 接受用户指令时,MVC 可以分成两种方式。一种是通过 View 接受指令,传递给 Controller。
62 |
63 | 
64 |
65 | 另一种是直接通过controller接受指令。
66 |
67 | 
68 |
69 | ### 实例:Backbone
70 |
71 | 实际项目往往采用更灵活的方式,以 [Backbone.js](http://documentcloud.github.com/backbone) 为例。
72 |
73 | 
74 |
75 | \1. 用户可以向 View 发送指令(DOM 事件),再由 View 直接要求 Model 改变状态。
76 |
77 | \2. 用户也可以直接向 Controller 发送指令(改变 URL 触发 hashChange 事件),再由 Controller 发送给 View。
78 |
79 | \3. Controller 非常薄,只起到路由的作用,而 View 非常厚,业务逻辑都部署在 View。所以,Backbone 索性取消了 Controller,只保留一个 Router(路由器) 。
80 |
81 | ### MVP
82 |
83 | MVP 模式将 Controller 改名为 Presenter,同时改变了通信方向。
84 |
85 | 
86 |
87 | \1. 各部分之间的通信,都是双向的。
88 |
89 | \2. View 与 Model 不发生联系,都通过 Presenter 传递。
90 |
91 | \3. View 非常薄,不部署任何业务逻辑,称为"被动视图"(Passive View),即没有任何主动性,而 Presenter非常厚,所有逻辑都部署在那里。
92 |
93 | ### MVVM
94 |
95 | MVVM 模式将 Presenter 改名为 ViewModel,基本上与 MVP 模式完全一致。
96 |
97 | 
98 |
99 | 唯一的区别是,它采用双向绑定(data-binding):View的变动,自动反映在 ViewModel,反之亦然。[Angular](https://angularjs.org/) 和 [Ember](http://emberjs.com/) 都采用这种模式。
100 |
101 |
102 |
103 | 参考链接
104 |
105 | [MVC,MVP 和 MVVM 的图示](http://www.ruanyifeng.com/blog/2015/02/mvcmvp_mvvm.html)
106 |
--------------------------------------------------------------------------------
/snippets/arch/base.md:
--------------------------------------------------------------------------------
1 | ## Kero初衷
2 |
3 | Kero是希望基于NeoUI组件,快速实现数据绑定,提供完整前端解决方案。以下介绍前端发展,及流行的框架设计模式。
4 |
5 |
6 |
7 | ### 浏览器格局
8 |
9 | 20世纪90年代,网景公司发布了Navigator浏览器,实现了内容的展示。为满足市场更多需求,网景仓促发布了:Javascript。
10 |
11 | 浏览器的一时风靡,微软也很快推出自己的桌面浏览器Internet Exploer。凭借着承诺永久免费,率先支持CSS等新标准,IE迅速占领了市场,也宣告了网景浏览器的终结。
12 |
13 | 开源方面的后起之秀随之也获得了强势的发展和极高的拥趸,以下为目前浏览器情况。
14 |
15 | 
16 |
17 |
18 |
19 | ### jQuery
20 |
21 | 浏览器的纷争,对标准的实现也不尽相同,jQuery为我们实现了:
22 |
23 | * 解决跨浏览器兼容
24 | * DOM选择器
25 | * 链式表达式,让书写代码变得有趣
26 | * 简化AJAX操作
27 | * 生态完善,海量插件
28 |
29 | 总体就是降低了前端的学习成本,提高了项目的效率。
30 |
31 | JavaScript 过于灵活,代码的组织过于零散,一旦需求变得复杂, JavaScript 代码将变得难以维护。特别是崇尚快速开发、快速试错的开发模式,臃肿、难以组织和维护的 JavaScript 代码成了一个需要重要解决的问题。
32 |
33 |
34 |
35 | ### 设计模式
36 |
37 | 设计模式常见的有MVC,MVP,MVVM。有关他们的介绍,引用阮一峰的[MVC,MVP 和 MVVM 的图示](http://www.ruanyifeng.com/blog/2015/02/mvcmvp_mvvm.html):
38 |
39 | #### MVC
40 |
41 | MVC模式的意思是,软件可以分成三个部分。
42 |
43 | 
44 |
45 | > - 视图(View):用户界面。
46 | > - 控制器(Controller):业务逻辑
47 | > - 模型(Model):数据保存
48 |
49 | 各部分之间的通信方式如下。
50 |
51 | 
52 |
53 | > 1. View 传送指令到 Controller
54 | > 2. Controller 完成业务逻辑后,要求 Model 改变状态
55 | > 3. Model 将新的数据发送到 View,用户得到反馈
56 |
57 | 所有通信都是单向的。
58 |
59 | #### 互动模式
60 |
61 | 接受用户指令时,MVC 可以分成两种方式。一种是通过 View 接受指令,传递给 Controller。
62 |
63 | 
64 |
65 | 另一种是直接通过controller接受指令。
66 |
67 | 
68 |
69 | #### 实例:Backbone
70 |
71 | 实际项目往往采用更灵活的方式,以 [Backbone.js](http://documentcloud.github.com/backbone) 为例。
72 |
73 | 
74 |
75 | \1. 用户可以向 View 发送指令(DOM 事件),再由 View 直接要求 Model 改变状态。
76 |
77 | \2. 用户也可以直接向 Controller 发送指令(改变 URL 触发 hashChange 事件),再由 Controller 发送给 View。
78 |
79 | \3. Controller 非常薄,只起到路由的作用,而 View 非常厚,业务逻辑都部署在 View。所以,Backbone 索性取消了 Controller,只保留一个 Router(路由器) 。
80 |
81 | #### MVP
82 |
83 | MVP 模式将 Controller 改名为 Presenter,同时改变了通信方向。
84 |
85 | 
86 |
87 | \1. 各部分之间的通信,都是双向的。
88 |
89 | \2. View 与 Model 不发生联系,都通过 Presenter 传递。
90 |
91 | \3. View 非常薄,不部署任何业务逻辑,称为"被动视图"(Passive View),即没有任何主动性,而 Presenter非常厚,所有逻辑都部署在那里。
92 |
93 | #### MVVM
94 |
95 | MVVM 模式将 Presenter 改名为 ViewModel,基本上与 MVP 模式完全一致。
96 |
97 | 
98 |
99 | 唯一的区别是,它采用双向绑定(data-binding):View的变动,自动反映在 ViewModel,反之亦然。[Angular](https://angularjs.org/) 和 [Ember](http://emberjs.com/) 都采用这种模式。
100 |
101 |
102 |
103 | 参考链接
104 |
105 | [MVC,MVP 和 MVVM 的图示](http://www.ruanyifeng.com/blog/2015/02/mvcmvp_mvvm.html)
106 |
--------------------------------------------------------------------------------
/snippets/overview/base.md:
--------------------------------------------------------------------------------
1 | ## Kero介绍
2 |
3 | ### kero出现的背景
4 |
5 | #### 构建大型企业级应用的痛点:
6 |
7 | - 复杂单据
8 | - 控件复杂,不断扩展
9 | - 数据格式不固定,运行时动态调整
10 |
11 | #### Kero如何解决这些问题:
12 |
13 |
14 | - 数据模型可描述
15 |
16 | kero 使用了描述性的代码风格定义数据模型。数据被存储在ViewModel中,通过数据模型进行访问和修改。
17 |
18 | var viewModel = {
19 | head : new u.DataTable({
20 | meta: {
21 | 'pk_org': {
22 | 'required': true,
23 | 'associations': {
24 | "pk_org": "name"
25 | },
26 | 'associationMeta': 'uap.org'
27 | },
28 | 'billnumber': {
29 | 'precision': 2,
30 | 'required': true,
31 | 'maxLength': 50
32 | }
33 | }
34 | })
35 | }
36 |
37 |
38 | - 统一可扩展的控件描述
39 |
40 | kero使用了描述性的风格来定义控件
41 |
42 |
43 |
44 |
45 |
46 | 在普通 HTML 中使用kero语法将在指定DOM上创建控件,并与数据模型关联。一旦创建了关联,控件 将与数据模型同步。每当修改了数据,控件便相应地更新,修改了控件,数据模型也会相应的更新.
47 |
48 | 扩展控件时可以通过数据模型对数据进行获取&监听和修改
49 |
50 | - 数据模型可变
51 |
52 | 数据格式可变使得无缝的数据修改称为可能, kero负责把不同控件的数据集中高效地组织并处理,视图层的控件会订阅数据模型及数据的变更,当数据变化时通知相应组件更新,并在客户端维护一份包含所有数据的数据缓存
53 |
54 | 
55 |
56 | - 基于元数据的服务器端
57 |
58 | 在服务器端,我们通过数据模型中的描述将iuap 元数据与底层的数据操作联系起来。
59 |
60 | iUAP元数据组件遵循元数据设计规范。基于元数据的定义,该组件提供了对数据的增删改查,数据表扩展以及关联关系查询等功能。同时提供热点数据缓存,数据变更日志等功能。
61 |
62 | ### Kero定位
63 |
64 | Kero依托基于 MVVM 架构的 Knockout 类库,实现了将NeoUI控件库自由进行数据绑定的前端类库。主要解决问题:
65 |
66 | - 提供NeoUI完整样式,解决页面UE风格一致的问题
67 | - 提供了数据模型,实现数据与UI双向绑定,构建数据驱动型页面。解决具有复杂交互的页面开发问题。
68 | - 依托NeoUI控件库,给开发者带来一站式完整前端解决方案
69 |
70 | ### Kero优势
71 |
72 | - **兼容IE8以上的主要浏览器**:IE 8+、Firefox、Chrome、safari
73 | - **完善的控件体系**:包含常用控件,见[NeoUI](../neoui/index.html),支持多端适配。
74 | - **声明式绑定**:使用简明易读的语法很容易地将模型数据关联到DOM元素上
75 | - **双向数据绑定**:模型与UI之间的双向自动更新
76 | - **多维数据模型**:解决了字段关联、主子数据、主子孙等多维数据模型的绑定问题。
77 |
78 | ### Kero设计理念
79 |
80 | #### **UI控件**
81 |
82 | UI控件遵循iUAP Design设计规范,构建跨平台和超越设备尺寸的统一体验。遵循基本的移动设计定则,同时支持触摸、语音、鼠标、键盘等输入方式。
83 |
84 | UI控件的使用,采用了类似bootstrap的用法,通过定义class名称来声明控件,如按钮控件的定义:
85 |
86 | ```html
87 |
88 | ```
89 |
90 | 开发者不需要通过js代码创建控件,简单易用,详见[NeoUI](../neoui/index.html)。
91 |
92 | #### **模型结构**
93 |
94 | ##### 数据模型
95 |
96 | 数据模型主要是对MVVM架构中的Model层做增强处理。主要功能有:
97 |
98 | - 以行、列的形式对数据做存储,并对外暴露一批增删改查的API,方便开发者对页面数据的处理,而且所有开发者之间做到统一,减少出错概率。
99 | - 数据增加状态标识新增或修改,方便开发者使用。
100 | - 具有分页缓存能力,可在前台处理分页(非必要情况下,不推荐前台分页)。
101 | - 具有事件触发器,把数据变化触发出去,供开发者监听使用。
102 |
103 | ##### 控件模型
104 |
105 | 控件模型是为解决复杂交互页面中,业务逻辑对数据存在一系列处理需求而设计的。用来简化开发者对相关逻辑的开发。比如:数据的必填、数据的各种校验、数据的显示格式等。
106 |
107 | 控件模型与UI和数据模型之间的关系表现为:
108 |
109 | 
110 |
111 | 在一般的场景中,数据模型可以直接与UI进行数据绑定。当有数据处理需求时,可以通过控件模型来处理UI和数据模型之间的数据通信。控件模型在处理数据的同时,会进行相关业务逻辑的处理。
112 |
--------------------------------------------------------------------------------
/lib/rowFocus.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module : kero dataTable rowFocus
3 | * Author : liuyk(liuyk@yonyou.com)
4 | * Date : 2016-08-08 09:59:01
5 | */
6 | import { isNumber } from 'tinper-sparrow/src/util';
7 |
8 | /**
9 | * 设置焦点行
10 | * @memberof DataTable
11 | * @param {number|u.Row} index 行对象或者行index
12 | * @param {boolean} [quiet] 如果为true则不触发事件,否则触发事件
13 | * @param {boolean} [force] 如果为true当index行与已focus的行相等时,仍然触发事件,否则不触发事件
14 | * @example
15 | * datatable.setRowFocus(1) // 设置第二行为焦点行
16 | * datatable.setRowFocus(1,true) // 设置第二行为焦点行,不触发事件
17 | * datatable.setRowFocus(1,false,true) // 设置第二行为焦点行,如果当前焦点行为第二行,仍旧触发事件
18 | */
19 | var setRowFocus = function setRowFocus(index, quiet, force) {
20 | var rowId = null;
21 | if (index instanceof Row) {
22 | index = this.getIndexByRowId(index.rowId);
23 | rowId = index.rowId;
24 | }
25 |
26 | if (index === -1 || index === this.focusIndex() && !force) {
27 | return;
28 | }
29 | if (this.focusIndex() > -1) {
30 | this.setRowUnFocus(this.focusIndex());
31 | }
32 | this.focusIndex(index);
33 | if (quiet) {
34 | return;
35 | }
36 | this.currentRowChange(-this.currentRowChange());
37 | if (!rowId) {
38 | rowId = this.getRow(index).rowId;
39 | }
40 | this.trigger(DataTable.ON_ROW_FOCUS, {
41 | index: index,
42 | rowId: rowId
43 | });
44 | this.updateCurrIndex();
45 | };
46 |
47 | /**
48 | * 焦点行反选
49 | * @memberof DataTable
50 | * @example
51 | * datatable.setRowUnFocus()
52 | */
53 | var setRowUnFocus = function setRowUnFocus() {
54 | this.currentRowChange(-this.currentRowChange());
55 | var indx = this.focusIndex(),
56 | rowId = null;
57 | if (indx !== -1) {
58 | rowId = this.getRow(indx).rowId;
59 | }
60 | this.trigger(DataTable.ON_ROW_UNFOCUS, {
61 | index: indx,
62 | rowId: rowId
63 | });
64 | this.focusIndex(-1);
65 | this.updateCurrIndex();
66 | };
67 |
68 | /***
69 | * 数据行发生改变时更新focusindex
70 | * @memberof DataTable
71 | * @param {number} opIndex 发生改变的数据行位置
72 | * @param {string} opType +表示新增行,-表示减少行
73 | * @param {number} num 新增/减少的行数
74 | *
75 | */
76 | var updateFocusIndex = function updateFocusIndex(opIndex, opType, num) {
77 | if (!isNumber(num)) {
78 | num = 1;
79 | }
80 | if (opIndex <= this.focusIndex() && this.focusIndex() != -1) {
81 | if (opType === '+') {
82 | this.focusIndex(this.focusIndex() + num);
83 | } else if (opType === '-') {
84 | if (this.focusIndex() >= opIndex && this.focusIndex() <= opIndex + num - 1) {
85 | this.focusIndex(-1);
86 | } else if (this.focusIndex() > opIndex + num - 1) {
87 | this.focusIndex(this.focusIndex() - num);
88 | }
89 | }
90 | }
91 | };
92 |
93 | export var rowFocusFunObj = {
94 | setRowFocus: setRowFocus,
95 | setRowUnFocus: setRowUnFocus,
96 | updateFocusIndex: updateFocusIndex
97 | };
--------------------------------------------------------------------------------
/docs/overview.md:
--------------------------------------------------------------------------------
1 | # Kero介绍
2 |
3 | ## kero出现的背景
4 |
5 | ### 构建大型企业级应用的痛点:
6 |
7 | - 复杂单据
8 | - 控件复杂,不断扩展
9 | - 数据格式不固定,运行时动态调整
10 |
11 | ### Kero如何解决这些问题:
12 |
13 |
14 | - 数据模型可描述
15 |
16 | kero 使用了描述性的代码风格定义数据模型。数据被存储在ViewModel中,通过数据模型进行访问和修改。
17 |
18 | var viewModel = {
19 | head : new u.DataTable({
20 | meta: {
21 | 'pk_org': {
22 | 'required': true,
23 | 'associations': {
24 | "pk_org": "name"
25 | },
26 | 'associationMeta': 'uap.org'
27 | },
28 | 'billnumber': {
29 | 'precision': 2,
30 | 'required': true,
31 | 'maxLength': 50
32 | }
33 | }
34 | })
35 | }
36 |
37 |
38 | - 统一可扩展的控件描述
39 |
40 | kero使用了描述性的风格来定义控件
41 |
42 |
43 |
44 |
45 |
46 | 在普通 HTML 中使用kero语法将在指定DOM上创建控件,并与数据模型关联。一旦创建了关联,控件 将与数据模型同步。每当修改了数据,控件便相应地更新,修改了控件,数据模型也会相应的更新.
47 |
48 | 扩展控件时可以通过数据模型对数据进行获取&监听和修改
49 |
50 | - 数据模型可变
51 |
52 | 数据格式可变使得无缝的数据修改称为可能, kero负责把不同控件的数据集中高效地组织并处理,视图层的控件会订阅数据模型及数据的变更,当数据变化时通知相应组件更新,并在客户端维护一份包含所有数据的数据缓存
53 |
54 | 
55 |
56 | - 基于元数据的服务器端
57 |
58 | 在服务器端,我们通过数据模型中的描述将iuap 元数据与底层的数据操作联系起来。
59 |
60 | iUAP元数据组件遵循元数据设计规范。基于元数据的定义,该组件提供了对数据的增删改查,数据表扩展以及关联关系查询等功能。同时提供热点数据缓存,数据变更日志等功能。
61 |
62 | ## Kero定位
63 |
64 | Kero依托基于 [MVVM](mvvm.html) 架构的 [Knockout](./knockout.html) 类库,实现了将NeoUI控件库自由进行数据绑定的前端类库。主要解决问题:
65 |
66 | - 提供NeoUI完整样式,解决页面UE风格一致的问题
67 | - 提供了数据模型,实现数据与UI双向绑定,构建数据驱动型页面。解决具有复杂交互的页面开发问题。
68 | - 依托NeoUI控件库,给开发者带来一站式完整前端解决方案
69 |
70 | ## Kero优势
71 |
72 | - **兼容IE8以上的主要浏览器**:IE 8+、Firefox、Chrome、safari
73 | - **完善的控件体系**:包含常用控件,见[NeoUI](../neoui/index.html),支持多端适配。
74 | - **声明式绑定**:使用简明易读的语法很容易地将模型数据关联到DOM元素上
75 | - **双向数据绑定**:模型与UI之间的双向自动更新
76 | - **多维数据模型**:解决了字段关联、主子数据、主子孙等多维数据模型的绑定问题。
77 |
78 | ## Kero设计理念
79 |
80 | ### **UI控件**
81 |
82 | UI控件遵循iUAP Design设计规范,构建跨平台和超越设备尺寸的统一体验。遵循基本的移动设计定则,同时支持触摸、语音、鼠标、键盘等输入方式。
83 |
84 | UI控件的使用,采用了类似bootstrap的用法,通过定义class名称来声明控件,如按钮控件的定义:
85 |
86 | ```html
87 |
88 | ```
89 |
90 | 开发者不需要通过js代码创建控件,简单易用,详见[NeoUI](../neoui/index.html)。
91 |
92 | ### **模型结构**
93 |
94 | #### 数据模型
95 |
96 | 数据模型主要是对MVVM架构中的Model层做增强处理。主要功能有:
97 |
98 | - 以行、列的形式对数据做存储,并对外暴露一批增删改查的API,方便开发者对页面数据的处理,而且所有开发者之间做到统一,减少出错概率。
99 | - 数据增加状态标识新增或修改,方便开发者使用。
100 | - 具有分页缓存能力,可在前台处理分页(非必要情况下,不推荐前台分页)。
101 | - 具有事件触发器,把数据变化触发出去,供开发者监听使用。
102 |
103 | #### 控件模型
104 |
105 | 控件模型是为解决复杂交互页面中,业务逻辑对数据存在一系列处理需求而设计的。用来简化开发者对相关逻辑的开发。比如:数据的必填、数据的各种校验、数据的显示格式等。
106 |
107 | 控件模型与UI和数据模型之间的关系表现为:
108 |
109 | 
110 |
111 | 在一般的场景中,数据模型可以直接与UI进行数据绑定。当有数据处理需求时,可以通过控件模型来处理UI和数据模型之间的数据通信。控件模型在处理数据的同时,会进行相关业务逻辑的处理。
112 |
113 |
114 |
115 |
--------------------------------------------------------------------------------
/src/row-getSimpleData.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module : kero dataTable row getSimpleData
3 | * Author : liuyk(liuyk@yonyou.com)
4 | * Date : 2016-08-08 13:54:01
5 | */
6 | import {
7 | rowUtilFunObj
8 | } from './row-util';
9 | import {
10 | isEmptyObject
11 | } from 'tinper-sparrow/src/util';
12 |
13 | // 获取数据的核心方法
14 | const _getSimpleData = function(rowObj, data) {
15 | var _data = {};
16 | var meta = rowObj.parent.getMeta() || {};
17 | for (var key in data) {
18 | if (key === 'meta' || isEmptyObject(data[key])) {
19 | continue;
20 | } else if (data[key].isChild) {
21 | _data[key] = data[key].value ? data[key].value.getSimpleData() : {};
22 | } else if (key === '$data') { //处理一维数组: [1,2,3]
23 | _data = data[key].value
24 | } else if (typeof data[key].value !== 'undefined') {
25 | //如果类型为boolean,无论值为false、true都应该等于他本身
26 | if (meta[key] && meta[key].type === 'boolean') {
27 | _data[key] = data[key].value ? true : false; //默认值可能是null
28 | } else {
29 | _data[key] = data[key].value;
30 | }
31 | if (meta[key] && meta[key].type) {
32 | var obj = {
33 | meta: meta,
34 | data: data,
35 | key: key
36 | }
37 | _data[key] = rowObj.formatValueFun(obj, rowObj.parent.dateNoConvert);
38 |
39 | }
40 | } else if (!data[key].value) {
41 | _data[key] = data[key].value;
42 | } else {
43 | _data[key] = _getSimpleData(rowObj, data[key])
44 | }
45 | }
46 | return _data;
47 |
48 | }
49 |
50 | // 对于日期获取值时进行转换
51 | const formatValueFun = function(obj, isDateNoConvert) {
52 | var meta = obj.meta,
53 | data = obj.data,
54 | key = obj.key;
55 | if (!isDateNoConvert && (meta[key].type == 'date' || meta[key].type == 'datetime')) {
56 | return rowUtilFunObj._dateToUTCString(data[key].value)
57 | }
58 | return data[key].value;
59 | }
60 |
61 | /**
62 | * 获取数据信息
63 | * @memberof Row
64 | * @param {object} [options] 获取数据信息时的配置参数
65 | * @param {array} [options.fields] 获取数据信息时是否制定字段值
66 | * @return {object} 数据信息
67 | * @example
68 | * row.getSimpleData()
69 | * row.getSimpleData({fields:['field1','field2']})
70 | */
71 | const getSimpleData = function(options) {
72 | options = options || {}
73 | var fields = options['fields'] || null;
74 | var meta = this.parent.getMeta();
75 | var data = this.data;
76 | var _data = _getSimpleData(this, data); //{};
77 | var _fieldsData = {};
78 | if (fields) {
79 | for (var key in _data) {
80 | if (fields.indexOf(key) != -1) {
81 | _fieldsData[key] = _data[key];
82 | }
83 | }
84 | return _fieldsData;
85 | }
86 | return _data;
87 |
88 | };
89 |
90 | export const rowGetSimpleDataFunObj = {
91 | formatValueFun: formatValueFun,
92 | getSimpleData: getSimpleData
93 | }
94 |
--------------------------------------------------------------------------------
/lib/row-getSimpleData.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module : kero dataTable row getSimpleData
3 | * Author : liuyk(liuyk@yonyou.com)
4 | * Date : 2016-08-08 13:54:01
5 | */
6 | import { rowUtilFunObj } from './row-util';
7 | import { isEmptyObject } from 'tinper-sparrow/src/util';
8 |
9 | // 获取数据的核心方法
10 | var _getSimpleData = function _getSimpleData(rowObj, data) {
11 | var _data = {};
12 | var meta = rowObj.parent.getMeta() || {};
13 | for (var key in data) {
14 | if (key === 'meta' || isEmptyObject(data[key])) {
15 | continue;
16 | } else if (data[key].isChild) {
17 | _data[key] = data[key].value ? data[key].value.getSimpleData() : {};
18 | } else if (key === '$data') {
19 | //处理一维数组: [1,2,3]
20 | _data = data[key].value;
21 | } else if (typeof data[key].value !== 'undefined') {
22 | //如果类型为boolean,无论值为false、true都应该等于他本身
23 | if (meta[key] && meta[key].type === 'boolean') {
24 | _data[key] = data[key].value ? true : false; //默认值可能是null
25 | } else {
26 | _data[key] = data[key].value;
27 | }
28 | if (meta[key] && meta[key].type) {
29 | var obj = {
30 | meta: meta,
31 | data: data,
32 | key: key
33 | };
34 | _data[key] = rowObj.formatValueFun(obj, rowObj.parent.dateNoConvert);
35 | }
36 | } else if (!data[key].value) {
37 | _data[key] = data[key].value;
38 | } else {
39 | _data[key] = _getSimpleData(rowObj, data[key]);
40 | }
41 | }
42 | return _data;
43 | };
44 |
45 | // 对于日期获取值时进行转换
46 | var formatValueFun = function formatValueFun(obj, isDateNoConvert) {
47 | var meta = obj.meta,
48 | data = obj.data,
49 | key = obj.key;
50 | if (!isDateNoConvert && (meta[key].type == 'date' || meta[key].type == 'datetime')) {
51 | return rowUtilFunObj._dateToUTCString(data[key].value);
52 | }
53 | return data[key].value;
54 | };
55 |
56 | /**
57 | * 获取数据信息
58 | * @memberof Row
59 | * @param {object} [options] 获取数据信息时的配置参数
60 | * @param {array} [options.fields] 获取数据信息时是否制定字段值
61 | * @return {object} 数据信息
62 | * @example
63 | * row.getSimpleData()
64 | * row.getSimpleData({fields:['field1','field2']})
65 | */
66 | var getSimpleData = function getSimpleData(options) {
67 | options = options || {};
68 | var fields = options['fields'] || null;
69 | var meta = this.parent.getMeta();
70 | var data = this.data;
71 | var _data = _getSimpleData(this, data); //{};
72 | var _fieldsData = {};
73 | if (fields) {
74 | for (var key in _data) {
75 | if (fields.indexOf(key) != -1) {
76 | _fieldsData[key] = _data[key];
77 | }
78 | }
79 | return _fieldsData;
80 | }
81 | return _data;
82 | };
83 |
84 | export var rowGetSimpleDataFunObj = {
85 | formatValueFun: formatValueFun,
86 | getSimpleData: getSimpleData
87 | };
--------------------------------------------------------------------------------
/src/rowFocus.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module : kero dataTable rowFocus
3 | * Author : liuyk(liuyk@yonyou.com)
4 | * Date : 2016-08-08 09:59:01
5 | */
6 | import {
7 | isNumber
8 | } from 'tinper-sparrow/src/util';
9 |
10 | /**
11 | * 设置焦点行
12 | * @memberof DataTable
13 | * @param {number|u.Row} index 行对象或者行index
14 | * @param {boolean} [quiet] 如果为true则不触发事件,否则触发事件
15 | * @param {boolean} [force] 如果为true当index行与已focus的行相等时,仍然触发事件,否则不触发事件
16 | * @example
17 | * datatable.setRowFocus(1) // 设置第二行为焦点行
18 | * datatable.setRowFocus(1,true) // 设置第二行为焦点行,不触发事件
19 | * datatable.setRowFocus(1,false,true) // 设置第二行为焦点行,如果当前焦点行为第二行,仍旧触发事件
20 | */
21 | const setRowFocus = function(index, quiet, force) {
22 | var rowId = null
23 | if (index instanceof Row) {
24 | index = this.getIndexByRowId(index.rowId)
25 | rowId = index.rowId
26 | }
27 |
28 | if (index === -1 || (index === this.focusIndex() && !force)) {
29 | return;
30 | }
31 | if (this.focusIndex() > -1) {
32 | this.setRowUnFocus(this.focusIndex());
33 | }
34 | this.focusIndex(index)
35 | if (quiet) {
36 | return;
37 | }
38 | this.currentRowChange(-this.currentRowChange())
39 | if (!rowId) {
40 | rowId = this.getRow(index).rowId
41 | }
42 | this.trigger(DataTable.ON_ROW_FOCUS, {
43 | index: index,
44 | rowId: rowId
45 | })
46 | this.updateCurrIndex();
47 | }
48 |
49 |
50 | /**
51 | * 焦点行反选
52 | * @memberof DataTable
53 | * @example
54 | * datatable.setRowUnFocus()
55 | */
56 | const setRowUnFocus = function() {
57 | this.currentRowChange(-this.currentRowChange())
58 | var indx = this.focusIndex(),
59 | rowId = null;
60 | if (indx !== -1) {
61 | rowId = this.getRow(indx).rowId
62 | }
63 | this.trigger(DataTable.ON_ROW_UNFOCUS, {
64 | index: indx,
65 | rowId: rowId
66 | })
67 | this.focusIndex(-1)
68 | this.updateCurrIndex();
69 | }
70 |
71 | /***
72 | * 数据行发生改变时更新focusindex
73 | * @memberof DataTable
74 | * @param {number} opIndex 发生改变的数据行位置
75 | * @param {string} opType +表示新增行,-表示减少行
76 | * @param {number} num 新增/减少的行数
77 | *
78 | */
79 | const updateFocusIndex = function(opIndex, opType, num) {
80 | if (!isNumber(num)) {
81 | num = 1
82 | }
83 | if (opIndex <= this.focusIndex() && this.focusIndex() != -1) {
84 | if (opType === '+') {
85 | this.focusIndex(this.focusIndex() + num)
86 | } else if (opType === '-') {
87 | if (this.focusIndex() >= opIndex && this.focusIndex() <= opIndex + num - 1) {
88 | this.focusIndex(-1)
89 | } else if (this.focusIndex() > opIndex + num - 1) {
90 | this.focusIndex(this.focusIndex() - num)
91 | }
92 | }
93 | }
94 | }
95 |
96 | export const rowFocusFunObj = {
97 | setRowFocus: setRowFocus,
98 | setRowUnFocus: setRowUnFocus,
99 | updateFocusIndex: updateFocusIndex
100 | }
101 |
--------------------------------------------------------------------------------
/lib/simpleData.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module : kero dataTable simpleData
3 | * Author : liuyk(liuyk@yonyou.com)
4 | * Date : 2016-08-01 14:34:01
5 | */
6 | import { isArray } from 'tinper-sparrow/src/util';
7 |
8 | /**
9 | * 设置数据, 只设置字段值
10 | * @memberof DataTable
11 | * @param {array} data 数据信息
12 | * @param {boject} [options] 可配置参数
13 | * @param {boject} [options.unSelect=false] 是否默认选中第一行,如果为true则不选中第一行,否则选中第一行
14 | * @example
15 | * var data = [{
16 | * filed1:'value1',
17 | * field2:'value2'
18 | * },{
19 | * filed1:'value11',
20 | * field2:'value21'
21 | * }]
22 | * datatable.setSimpleData(data)
23 | * datatable.setSimpleData(data,{unSelect:true})
24 | */
25 | var setSimpleData = function setSimpleData(data, options) {
26 | this.removeAllRows();
27 | this.cachedPages = [];
28 | this.focusIndex(-1);
29 | this.selectedIndices([]);
30 | this.setSimpleDataReal = [];
31 | if (!data) {
32 | this.setSimpleDataReal = data;
33 | // throw new Error("dataTable.setSimpleData param can't be null!");
34 | return;
35 | }
36 |
37 | var rows = [];
38 | if (!isArray(data)) data = [data];
39 | for (var i = 0; i < data.length; i++) {
40 | var _data = data[i];
41 | /* 判断data中的字段在datatable中是否存在,如果不存在则创建 */
42 | // for(var f in _data){
43 | // this.createField(f)
44 | // }
45 | if (babelHelpers['typeof'](data[i]) !== 'object') _data = {
46 | $data: data[i]
47 | };
48 | if (options && options.status) {
49 | rows.push({
50 | status: options.status,
51 | data: _data
52 | });
53 | } else {
54 | rows.push({
55 | status: Row.STATUS.NORMAL,
56 | data: _data
57 | });
58 | }
59 | }
60 | var _data = {
61 | rows: rows
62 | };
63 | if (options) {
64 | if (typeof options.fieldFlag == 'undefined') {
65 | options.fieldFlag = true;
66 | }
67 | }
68 | this.setData(_data, options);
69 | };
70 |
71 | /**
72 | * 追加数据, 只设置字段值
73 | * @memberof DataTable
74 | * @param {array} data 数据信息
75 | * @param {string} [status=nrm] 追加数据信息的状态,参照Row对象的状态介绍
76 | * @param {boject} [options] 可配置参数
77 | * @param {boject} [options.unSelect=false] 是否默认选中第一行,如果为true则不选中第一行,否则选中第一行
78 | * @example
79 | * var data = [{
80 | * filed1:'value1',
81 | * field2:'value2'
82 | * },{
83 | * filed1:'value11',
84 | * field2:'value21'
85 | * }]
86 | * datatable.addSimpleData(data,Row.STATUS.NEW)
87 | * datatable.addSimpleData(data, null, {unSelect:true})
88 | */
89 | var addSimpleData = function addSimpleData(data, status, options) {
90 | if (!data) {
91 | throw new Error("dataTable.addSimpleData param can't be null!");
92 | }
93 | if (!isArray(data)) data = [data];
94 | for (var i = 0; i < data.length; i++) {
95 | var r = this.createEmptyRow(options);
96 | r.setSimpleData(data[i], status);
97 | }
98 | };
99 |
100 | export var simpleDataFunObj = {
101 | setSimpleData: setSimpleData,
102 | addSimpleData: addSimpleData
103 | };
--------------------------------------------------------------------------------
/src/simpleData.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module : kero dataTable simpleData
3 | * Author : liuyk(liuyk@yonyou.com)
4 | * Date : 2016-08-01 14:34:01
5 | */
6 | import {
7 | isArray
8 | } from 'tinper-sparrow/src/util';
9 |
10 | /**
11 | * 设置数据, 只设置字段值
12 | * @memberof DataTable
13 | * @param {array} data 数据信息
14 | * @param {boject} [options] 可配置参数
15 | * @param {boject} [options.unSelect=false] 是否默认选中第一行,如果为true则不选中第一行,否则选中第一行
16 | * @example
17 | * var data = [{
18 | * filed1:'value1',
19 | * field2:'value2'
20 | * },{
21 | * filed1:'value11',
22 | * field2:'value21'
23 | * }]
24 | * datatable.setSimpleData(data)
25 | * datatable.setSimpleData(data,{unSelect:true})
26 | */
27 | const setSimpleData = function(data, options) {
28 | this.removeAllRows();
29 | this.cachedPages = [];
30 | this.focusIndex(-1);
31 | this.selectedIndices([]);
32 | this.setSimpleDataReal = [];
33 | if (!data) {
34 | this.setSimpleDataReal = data;
35 | // throw new Error("dataTable.setSimpleData param can't be null!");
36 | return;
37 | }
38 |
39 | var rows = [];
40 | if (!isArray(data))
41 | data = [data];
42 | for (var i = 0; i < data.length; i++) {
43 | var _data = data[i];
44 | /* 判断data中的字段在datatable中是否存在,如果不存在则创建 */
45 | // for(var f in _data){
46 | // this.createField(f)
47 | // }
48 | if (typeof data[i] !== 'object')
49 | _data = {
50 | $data: data[i]
51 | }
52 | if (options && options.status) {
53 | rows.push({
54 | status: options.status,
55 | data: _data
56 | })
57 | } else {
58 | rows.push({
59 | status: Row.STATUS.NORMAL,
60 | data: _data
61 | })
62 | }
63 |
64 | }
65 | var _data = {
66 | rows: rows
67 | }
68 | if (options) {
69 | if (typeof options.fieldFlag == 'undefined') {
70 | options.fieldFlag = true;
71 | }
72 | }
73 | this.setData(_data, options);
74 | };
75 |
76 |
77 | /**
78 | * 追加数据, 只设置字段值
79 | * @memberof DataTable
80 | * @param {array} data 数据信息
81 | * @param {string} [status=nrm] 追加数据信息的状态,参照Row对象的状态介绍
82 | * @param {boject} [options] 可配置参数
83 | * @param {boject} [options.unSelect=false] 是否默认选中第一行,如果为true则不选中第一行,否则选中第一行
84 | * @example
85 | * var data = [{
86 | * filed1:'value1',
87 | * field2:'value2'
88 | * },{
89 | * filed1:'value11',
90 | * field2:'value21'
91 | * }]
92 | * datatable.addSimpleData(data,Row.STATUS.NEW)
93 | * datatable.addSimpleData(data, null, {unSelect:true})
94 | */
95 | const addSimpleData = function(data, status, options) {
96 | if (!data) {
97 | throw new Error("dataTable.addSimpleData param can't be null!");
98 | }
99 | if (!isArray(data))
100 | data = [data];
101 | for (var i = 0; i < data.length; i++) {
102 | var r = this.createEmptyRow(options);
103 | r.setSimpleData(data[i], status);
104 | }
105 |
106 | }
107 |
108 | export const simpleDataFunObj = {
109 | setSimpleData: setSimpleData,
110 | addSimpleData: addSimpleData
111 | }
112 |
--------------------------------------------------------------------------------
/vendor/uui/js/u-polyfill.min.js:
--------------------------------------------------------------------------------
1 | function isDomElement(t){return window.HTMLElement?t instanceof HTMLElement:t&&t.tagName&&1===t.nodeType}window.u=window.u||{};var u=window.u;if(u.polyfill=!0,u._addClass=function(t,e){var r,n,o,a,c,i=/[\t\r\n\f]/g,l="string"==typeof e&&e,s=/\S+/g;if(l&&(r=(e||"").match(s)||[],n=1===t.nodeType&&(t.className?(" "+t.className+" ").replace(i," "):" "))){for(a=0;o=r[a++];)n.indexOf(" "+o+" ")<0&&(n+=o+" ");c=(n+"").trim(),t.className!==c&&(t.className=c)}return this},u._removeClass=function(t,e){var r,n,o,a,c,i=/\S+/g,l=/[\t\r\n\f]/g,s=0===arguments.length||"string"==typeof e&&e;if(s&&(r=(e||"").match(i)||[],n=1===t.nodeType&&(t.className?(" "+t.className+" ").replace(l," "):""))){for(a=0;o=r[a++];)for(;n.indexOf(" "+o+" ")>=0;)n=n.replace(" "+o+" "," ");c=e?(n+"").trim():"",t.className!==c&&(t.className=c)}return this},u._hasClass=function(t,e){var r=/[\t\r\n\f]/g;return 1===t.nodeType&&(" "+t.className+" ").replace(r," ").indexOf(e)>=0},u._toggleClass=function(t,e){u._hasClass(t,e)?u._removeClass(t,e):u._addClass(t,e)},String.prototype.trim||(String.prototype.trim=function(){return this.replace(/^\s*(\b.*\b|)\s*$/,"$1")}),Array.prototype.indexOf||(Array.prototype.indexOf=function(t){for(var e=0;et||t>this.length?void alert("index out of bound"):void this.splice(t,1)}),Array.prototype.forEach||(Array.prototype.forEach=function(t){for(var e=0,r=this.length;r>e;e++)t(this[e],e,this)}),NodeList.prototype.forEach||(NodeList.prototype.forEach=Array.prototype.forEach),!window.HTMLElement){var _querySelectorAll=Element.prototype.querySelectorAll;Element.prototype.querySelectorAll=function(t){var e=_querySelectorAll.call(this,t);if(!isDomElement(this))return e;for(var r=[],n=0;n0){for(var n=0;nn;n++)r.push(arguments[n]);return function(){return e.apply(t,r.concat(Array.prototype.slice.call(arguments)))}}),window.getCurrentJsPath=function(){var t=document,e={},r=+new Date,n=/((?:http|https|file):\/\/.*?\/[^:]+)(?::\d+)?:\d+/,o=-1===(""+t.querySelector).indexOf("[native code]");if(t.currentScript)return t.currentScript.src;var a;try{e.b()}catch(c){a=c.fileName||c.sourceURL||c.stack||c.stacktrace}if(a){var i=n.exec(a)[1];if(i)return i}for(var l,s=t.scripts,u=s.length-1;l=s[u--];)if(l.className!==r&&"interactive"===l.readyState)return l.className=r,o?l.getAttribute("src",4):l.src},window.encodeBase64=function(t){for(var e,r,n,o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",a=0,c=t.length,i="";c>a;){if(e=255&t[a++],a==c){i+=o.charAt(e>>2),i+=o.charAt((3&e)<<4),i+="==";break}if(r=t[a++],a==c){i+=o.charAt(e>>2),i+=o.charAt((3&e)<<4|(240&r)>>4),i+=o.charAt((15&r)<<2),i+="=";break}n=t[a++],i+=o.charAt(e>>2),i+=o.charAt((3&e)<<4|(240&r)>>4),i+=o.charAt((15&r)<<2|(192&n)>>6),i+=o.charAt(63&n)}return i};
--------------------------------------------------------------------------------
/src/getSelect.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module : kero dataTable getSelect
3 | * Author : liuyk(liuyk@yonyou.com)
4 | * Date : 2016-08-01 14:34:01
5 | */
6 |
7 |
8 | /**
9 | * 获取选中行索引,多选时,只返回第一个行索引
10 | * @memberof DataTable
11 | * @return {number} 选中行索引
12 | * @example
13 | * datatable.getSelectedIndex()
14 | */
15 | const getSelectedIndex = function() {
16 | var selectedIndices = this.selectedIndices()
17 | if (selectedIndices == null || selectedIndices.length == 0)
18 | return -1
19 | return selectedIndices[0]
20 | };
21 |
22 | /**
23 | * 获取选中的所有行索引数组
24 | * @memberof DataTable
25 | * @return {array} 所有行索引数组
26 | * @example
27 | * datatable.getSelectedIndices()
28 | */
29 | const getSelectedIndices = function() {
30 | var selectedIndices = this.selectedIndices()
31 | if (selectedIndices == null || selectedIndices.length == 0)
32 | return []
33 | return selectedIndices
34 | };
35 |
36 | // 兼容保留,不要用
37 | const getSelectedIndexs = function() {
38 | return this.getSelectedIndices();
39 | }
40 |
41 | /**
42 | * 获取选中行的数据信息
43 | * @memberof DataTable
44 | * @param {boolean} [withEmptyRow=false] 未选中的数据是否使用空行代替,true表示以空行代替未选中行,false相反
45 | * @return {array} 发生变化的数据信息
46 | * @example
47 | * datatable.getSelectedDatas()
48 | * datatable.getSelectedDatas(true)
49 | */
50 | const getSelectedDatas = function(withEmptyRow) {
51 | var selectedIndices = this.selectedIndices()
52 | var datas = []
53 | var sIndices = []
54 | for (var i = 0, count = selectedIndices.length; i < count; i++) {
55 | sIndices.push(selectedIndices[i])
56 | }
57 | var rows = this.rows();
58 | for (var i = 0, count = rows.length; i < count; i++) {
59 | if (sIndices.indexOf(i) != -1)
60 | datas.push(rows[i].getData())
61 | else if (withEmptyRow == true)
62 | datas.push(rows[i].getEmptyData())
63 | }
64 | return datas
65 | };
66 |
67 | /**
68 | * 获取选中的Row对象
69 | * @memberof DataTable
70 | * @return {array} 选中的Row对象
71 | * @example
72 | * datatable.getSelectedRows()
73 | */
74 | const getSelectedRows = function() {
75 | var selectedIndices = this.selectedIndices();
76 | var selectRows = [];
77 | var rows = this.rows.peek();
78 | var sIndices = []
79 | for (var i = 0, count = selectedIndices.length; i < count; i++) {
80 | sIndices.push(selectedIndices[i])
81 | }
82 | for (var i = 0, count = rows.length; i < count; i++) {
83 | if (sIndices.indexOf(i) != -1)
84 | selectRows.push(rows[i])
85 | }
86 | return selectRows
87 | }
88 |
89 | const getAllPageSelectedRows = function() {
90 | var rows = [];
91 | if (this.pageCache) {
92 | var pages = this.getPages();
93 | for (var i = 0; i < pages.length; i++) {
94 | var page = pages[i];
95 | if (page) {
96 | rows = rows.concat(page.getSelectRows());
97 | }
98 | }
99 | }
100 | return rows;
101 | }
102 |
103 | export const getSelectFunObj = {
104 | getSelectedIndex: getSelectedIndex,
105 | getSelectedIndices: getSelectedIndices,
106 | getSelectedIndexs: getSelectedIndexs,
107 | getSelectedDatas: getSelectedDatas,
108 | getSelectedRows: getSelectedRows,
109 | getAllPageSelectedRows: getAllPageSelectedRows
110 | }
111 |
--------------------------------------------------------------------------------
/lib/getSelect.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module : kero dataTable getSelect
3 | * Author : liuyk(liuyk@yonyou.com)
4 | * Date : 2016-08-01 14:34:01
5 | */
6 |
7 | /**
8 | * 获取选中行索引,多选时,只返回第一个行索引
9 | * @memberof DataTable
10 | * @return {number} 选中行索引
11 | * @example
12 | * datatable.getSelectedIndex()
13 | */
14 | var getSelectedIndex = function getSelectedIndex() {
15 | var selectedIndices = this.selectedIndices();
16 | if (selectedIndices == null || selectedIndices.length == 0) return -1;
17 | return selectedIndices[0];
18 | };
19 |
20 | /**
21 | * 获取选中的所有行索引数组
22 | * @memberof DataTable
23 | * @return {array} 所有行索引数组
24 | * @example
25 | * datatable.getSelectedIndices()
26 | */
27 | var getSelectedIndices = function getSelectedIndices() {
28 | var selectedIndices = this.selectedIndices();
29 | if (selectedIndices == null || selectedIndices.length == 0) return [];
30 | return selectedIndices;
31 | };
32 |
33 | // 兼容保留,不要用
34 | var getSelectedIndexs = function getSelectedIndexs() {
35 | return this.getSelectedIndices();
36 | };
37 |
38 | /**
39 | * 获取选中行的数据信息
40 | * @memberof DataTable
41 | * @param {boolean} [withEmptyRow=false] 未选中的数据是否使用空行代替,true表示以空行代替未选中行,false相反
42 | * @return {array} 发生变化的数据信息
43 | * @example
44 | * datatable.getSelectedDatas()
45 | * datatable.getSelectedDatas(true)
46 | */
47 | var getSelectedDatas = function getSelectedDatas(withEmptyRow) {
48 | var selectedIndices = this.selectedIndices();
49 | var datas = [];
50 | var sIndices = [];
51 | for (var i = 0, count = selectedIndices.length; i < count; i++) {
52 | sIndices.push(selectedIndices[i]);
53 | }
54 | var rows = this.rows();
55 | for (var i = 0, count = rows.length; i < count; i++) {
56 | if (sIndices.indexOf(i) != -1) datas.push(rows[i].getData());else if (withEmptyRow == true) datas.push(rows[i].getEmptyData());
57 | }
58 | return datas;
59 | };
60 |
61 | /**
62 | * 获取选中的Row对象
63 | * @memberof DataTable
64 | * @return {array} 选中的Row对象
65 | * @example
66 | * datatable.getSelectedRows()
67 | */
68 | var getSelectedRows = function getSelectedRows() {
69 | var selectedIndices = this.selectedIndices();
70 | var selectRows = [];
71 | var rows = this.rows.peek();
72 | var sIndices = [];
73 | for (var i = 0, count = selectedIndices.length; i < count; i++) {
74 | sIndices.push(selectedIndices[i]);
75 | }
76 | for (var i = 0, count = rows.length; i < count; i++) {
77 | if (sIndices.indexOf(i) != -1) selectRows.push(rows[i]);
78 | }
79 | return selectRows;
80 | };
81 |
82 | var getAllPageSelectedRows = function getAllPageSelectedRows() {
83 | var rows = [];
84 | if (this.pageCache) {
85 | var pages = this.getPages();
86 | for (var i = 0; i < pages.length; i++) {
87 | var page = pages[i];
88 | if (page) {
89 | rows = rows.concat(page.getSelectRows());
90 | }
91 | }
92 | }
93 | return rows;
94 | };
95 |
96 | export var getSelectFunObj = {
97 | getSelectedIndex: getSelectedIndex,
98 | getSelectedIndices: getSelectedIndices,
99 | getSelectedIndexs: getSelectedIndexs,
100 | getSelectedDatas: getSelectedDatas,
101 | getSelectedRows: getSelectedRows,
102 | getAllPageSelectedRows: getAllPageSelectedRows
103 | };
--------------------------------------------------------------------------------
/lib/row-getData.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module : kero dataTable row getData
3 | * Author : liuyk(liuyk@yonyou.com)
4 | * Date : 2016-08-08 13:54:01
5 | */
6 | import { rowUtilFunObj } from './row-util';
7 | /**
8 | * 获取row中某一字段的值
9 | * @memberof Row
10 | * @param {string} fieldName 字段名
11 | * @return {string} 字段值
12 | * @example
13 | * row.getValue('field1')
14 | */
15 | var getValue = function getValue(fieldName) {
16 | return rowUtilFunObj._getField(this, fieldName)['value'];
17 | };
18 |
19 | //获取子表值 ,如果fieldName对应了一个子表,返回该子表的行数组
20 | var getChildValue = function getChildValue(fieldName) {
21 | var nameArr = fieldName.split('.');
22 | var _name = nameArr[0];
23 | for (var i = 0, count = nameArr.length; i < count; i++) {
24 | var _value = this.getValue(_name);
25 | //最后一级
26 | if (i == count - 1) {
27 | if (_value instanceof u.DataTable) {
28 | return _value.rows.peek();
29 | } else {
30 | return _value;
31 | }
32 | } else {
33 | if (_value instanceof u.DataTable) {
34 | _value = _value.getCurrentRow();
35 | if (!_value) return '';else return _value.getChildValue(fieldName.replace(_name + '.', ''));
36 | } else {
37 | _name = _name + '.' + nameArr[i + 1];
38 | }
39 | }
40 | }
41 | return '';
42 | };
43 |
44 | /**
45 | * 获取数据信息
46 | * @memberof Row
47 | * @return {object} 格式如下:{'id': this.rowId, 'status': this.status, data: data}
48 | * @example
49 | * row.getData()
50 | */
51 | var getData = function getData() {
52 | var data = ko.toJS(this.data);
53 | var meta = this.parent.getMeta();
54 | for (var key in meta) {
55 | if (meta[key] && meta[key].type) {
56 | if (meta[key].type == 'date' || meta[key].type == 'datetime') {
57 | if (key.indexOf('.') > 0) {
58 | //大于0说明是多级json
59 | var keys = key.split('.');
60 | var _keyValue = data;
61 | for (var i = 0, count = keys.length; i < count; i++) {
62 | _keyValue = _keyValue[keys[i]];
63 | }
64 | _keyValue.value = rowUtilFunObj._dateToUTCString(_keyValue.value);
65 | } else {
66 | data[key].value = rowUtilFunObj._dateToUTCString(data[key].value);
67 | }
68 | } else if (meta[key].type == 'child') {
69 | var chiddt = this.getValue(key),
70 | rs = chiddt.rows(),
71 | cds = [];
72 | for (var i = 0; i < rs.length; i++) {
73 | cds.push(rs[i].getData());
74 | }
75 | data[key].value = JSON.stringify(cds);
76 | }
77 | }
78 | }
79 | return {
80 | 'id': this.rowId,
81 | 'status': this.status,
82 | data: data
83 | };
84 | };
85 |
86 | // 获取空数据
87 | var getEmptyData = function getEmptyData() {
88 | return {
89 | 'id': this.rowId,
90 | 'status': this.status,
91 | data: {}
92 | };
93 | };
94 |
95 | export var rowGetDataFunObj = {
96 | getValue: getValue,
97 | getChildValue: getChildValue,
98 | getData: getData,
99 | getEmptyData: getEmptyData
100 | };
--------------------------------------------------------------------------------
/src/row-getData.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module : kero dataTable row getData
3 | * Author : liuyk(liuyk@yonyou.com)
4 | * Date : 2016-08-08 13:54:01
5 | */
6 | import {
7 | rowUtilFunObj
8 | } from './row-util';
9 | /**
10 | * 获取row中某一字段的值
11 | * @memberof Row
12 | * @param {string} fieldName 字段名
13 | * @return {string} 字段值
14 | * @example
15 | * row.getValue('field1')
16 | */
17 | const getValue = function(fieldName) {
18 | return rowUtilFunObj._getField(this, fieldName)['value']
19 | }
20 |
21 | //获取子表值 ,如果fieldName对应了一个子表,返回该子表的行数组
22 | const getChildValue = function(fieldName) {
23 | var nameArr = fieldName.split('.');
24 | var _name = nameArr[0];
25 | for (var i = 0, count = nameArr.length; i < count; i++) {
26 | var _value = this.getValue(_name);
27 | //最后一级
28 | if (i == count - 1) {
29 | if (_value instanceof u.DataTable) {
30 | return _value.rows.peek();
31 | } else {
32 | return _value;
33 | }
34 | } else {
35 | if (_value instanceof u.DataTable) {
36 | _value = _value.getCurrentRow();
37 | if (!_value)
38 | return '';
39 | else
40 | return _value.getChildValue(fieldName.replace(_name + '.', ''))
41 | } else {
42 | _name = _name + '.' + nameArr[i + 1];
43 | }
44 |
45 | }
46 | }
47 | return '';
48 | };
49 |
50 |
51 | /**
52 | * 获取数据信息
53 | * @memberof Row
54 | * @return {object} 格式如下:{'id': this.rowId, 'status': this.status, data: data}
55 | * @example
56 | * row.getData()
57 | */
58 | const getData = function() {
59 | var data = ko.toJS(this.data)
60 | var meta = this.parent.getMeta()
61 | for (var key in meta) {
62 | if (meta[key] && meta[key].type) {
63 | if (meta[key].type == 'date' || meta[key].type == 'datetime') {
64 | if (key.indexOf('.') > 0) { //大于0说明是多级json
65 | var keys = key.split('.');
66 | var _keyValue = data;
67 | for (var i = 0, count = keys.length; i < count; i++) {
68 | _keyValue = _keyValue[keys[i]];
69 | }
70 | _keyValue.value = rowUtilFunObj._dateToUTCString(_keyValue.value);
71 |
72 | } else {
73 | data[key].value = rowUtilFunObj._dateToUTCString(data[key].value)
74 | }
75 | } else if (meta[key].type == 'child') {
76 | var chiddt = this.getValue(key),
77 | rs = chiddt.rows(),
78 | cds = [];
79 | for (var i = 0; i < rs.length; i++) {
80 | cds.push(rs[i].getData());
81 | }
82 | data[key].value = JSON.stringify(cds);
83 | }
84 | }
85 | }
86 | return {
87 | 'id': this.rowId,
88 | 'status': this.status,
89 | data: data
90 | }
91 | }
92 |
93 | // 获取空数据
94 | const getEmptyData = function() {
95 | return {
96 | 'id': this.rowId,
97 | 'status': this.status,
98 | data: {}
99 | }
100 | };
101 |
102 | export const rowGetDataFunObj = {
103 | getValue: getValue,
104 | getChildValue: getChildValue,
105 | getData: getData,
106 | getEmptyData: getEmptyData
107 | }
108 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | [](https://www.npmjs.com/package/kero)
5 | [](https://travis-ci.org/iuap-design/kero)
6 | [](https://david-dm.org/iuap-design/kero#info=devDependencies)
7 | [](https://npmjs.org/package/kero)
8 |
9 |
10 | [中文文档](./README_CN.md)
11 | ## Introduction
12 | [kero](http://tinper.org/dist/kero/index.html) is a front-end model framework,As a ` MVVM ` architecture ` Model ` layer, multidimensional data Model, provide the solution for complex enterprise applications business application scenario development problems。
13 |
14 |
15 | ## Features
16 |
17 | * Abundant API
18 | * Multidimensional Data Model
19 | * Status identifier
20 | * Paging cache capacity
21 | * event trigger
22 |
23 |
24 | ## Quickstart
25 |
26 |
27 | ### Get kero
28 |
29 | - npm
30 |
31 | ```
32 | npm install kero
33 | ```
34 | * cdn
35 | ```
36 | //design.yonyoucloud.com/static/kero/latest/kero.js
37 | ```
38 | ### Introducing kero
39 |
40 | - ES6
41 | ```
42 | import { Datatable } from "kero"
43 |
44 | ```
45 | * HTML
46 |
47 | ```
48 |
49 |
50 |
51 | ```
52 |
53 | ### Use
54 |
55 | #### definition
56 |
57 |
58 | var myDataTable = new u.DataTable({
59 | meta:{
60 | field1:{required:true},
61 | field2:{}
62 | }
63 | })
64 |
65 |
66 |
67 |
68 |
69 | #### add data
70 |
71 |
72 | dataTable.setSimpleData([
73 | {"id": "001","name": "tom"},
74 | {"id": "002","name": "john"}
75 | ])
76 |
77 |
78 |
79 | #### setValue
80 |
81 | var row = dataTable.createEmptyRow();
82 | row.setValue('id','003')
83 |
84 |
85 | #### update
86 |
87 | var row = dataTable.getRow(index);
88 | row.setValue('name','jerry');
89 |
90 |
91 | #### delete
92 |
93 | dataTable.removeRow(index);
94 |
95 | #### get all data
96 |
97 | var json = dataTable.getSimpleData();
98 |
99 | #### add event trigger
100 |
101 | ```
102 | dataTable1.on('valueChange',function(event){
103 | var field = event.field,
104 | rowId = event.rowId,
105 | oldValue = event.oldValue,
106 | newValue = event.newValue;
107 | });
108 | ```
109 |
110 | Read the [Develop documentation](http://tinper.org/dist/kero/docs/overview.html) for information on the framework contents, templates and examples, and more.
111 |
112 |
113 | ## Contributing
114 |
115 | ### Develop
116 |
117 | Developers can participate in the development of kero, but also can be based on kero two development
118 |
119 |
120 | kero use gulp.js and webpack build the project.
121 |
122 |
123 | clone:
124 |
125 | ```
126 | $ git clone git@github.com:iuap-design/kero.git
127 | ```
128 |
129 | install:
130 |
131 | ```
132 | $ npm install
133 | ```
134 |
135 | build:
136 |
137 | ```
138 | $ npm run product
139 | ```
140 |
141 | ### Feedback
142 |
143 | If you encounter any problems , submit [issues](https://github.com/iuap-design/kero/issues),or pull request。
144 |
145 | [PR code](CONTRIBUTING.md)
146 |
147 |
148 | ## Licence 版权
149 |
150 | [MIT](./LICENSE)
151 |
--------------------------------------------------------------------------------
/src/page-getData.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module : kero dataTable page getData
3 | * Author : liuyk(liuyk@yonyou.com)
4 | * Date : 2016-08-08 09:59:01
5 | */
6 |
7 | /**
8 | * 获取Page的数据信息
9 | * @memberof Page
10 | * @return {array} 数据信息对应的数组,每项对应一条数据
11 | * @example
12 | * page.getData()
13 | */
14 | const getData = function() {
15 | var datas = [],
16 | row, meta;
17 | meta = this.parent.getMeta()
18 | for (var i = 0; i < this.rows.length; i++) {
19 | row = this.rows[i];
20 | datas.push({
21 | 'id': row.rowId,
22 | 'status': row.status,
23 | data: row.data
24 | });
25 | }
26 | return datas
27 | }
28 |
29 |
30 | /**
31 | * 获取Page的选中行数据信息
32 | * @memberof Page
33 | * @return {array} 数据信息对应的数组,每项对应一条数据
34 | * @example
35 | * page.getSelectDatas()
36 | */
37 | const getSelectDatas = function() {
38 | var datas = [],
39 | row;
40 | for (var i = 0; i < this.rows.length; i++) {
41 | row = this.rows[i];
42 | datas.push({
43 | 'id': row.rowId,
44 | 'status': row.status,
45 | data: row.data
46 | });
47 | }
48 | for (var i = 0; i < this.selectedIndices.length; i++) {
49 | row = this.rows[this.selectedIndices[i]];
50 | datas.push({
51 | 'id': row.rowId,
52 | 'status': row.status,
53 | data: row.data
54 | });
55 | }
56 | return datas
57 | }
58 |
59 |
60 | /**
61 | * 获取Page的选中Row对象
62 | * @memberof Page
63 | * @return {array} Row对象对应的数组,每项对应一条数据
64 | * @example
65 | * page.getSelectRows()
66 | */
67 | const getSelectRows = function() {
68 | var rows = [];
69 | for (var i = 0; i < this.selectedIndices.length; i++) {
70 | rows.push(this.rows[this.selectedIndices[i]])
71 | }
72 | return rows
73 | }
74 |
75 |
76 | /**
77 | * 获取发生改变的Row对象
78 | * @memberof DataTable
79 | * @return {array} 发生改变的Row对象
80 | * @example
81 | * datatable.getChangedRows()
82 | */
83 | const getChangedRows = function() {
84 | var changedRows = [],
85 | rows = this.rows;
86 | for (var i = 0, count = rows.length; i < count; i++) {
87 | if (rows[i] && rows[i].status != Row.STATUS.NORMAL) {
88 | changedRows.push(rows[i])
89 | }
90 | }
91 | return changedRows
92 | }
93 | /**
94 | * 根据rowid获取Row对象
95 | * @memberof Page
96 | * @param {string} rowid 需要获取的Row对应的rowid
97 | * @returns {Row} Row对象
98 | * @example
99 | * page.getRowByRowId('rowid')
100 | */
101 | const getRowByRowId = function(rowid) {
102 | for (var i = 0, count = this.rows.length; i < count; i++) {
103 | if (this.rows[i].rowId == rowid)
104 | return this.rows[i]
105 | }
106 | return null
107 | }
108 |
109 | /**
110 | * 根据行索引获取对应行的字段值
111 | * @memberof Page
112 | * @param {number} rowIndex 行索引
113 | * @param {string} fieldName 字段名
114 | * @returns {sting} 字段值
115 | * @example
116 | * page.getRowValue(1,'field1')
117 | */
118 | const getRowValue = function(rowIndex, fieldName) {
119 | var row = this.rows[rowIndex]
120 | if (row) {
121 | return row.data[fieldName]['value']
122 | }
123 | return null
124 | }
125 |
126 | export const pageGetDataFunObj = {
127 | getData: getData,
128 | getSelectDatas: getSelectDatas,
129 | getSelectRows: getSelectRows,
130 | getChangedRows: getChangedRows,
131 | getRowByRowId: getRowByRowId,
132 | getRowValue: getRowValue
133 | }
134 |
--------------------------------------------------------------------------------
/lib/page-getData.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module : kero dataTable page getData
3 | * Author : liuyk(liuyk@yonyou.com)
4 | * Date : 2016-08-08 09:59:01
5 | */
6 |
7 | /**
8 | * 获取Page的数据信息
9 | * @memberof Page
10 | * @return {array} 数据信息对应的数组,每项对应一条数据
11 | * @example
12 | * page.getData()
13 | */
14 | var getData = function getData() {
15 | var datas = [],
16 | row,
17 | meta;
18 | meta = this.parent.getMeta();
19 | for (var i = 0; i < this.rows.length; i++) {
20 | row = this.rows[i];
21 | datas.push({
22 | 'id': row.rowId,
23 | 'status': row.status,
24 | data: row.data
25 | });
26 | }
27 | return datas;
28 | };
29 |
30 | /**
31 | * 获取Page的选中行数据信息
32 | * @memberof Page
33 | * @return {array} 数据信息对应的数组,每项对应一条数据
34 | * @example
35 | * page.getSelectDatas()
36 | */
37 | var getSelectDatas = function getSelectDatas() {
38 | var datas = [],
39 | row;
40 | for (var i = 0; i < this.rows.length; i++) {
41 | row = this.rows[i];
42 | datas.push({
43 | 'id': row.rowId,
44 | 'status': row.status,
45 | data: row.data
46 | });
47 | }
48 | for (var i = 0; i < this.selectedIndices.length; i++) {
49 | row = this.rows[this.selectedIndices[i]];
50 | datas.push({
51 | 'id': row.rowId,
52 | 'status': row.status,
53 | data: row.data
54 | });
55 | }
56 | return datas;
57 | };
58 |
59 | /**
60 | * 获取Page的选中Row对象
61 | * @memberof Page
62 | * @return {array} Row对象对应的数组,每项对应一条数据
63 | * @example
64 | * page.getSelectRows()
65 | */
66 | var getSelectRows = function getSelectRows() {
67 | var rows = [];
68 | for (var i = 0; i < this.selectedIndices.length; i++) {
69 | rows.push(this.rows[this.selectedIndices[i]]);
70 | }
71 | return rows;
72 | };
73 |
74 | /**
75 | * 获取发生改变的Row对象
76 | * @memberof DataTable
77 | * @return {array} 发生改变的Row对象
78 | * @example
79 | * datatable.getChangedRows()
80 | */
81 | var getChangedRows = function getChangedRows() {
82 | var changedRows = [],
83 | rows = this.rows;
84 | for (var i = 0, count = rows.length; i < count; i++) {
85 | if (rows[i] && rows[i].status != Row.STATUS.NORMAL) {
86 | changedRows.push(rows[i]);
87 | }
88 | }
89 | return changedRows;
90 | };
91 | /**
92 | * 根据rowid获取Row对象
93 | * @memberof Page
94 | * @param {string} rowid 需要获取的Row对应的rowid
95 | * @returns {Row} Row对象
96 | * @example
97 | * page.getRowByRowId('rowid')
98 | */
99 | var getRowByRowId = function getRowByRowId(rowid) {
100 | for (var i = 0, count = this.rows.length; i < count; i++) {
101 | if (this.rows[i].rowId == rowid) return this.rows[i];
102 | }
103 | return null;
104 | };
105 |
106 | /**
107 | * 根据行索引获取对应行的字段值
108 | * @memberof Page
109 | * @param {number} rowIndex 行索引
110 | * @param {string} fieldName 字段名
111 | * @returns {sting} 字段值
112 | * @example
113 | * page.getRowValue(1,'field1')
114 | */
115 | var getRowValue = function getRowValue(rowIndex, fieldName) {
116 | var row = this.rows[rowIndex];
117 | if (row) {
118 | return row.data[fieldName]['value'];
119 | }
120 | return null;
121 | };
122 |
123 | export var pageGetDataFunObj = {
124 | getData: getData,
125 | getSelectDatas: getSelectDatas,
126 | getSelectRows: getSelectRows,
127 | getChangedRows: getChangedRows,
128 | getRowByRowId: getRowByRowId,
129 | getRowValue: getRowValue
130 | };
--------------------------------------------------------------------------------
/README_CN.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | [](https://www.npmjs.com/package/kero)
5 | [](https://travis-ci.org/iuap-design/kero)
6 | [](https://david-dm.org/iuap-design/kero#info=devDependencies)
7 | [](https://npmjs.org/package/kero)
8 |
9 |
10 | [English Document](./README.md)
11 | ## 介绍
12 | [kero](http://tinper.org/dist/kero/index.html) 是一个前端模型框架,做为`MVVM` 架构中 `Model` 层的增强,提供多维数据模型,解决企业应用中复杂的业务应用场景的开发问题。
13 |
14 |
15 | ## 功能
16 |
17 |
18 | - **丰富的API:** 对外暴露丰富的增删改查API,方便开发者对页面数据的管理
19 |
20 | - **多维数据模型:** 解决了字段关联、主子数据、主子孙等多维数据模型的绑定问题
21 |
22 | - **状态标识:** 数据增加状态标识:新增、修改、删除,方便开发者使用
23 |
24 | - **分页缓存能力:** 具有分页缓存能力,可在前台处理分页,实现跨页操作数据(非必要情况下,不推荐前台分页)
25 |
26 | - **事件触发器:** 具有事件触发器,增删改查过程中的数据变化通过on方法添加监听,供开发者使用
27 |
28 | ## 快速上手
29 |
30 | ### 获取kero
31 |
32 | - npm资源
33 |
34 | ```
35 | npm install kero
36 | ```
37 | - cdn 资源
38 | ```
39 | //design.yonyoucloud.com/static/kero/latest/js/kero.js
40 | ```
41 |
42 | ### 引入kero
43 | - ES6语法
44 | ```
45 | import { Datatable } from "kero"
46 |
47 | ```
48 | - HTML直接引入
49 | ```
50 |
51 |
52 |
53 | ```
54 |
55 | ### 简单示例
56 |
57 | #### 模型定义
58 |
59 | 模型定义方法:
60 |
61 | var myDataTable = new DataTable({
62 | meta:{
63 | id:{required:true},
64 | name:{}
65 | }
66 | })
67 |
68 |
69 | meta中是模型的字段信息,字段名对应的对象为字段的属性定义。没有字段属性时,可以为空对象。
70 |
71 | 字段的属性值在控件模型中被使用到,主要用于控制表单输入、字段显示格式等业务特性。
72 |
73 |
74 |
75 | #### 数据载入到模型中
76 |
77 | 模型定义好之后,可以通过`dataTable.setSimpleData`方法把从后台查询到的json数据载入模型之中:
78 |
79 | myDataTable.setSimpleData([
80 | {"id": "001","name": "tom"},
81 | {"id": "002","name": "john"}
82 | ])
83 |
84 | 数据载入到模型中之后,数据被存储在一组`Row`对象之中,json数组中的每一个对象,对应dataTable中的`Row`对象中。
85 |
86 |
87 | #### 新增数据行并赋值
88 |
89 | var row = myDataTable.createEmptyRow();
90 | row.setValue('id','003')
91 |
92 | 新增的数据在dataTable中表现为新增一个`Row`对象。调用`setValue`对其中字段赋值。
93 |
94 | #### 修改已存在的行中数据
95 |
96 | var row = myDataTable.getRow(index);//index为行的索引,index为0说明获取的是第一行数据
97 | row.setValue('name','jerry');//修改后第一行的对象的name为jerry
98 |
99 |
100 | #### 删除某一行数据
101 |
102 | myDataTable.removeRow(index);//index为行的索引
103 |
104 | #### 获取所有数据
105 |
106 | var json = myDataTable.getSimpleData();
107 |
108 | #### 添加事件监听
109 |
110 | 示例如下:
111 |
112 | ```
113 | //数据改变监听
114 | myDataTable.on('valueChange',function(event){
115 | var field = event.field,
116 | rowId = event.rowId,
117 | oldValue = event.oldValue,
118 | newValue = event.newValue;
119 | });
120 | ```
121 | 开发文档详见[这里](http://tinper.org/dist/kero/docs/overview.html)。
122 |
123 |
124 | ## 如何参与贡献
125 |
126 | ### 开发及构建
127 |
128 | 开发者可以一起参与为 kero 贡献代码,同时也可以基于 kero 进行二次开发或封装插件。
129 |
130 | 克隆项目文件:
131 |
132 | ```
133 | $ git clone git@github.com:iuap-design/kero.git
134 | ```
135 |
136 | 然后进入目录安装依赖:
137 |
138 | ```
139 | $ npm install
140 | ```
141 |
142 | 接下来,执行 `gulp`:
143 |
144 | ```
145 | $ npm run product
146 | ```
147 |
148 |
149 | ### 反馈
150 | 如在使用过程中遇到任何问题,可以在[这里](https://github.com/iuap-design/kero/issues)提交issue反馈;
151 |
152 | 或者直接fork代码到你的github仓库,提交pull request给我们。
153 |
154 |
155 | [Bug 反馈及需求提交](CONTRIBUTING.md)
156 |
157 | ## Licence 版权
158 |
159 | [MIT](./LICENSE)
160 |
--------------------------------------------------------------------------------
/docs/dataTableUseBackend.md:
--------------------------------------------------------------------------------
1 | # DataTable后端使用
2 | 后端DataTable主要是在后端的Controller里面操作DataTable类提供的api来达到更新前端页面的效果,这样就达到了前后台一体化开发的目的。
3 | ## 后端DataTable的基本使用
4 | ### 使用的例子
5 | 先来看一个常用的例子,下面的代码是实现分页的后端Controller的代码。
6 |
7 | ``` java
8 | @RequestMapping(value = "initDb", method = RequestMethod.POST)
9 | public @ResponseBody EventResponse initDt(@IWeb参数eter(id = "data1") DataTable data1,
10 | @IWeb参数eter() EventResponse response) throws Exception {
11 | //准备分页信息
12 | PagePOJO page = new PagePOJO();
13 | page.setCurrentPage(data1.getPageIndex());
14 | page.setPageSize(data1.getPageSize());
15 |
16 | //查询条件
17 | ProdSpecQuery参数eter psqp = new ProdSpecQuery参数eter();
18 | //查询数据
19 | PageBean pagebean = prodSpecService.queryPageByCondition(page, psqp);
20 | @SuppressWarnings("unchecked")
21 | List resultList = (List) pagebean.getResultList();
22 |
23 | data1.set(resultList.toArray(new ProdSpecHPOJO[resultList.size()]));
24 | Long totalpage = pagebean.getTotalPage();
25 | data1.setTotalPages(totalpage.intValue());
26 | return response;
27 |
28 | }
29 | ```
30 | 后端的DataTable对象通过注解的方式可以直接获得;通过datatable.getPageIndex()和datatable.getPageSize()可以获得datatable上的分页信息;datatable.set()方法可以直接将一个普通的java对象数组转化成datatable上的行数据;datatable.setTotalPages()可以设置分页信息。
31 | 这就是后端datatable基本使用方法。
32 | ## DataTable api
33 | ### 基本属性
34 | ##### getId
35 | 获取id
36 | ##### setId
37 | 设置取id
38 |
39 | ##### get参数s
40 | 获取datatable上的设置的参数
41 |
42 | ##### set参数s
43 | 设置datatable上的设置的参数
44 |
45 | ### 基本的增删改查
46 | ##### getRow
47 | 根据rowid获取row
48 |
49 | ##### getSelectRow
50 | 获取所有选中行
51 |
52 | ##### getFocusRow
53 | 获取聚焦行
54 |
55 | ##### getCurrentRow
56 | 获取当前行,当前行为聚焦行,如果聚焦行不存在,则取选中行
57 |
58 | ##### getAllRow
59 | 获取datatable上的所有行
60 |
61 | ##### getAllPagesRow
62 | 获取所有页上的所有行
63 |
64 | ##### addRow
65 | 增加一行
66 |
67 | ##### addRows
68 | 增加多行
69 |
70 | ##### remove
71 | 可以传入一个普通java对象或者对象数组或者Row对象
72 |
73 | ##### createEmptyRow
74 | 生成一个新行
75 |
76 | ### meta相关
77 |
78 | ##### getMeta
79 | 获取meta信息
80 |
81 | ##### setMeta
82 | 设置meta
83 |
84 | ##### updateMeta
85 | 更新meta信息
86 |
87 |
88 |
89 |
90 | ### VO相关
91 | ##### set
92 | 这个方法是一个比较常用的方法,可以传入一个ISetRowHandler参数,它提供了两个方法beforSet和afterSet,可以在每增加一行之前或之后做一些处理。
93 |
94 | ##### getAll
95 | 获取所有的行
96 |
97 | ##### getFocusPuppet
98 | 获取聚焦行的vo
99 |
100 | ##### getSelectPuppet
101 | 获取所有选中行的vo
102 |
103 | ##### getT
104 | 将row对象转化成vo
105 |
106 | ##### remove
107 | 删除vo对应的row
108 |
109 | ##### getCls
110 | 获取vo的类名
111 |
112 | ##### setCls
113 | 设置vo类名
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 | ### 分页有关方法
122 | ##### getPageIndex
123 | 获取当前页号
124 | ##### setPageIndex
125 | 设置当前页号
126 | ##### getPageSize
127 | 获取一页的行数
128 | ##### setPageSize
129 | 设置一页的行数
130 | ##### getTotalPage
131 | 获取页数
132 | ##### setTotalPage
133 | 设置页数
134 | ##### getPage
135 | 获取某一页
136 | ##### addPage
137 | 增加一页
138 | ##### removePage
139 | 删除某一页
140 |
141 | ### 其他
142 | ##### breed
143 | 克隆一个新的datatable
144 | ##### isBread
145 | 是否是克隆出来的
146 |
147 | ## 3. Row api
148 | ##### getId
149 | 获取id
150 |
151 | ##### setId
152 | 设置id
153 |
154 | ##### getEntity
155 | 获取datatable
156 |
157 | ##### setEntity
158 | 设置datatable
159 |
160 | ##### setData
161 | 设置row上的数据
162 |
163 | ##### getField
164 | 获取某个字段
165 | ##### addField
166 | 添加一个字段
167 | ##### getFields
168 | 获取所有字段
169 |
170 | ##### getChangedFields
171 | 获取所有字段值改变过的字段
172 |
173 | ##### getStatus
174 | 获取行的状态
175 |
176 | ##### setStatus
177 | 设置行的状态
178 |
179 | ## 4. Field api
180 | ##### getFid
181 | 获取字段id
182 | ##### setFid
183 | 设置字段id
184 | ##### getValue
185 | 获取字段值
186 | ##### setValue
187 | 设置字段值
188 | ##### getMeta
189 | 获取meta
190 | ##### setMeta
191 | 设置meta
192 | ##### setDesc
193 | 添加meta项
194 | ##### getRow
195 | 获取字段所在的行
196 | ##### setRow
197 | 设置字段的行
198 |
--------------------------------------------------------------------------------
/snippets/validateapi/base.md:
--------------------------------------------------------------------------------
1 |
2 | ## 验证设置Validate
3 |
4 | 创建dataTable,field字段中验证字段,基本设置如下:
5 |
6 | new u.DataTable({
7 | meta:{
8 | field:{
9 | required: true,
10 | nullMsg: '内容不能为空!',
11 | errorMsg: '内容输入错误',
12 | placement: 'top'
13 | ...
14 | }
15 | }
16 | })
17 |
18 | *params*:
19 |
20 | `meta`: 字段信息集合,其中的key为字段名,value为字段属性信息,属性信息可自定义
21 |
22 | ---
23 | ### required
24 |
25 | `required`:指定输入字段是否为必填项,默认为`false`
26 |
27 | | Key | Value | 说明 |
28 | | -------- | ----- | ------- |
29 | | required | true | 字段为必填项 |
30 | | required | false | 字段为非必填项 |
31 |
32 |
33 |
34 | ---
35 |
36 |
37 | ### validType
38 |
39 | `validType`:验证输入类型,默认值为`null`
40 |
41 | | Key | Value | 说明 |
42 | | --------- | -------- | -------- |
43 | | validType | integer | 输入需为整数 |
44 | | validType | float | 输入需为浮点数 |
45 | | validType | zipCode | 输入需为邮编 |
46 | | validType | phone | 输入需为手机号码 |
47 | | validType | landline | 输入需为座机号码 |
48 | | validType | email | 输入需为邮箱 |
49 | | validType | url | 输入需为网址 |
50 | | validType | datetime | 输入需为日期 |
51 |
52 |
53 |
54 | ***
55 |
56 |
57 | ### nullMsg/errorMsg
58 |
59 | `nullMsg`:输入为空时的提示信息
60 |
61 | `errorMsg`:输入错误时的提示信息
62 |
63 | | Key | Value | 说明 |
64 | | -------- | ------------------ | ---------- |
65 | | nullMsg | 内容自定义:输入为空显示的内容 | 输入为空时的提示信息 |
66 | | errorMsg | 内容自定义:输入错误时显示的内容 | 输入错误时的提示信息 |
67 |
68 |
69 |
70 | ---
71 | ### regExp
72 |
73 | `regExp`:设置正则匹配
74 |
75 | | Key | Value | 说明 |
76 | | ------ | --------- | ---------- |
77 | | regExp | 正则表达式 | 文本框需要匹配的正则 |
78 |
79 |
80 |
81 | ---
82 | ### notipFlag
83 |
84 | `notipFlag`:错误信息提示方式是否为`tooltip`,默认为`false`
85 |
86 | | Key | Value | 说明 |
87 | | --------- | ----- | ------------------ |
88 | | notipFlag | false| 错误信息提示为tips形式 |
89 | | notipFlag | true| 错误信息提示自定义,不为tips形式 |
90 |
91 |
92 |
93 | ---
94 | ### tipId
95 | `tipId`: 指定`tooltip`显示位置,其值为显示dom元素的id,默认为空,使用默认的`tooltip`
96 |
97 | | Key | Value | 说明 |
98 | | ----- | ----- | ----------------- |
99 | | tipId | ' ' | 使用默认的tooltip显示tip |
100 | | tipId | id | 使用自定义的id元素显示tip |
101 |
102 |
103 |
104 | ---
105 | ### hasSuccess
106 | `hasSuccess`:输入正确后是否提示。默认为`false`
107 |
108 | | Key | Value | 说明 |
109 | | ---------- | ----- | -------- |
110 | | hasSuccess | true | 输入正确后提示 |
111 | | hasSuccess | false | 输入正确后不提示 |
112 |
113 |
114 |
115 | ---
116 | ### successId
117 | `successId`:指定正确提示信息的位置,其值为正确dom元素的id,默认在输入框的后面显示
118 |
119 | | Key | Value | 说明 |
120 | | --------- | ----- | --------------- |
121 | | successId | id | 使用自定义的id元素显示正确提示信息 |
122 |
123 | `successId`能正常显示的前提是`hasSuccess:true`
124 |
125 |
126 |
127 | ---
128 |
129 | ### placement
130 |
131 | `placement`:提示框位置,默认为`top`
132 |
133 | | Key | Value | 说明 |
134 | | --------- | ------ | ---- |
135 | | placement | top | 上部显示 |
136 | | placement | bottom | 底部显示 |
137 | | placement | left | 左边显示 |
138 | | placement | right | 右边显示 |
139 |
140 |
141 | ---
142 | ### minLength&maxLength
143 |
144 | 字符串长度,注意`type`类型`string`
145 |
146 |
147 | | Key | Value | 说明 |
148 | | --------- | ----- | ---- |
149 | | minLength | num | 最小长度 |
150 | | maxLength | num | 最大长度 |
151 |
152 |
153 |
154 | ---
155 | ### 数值区间
156 |
157 | 数值区间,注意`type`类型`integer`或`float`
158 |
159 |
160 | | Key | Value | 说明 |
161 | | -------- | ----- | --------- |
162 | | min | num | 最小数值(包含) |
163 | | max | num | 最大数值(包含) |
164 | | minNotEq | num | 最小数值(不包含) |
165 | | maxNotEq | num | 最大数值(不包含) |
166 |
167 |
168 |
169 | ---
170 |
171 | ### 基本示例
172 |
173 |
174 |
175 |
176 |
177 | [试一试](http://tinper.org/webide/#/demos/kero/validate)
178 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | /* global __dirname */
2 |
3 | var path = require('path');
4 | var webpack = require('webpack');
5 | var UglifyJsPlugin = webpack.optimize.UglifyJsPlugin;
6 | var fs = require('fs');
7 |
8 | var dir_js = path.resolve(__dirname, 'src');
9 | var dir_build = path.resolve(__dirname, 'dist');
10 |
11 | var libraryName = 'kero';
12 |
13 | var data = fs.readFileSync('./package.json', 'utf8');
14 | var packageObj = JSON.parse(data);
15 | var headerStr = '';
16 | headerStr += packageObj.name + ' v' + packageObj.version + '\r\n';
17 | headerStr += packageObj.description + '\r\n';
18 | headerStr += 'author : ' + packageObj.author + '\r\n';
19 | headerStr += 'homepage : ' + packageObj.homepage + '\r\n';
20 | headerStr += 'bugs : ' + packageObj.bugs.url;
21 | var plugins = [new webpack.BannerPlugin(headerStr),
22 | new webpack.LoaderOptionsPlugin({
23 | minimize: true
24 | }),
25 | new webpack.NoErrorsPlugin()
26 | ]
27 |
28 | var returnFUn = function(env) {
29 | var mode = env.mode,
30 | outputFile;
31 |
32 | if (mode == 'build') {
33 | outputFile = libraryName + '.min.js';
34 | plugins.push(new webpack.optimize.UglifyJsPlugin({
35 | mangle: true,
36 | beautify: true
37 | }))
38 | plugins.push(new UglifyJsPlugin({
39 | minimize: true
40 | }));
41 | } else {
42 | outputFile = libraryName + '.js';
43 | plugins.push(new webpack.optimize.UglifyJsPlugin({
44 | mangle: false,
45 | beautify: true
46 | }))
47 | }
48 |
49 | var obj = {
50 | entry: path.resolve(dir_js, 'index.js'),
51 | output: {
52 | path: dir_build,
53 | filename: outputFile
54 | },
55 | devServer: {
56 | contentBase: dir_build,
57 | },
58 | module: {
59 | loaders: [{
60 | loader: 'babel-loader',
61 | test: dir_js,
62 | query: {
63 | //presets: ['es2015'],
64 |
65 | // All of the plugins of babel-preset-es2015,
66 | // minus babel-plugin-transform-es2015-modules-commonjs
67 | plugins: [
68 | 'transform-es2015-template-literals',
69 | 'transform-es2015-literals',
70 | 'transform-es2015-function-name',
71 | 'transform-es2015-arrow-functions',
72 | 'transform-es2015-block-scoped-functions',
73 | 'transform-es2015-classes',
74 | 'transform-es2015-object-super',
75 | 'transform-es2015-shorthand-properties',
76 | 'transform-es2015-computed-properties',
77 | 'transform-es2015-for-of',
78 | 'transform-es2015-sticky-regex',
79 | 'transform-es2015-unicode-regex',
80 | 'check-es2015-constants',
81 | 'transform-es2015-spread',
82 | 'transform-es2015-parameters',
83 | 'transform-es2015-destructuring',
84 | 'transform-es2015-block-scoping',
85 | 'transform-es2015-typeof-symbol', ['transform-regenerator', {
86 | async: false,
87 | asyncGenerators: false
88 | }],
89 | ],
90 | },
91 | }]
92 | },
93 | plugins: plugins,
94 | stats: {
95 | // Nice colored output
96 | colors: true
97 | },
98 | // Create source maps for the bundle
99 | devtool: 'source-map',
100 | }
101 | return obj;
102 | }
103 | module.exports = returnFUn;
104 |
--------------------------------------------------------------------------------
/src/indexRow.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module : Kero webpack entry row index
3 | * Author : liuyk(liuyuekai@yonyou.com)
4 | * Date : 2016-08-09 15:24:46
5 | */
6 |
7 | import {
8 | Events
9 | } from './indexEvents';
10 |
11 |
12 | import {
13 | rowDataFunObj
14 | } from './row-data';
15 |
16 | import {
17 | rowGetDataFunObj
18 | } from './row-getData';
19 |
20 | import {
21 | rowGetMetaFunObj
22 | } from './row-getMeta';
23 |
24 | import {
25 | rowGetSimpleDataFunObj
26 | } from './row-getSimpleData';
27 |
28 | import {
29 | rowInitFunObj
30 | } from './row-init';
31 |
32 | import {
33 | rowMetaFunObj
34 | } from './row-meta';
35 |
36 | import {
37 | rowRefFunObj
38 | } from './row-ref';
39 |
40 | import {
41 | rowRowSelectFunObj
42 | } from './row-rowSelect';
43 |
44 | import {
45 | rowSimpleDataFunObj
46 | } from './row-simpleData';
47 |
48 | import {
49 | rowUtilFunObj
50 | } from './row-util';
51 |
52 |
53 | /**
54 | * Row
55 | * @namespace
56 | * @description 前端数据模型行对象
57 | */
58 |
59 | class Row extends Events {
60 | constructor(options) {
61 | super();
62 | var self = this;
63 | /**
64 | * 当前行的唯一标识
65 | * @type {string}
66 | */
67 | this.rowId = options['id'] || Row.getRandomRowId()
68 | /**
69 | * 当前行的状态
70 | * Row.STATUS.NORMAL('nrm') :前后端都存在并且保持一致
71 | * Row.STATUS.UPDATE('upd') :前后端都存在并且前端进行了修改
72 | * Row.STATUS.NEW('new') :后端不存在,前端存在的数据
73 | * Row.STATUS.DELETE('del') :后端请求返回的状态,前端判断为此状态则将数据删除
74 | * Row.STATUS.FALSE_DELETE('fdel') :后端存在,前端不存在的数据
75 | * @type {string}
76 | * @default Row.STATUS.NEW
77 | */
78 | this.status = Row.STATUS.NEW
79 | /**
80 | * 当前行对应的DataTable对象
81 | * @type {u.DataTable}
82 | */
83 | this.parent = options['parent']
84 | // 当前行的数据信息
85 | this.data = {}
86 | // 存储meta改变信息
87 | this.metaChange = {} //ko.observable(1)
88 | // 存储valuecahnge改变信息
89 | this.valueChange = {};
90 | // 监听当前行改变
91 | this.currentRowChange = ko.observable(1);
92 | // 监听当前行是否选中
93 | this.selected = ko.pureComputed({
94 | read: function() {
95 | var index = this.parent.getRowIndex(this);
96 | var selectindices = this.parent.getSelectedIndices();
97 | return selectindices.indexOf(index) != -1;
98 | },
99 | owner: this
100 |
101 | })
102 | // 监听当前行是否为focus
103 | this.focused = ko.pureComputed({
104 | read: function() {
105 | var index = this.parent.getRowIndex(this);
106 | var focusIndex = this.parent.getFocusIndex()
107 | return focusIndex == index;
108 | },
109 | owner: this
110 |
111 | })
112 | this.init();
113 | }
114 | }
115 | const RowProto = Row.prototype;
116 | Object.assign(RowProto, rowDataFunObj);
117 | Object.assign(RowProto, rowGetDataFunObj);
118 | Object.assign(RowProto, rowGetMetaFunObj);
119 | Object.assign(RowProto, rowGetSimpleDataFunObj);
120 | Object.assign(RowProto, rowInitFunObj);
121 | Object.assign(RowProto, rowMetaFunObj);
122 | Object.assign(RowProto, rowRefFunObj);
123 | Object.assign(RowProto, rowRowSelectFunObj);
124 | Object.assign(RowProto, rowSimpleDataFunObj);
125 | Object.assign(RowProto, rowUtilFunObj);
126 |
127 | Row.STATUS = {
128 | NORMAL: 'nrm',
129 | UPDATE: 'upd',
130 | NEW: 'new',
131 | DELETE: 'del',
132 | FALSE_DELETE: 'fdel'
133 | }
134 |
135 | /*
136 | * 生成随机行id
137 | * @private
138 | */
139 | Row.getRandomRowId = function() {
140 | var _id = setTimeout(function() {})
141 | return _id + '';
142 | };
143 | //为了能让rowUtilFunObj给项目组重写,主要重写eq方法-huyue
144 | window.u = window.u || {};
145 | u = window.u;
146 | u.rowUtilFunObj = rowUtilFunObj;
147 |
148 | export {
149 | Row
150 | }
151 |
--------------------------------------------------------------------------------
/snippets/datatable/base.md:
--------------------------------------------------------------------------------
1 | ## 数据模型
2 |
3 | 数据模型(dataTabe)作为MVVM架构中Model层的增强。主要功能有:
4 |
5 | + 以行、列的形式,通过json对象对数据做存储,并对外暴露一批增删改查的API,方便开发者对页面数据的处理,而且所有开发者之间做到统一,减少出错概率。
6 | + 数据增加状态标识新增或修改,方便开发者使用。
7 | + 具有分页缓存能力,可在前端处理分页(非必要情况下,不推荐前端分页)。
8 | + 提供事件监听u.on(element, eventName,child,listener),把数据变化触发出去,供开发者监听使用。
9 |
10 |
11 | ### 模型定义
12 |
13 | 模型定义方法:
14 |
15 | var myDataTable = new u.DataTable({
16 | meta:{
17 | field1:{type:date},
18 | field2:{}
19 | }
20 | })
21 |
22 |
23 | meta中是模型的字段信息,字段名对应的对象为字段的属性定义。其中常用字段的属性定义的有type、以及一些校验属性(详情参考[这里](/moy/kero-data.html#验证设置Validate))、default(设置字段的默认值)以及不同控件的属性设置等。没有字段属性时,可以为空对象。
24 |
25 | * 下面是常用的type类型。
26 | + string:字符串
27 | + integer:整型
28 | + float:浮点型
29 | + date: 日期类型(YY-MM-DD)
30 | + datetime:日期时间类型(YY-MM-DD hh:mm:ss)
31 |
32 | * default可以对应函数(返回具体的默认值),也可以是具体的对象。
33 |
34 | + 对应函数的写法。
35 |
36 | ```
37 | meta: {
38 | f1: {
39 | default: function() {
40 | return '02-01';//'02-01'为返回的默认值
41 | }
42 | }
43 | }
44 | ```
45 |
46 | + 对应对象的写法。default:function(){return 'aa'}。
47 |
48 | ```
49 | meta: {
50 | f1: {
51 | default: {
52 | value: '02-01'//value对应具体的默认值
53 | }
54 | }
55 | }
56 | ```
57 | * 控件的属性设置
58 |
59 | (1)integerAdapter (整数)
60 |
61 | |属性名称| 属性值类型|具体描述|
62 | | ------- | :-------: | ------: |
63 | |max|integer|输入的值小于等于max|
64 | |min|integer|输入的值大于等于min|
65 | |maxNotEq|integer|输入的值小于max|
66 | |minNotEq|integer|输入的值大于min|
67 |
68 | (2) stringAdapter (字符串)
69 |
70 | |属性名称| 属性值类型|具体描述|
71 | |-------|:-------:|------:|
72 | |minLength|integer|输入的字符串长度大于等于minLength|
73 | |maxLength|integer|输入的字符串长度小于等于maxLength|
74 |
75 | (3) floatAdapter(浮点数)
76 |
77 | |属性名称| 属性值类型|具体描述|默认值|
78 | |-------|:-------:|:------:|------|
79 | |precision|integer|浮点数的精度|2|
80 | |max|integer|输入的值小于等于max| |
81 | |min|integer|输入的值大于等于min| |
82 | |maxNotEq|integer|输入的值小于max| |
83 | |minNotEq|integer|输入的值大于min| |
84 |
85 | (4)currencyAdapter(货币)
86 |
87 | |属性名称| 属性值类型|具体描述|默认值|
88 | |-------|:-------:|:------:|------|
89 | |precision|integer|浮点数的精度|2|
90 | |max|integer|输入的值小于等于max||
91 | |min|integer|输入的值大于等于min||
92 | |maxNotEq|integer|输入的值小于max||
93 | |minNotEq|integer|输入的值大于min||
94 | |curSymbol|String|货币符号|¥|
95 |
96 | (5) percentAdapter(百分比)
97 |
98 | |属性名称| 属性值类型|具体描述|默认值|
99 | |-------|:-------:|:------:|------|
100 | |precision|integer|浮点数的精度|2|
101 |
102 |
103 |
104 |
105 | 字段的属性值在控件模型中被使用到,主要用于控制表单输入、字段显示格式等业务特性。
106 |
107 |
108 |
109 | ### 数据载入到模型中
110 |
111 | 模型定义好之后,可以通过`dataTable.setSimpleData`方法把从后台查询到的json数据载入模型之中:
112 |
113 | dataTable.setSimpleData([
114 | {"id": "001","name": "tom"},
115 | {"id": "002","name": "john"}
116 | ])
117 |
118 | 数据载入到模型中之后,数据被存储在一组`Row`对象之中,json数组中的每一个对象,对应dataTable中的`Row`对象中。
119 |
120 |
121 | ### 数据的新增与修改
122 |
123 | #### 新增数据行并赋值
124 |
125 | var row = dataTable.createEmptyRow();
126 | row.setValue('id','003')
127 |
128 | 新增的数据在dataTable中表现为新增一个`Row`对象。调用`setValue`对其中字段赋值。
129 |
130 | #### 修改已存在的行中数据
131 |
132 | var row = dataTable.getRow(index);
133 | row.setValue('name','jerry');
134 |
135 |
136 | ### 数据的删除
137 |
138 | #### 删除某一行数据
139 |
140 | dataTable.removeRow(index);
141 |
142 | #### 删除所有行数据
143 |
144 | dataTable.removeAllRows();
145 |
146 |
147 | ### 获取模型中的数据
148 |
149 | #### 获取所有数据
150 |
151 | var json = dataTable.getSimpleData();
152 |
153 | 获取到的json数据格式,与载入时的数据格式一致。一般是在提交数据时,调用此方法,获取数据后提交给后端。
154 | 在调用`getSimpleData`方法时可传递参数`type`来决定获取的数据类型。
155 |
156 | var json = dataTable.getSimpleData({type:'select'});
157 |
158 | type可设置为:
159 |
160 | + select: 处理选中状态的行数据
161 | + focus: 焦点状态的行数据
162 | + change: 发生改变的行数据
163 |
164 | 默认不传递参数则获取所有的数据。
165 |
166 | #### 获取某一行的数据
167 |
168 | var row = dataTable.getRow(index);
169 | var json = row.getSimpleData();
170 |
171 | #### 获取某一行中某个字段的值
172 |
173 | var row = dataTable.getRow(index);
174 | var value = row.getValue('name');
175 |
--------------------------------------------------------------------------------
/docs/datatable.md:
--------------------------------------------------------------------------------
1 | # 数据模型
2 |
3 | 数据模型(dataTabe)作为MVVM架构中Model层的增强。主要功能有:
4 |
5 | + 以行、列的形式,通过json对象对数据做存储,并对外暴露一批增删改查的API,方便开发者对页面数据的处理,而且所有开发者之间做到统一,减少出错概率。
6 | + 数据增加状态标识新增或修改,方便开发者使用。
7 | + 具有分页缓存能力,可在前端处理分页(非必要情况下,不推荐前端分页)。
8 | + 提供事件监听u.on(element, eventName,child,listener),把数据变化触发出去,供开发者监听使用。
9 |
10 |
11 | ## 模型定义
12 |
13 | 模型定义方法:
14 |
15 | var myDataTable = new u.DataTable({
16 | meta:{
17 | field1:{type:date},
18 | field2:{}
19 | }
20 | })
21 |
22 |
23 | meta中是模型的字段信息,字段名对应的对象为字段的属性定义。其中常用字段的属性定义的有type、以及一些校验属性(详情参考[这里](validateapi.html))、default(设置字段的默认值)以及不同控件的属性设置等。没有字段属性时,可以为空对象。
24 |
25 | * 下面是常用的type类型。
26 | + string:字符串
27 | + integer:整型
28 | + float:浮点型
29 | + date: 日期类型(YY-MM-DD)
30 | + datetime:日期时间类型(YY-MM-DD hh:mm:ss)
31 |
32 | * default可以对应函数(返回具体的默认值),也可以是具体的对象。
33 |
34 | + 对应函数的写法。
35 |
36 | ```
37 | meta: {
38 | f1: {
39 | default: function() {
40 | return '02-01';//'02-01'为返回的默认值
41 | }
42 | }
43 | }
44 | ```
45 |
46 | + 对应对象的写法。default:function(){return 'aa'}。
47 |
48 | ```
49 | meta: {
50 | f1: {
51 | default: {
52 | value: '02-01'//value对应具体的默认值
53 | }
54 | }
55 | }
56 | ```
57 | * 控件的属性设置
58 |
59 | (1)integerAdapter (整数)
60 |
61 | |属性名称| 属性值类型|具体描述|
62 | | ------- | :-------: | ------: |
63 | |max|integer|输入的值小于等于max|
64 | |min|integer|输入的值大于等于min|
65 | |maxNotEq|integer|输入的值小于max|
66 | |minNotEq|integer|输入的值大于min|
67 |
68 | (2) stringAdapter (字符串)
69 |
70 | |属性名称| 属性值类型|具体描述|
71 | |-------|:-------:|------:|
72 | |minLength|integer|输入的字符串长度大于等于minLength|
73 | |maxLength|integer|输入的字符串长度小于等于maxLength|
74 |
75 | (3) floatAdapter(浮点数)
76 |
77 | |属性名称| 属性值类型|具体描述|默认值|
78 | |-------|:-------:|:------:|------|
79 | |precision|integer|浮点数的精度|2|
80 | |max|integer|输入的值小于等于max| |
81 | |min|integer|输入的值大于等于min| |
82 | |maxNotEq|integer|输入的值小于max| |
83 | |minNotEq|integer|输入的值大于min| |
84 |
85 | (4)currencyAdapter(货币)
86 |
87 | |属性名称| 属性值类型|具体描述|默认值|
88 | |-------|:-------:|:------:|------|
89 | |precision|integer|浮点数的精度|2|
90 | |max|integer|输入的值小于等于max||
91 | |min|integer|输入的值大于等于min||
92 | |maxNotEq|integer|输入的值小于max||
93 | |minNotEq|integer|输入的值大于min||
94 | |curSymbol|String|货币符号|¥|
95 |
96 | (5) percentAdapter(百分比)
97 |
98 | |属性名称| 属性值类型|具体描述|默认值|
99 | |-------|:-------:|:------:|------|
100 | |precision|integer|浮点数的精度|2|
101 |
102 |
103 |
104 |
105 | 字段的属性值在控件模型中被使用到,主要用于控制表单输入、字段显示格式等业务特性。
106 |
107 |
108 |
109 | ## 数据载入到模型中
110 |
111 | 模型定义好之后,可以通过`dataTable.setSimpleData`方法把从后台查询到的json数据载入模型之中:
112 |
113 | dataTable.setSimpleData([
114 | {"id": "001","name": "tom"},
115 | {"id": "002","name": "john"}
116 | ])
117 |
118 | 数据载入到模型中之后,数据被存储在一组`Row`对象之中,json数组中的每一个对象,对应dataTable中的`Row`对象中。
119 |
120 |
121 | ## 数据的新增与修改
122 |
123 | ### 新增数据行并赋值
124 |
125 | var row = dataTable.createEmptyRow();
126 | row.setValue('id','003')
127 |
128 | 新增的数据在dataTable中表现为新增一个`Row`对象。调用`setValue`对其中字段赋值。
129 |
130 | ### 修改已存在的行中数据
131 |
132 | var row = dataTable.getRow(index);
133 | row.setValue('name','jerry');
134 |
135 |
136 | ## 数据的删除
137 |
138 | ### 删除某一行数据
139 |
140 | dataTable.removeRow(index);
141 |
142 | ### 删除所有行数据
143 |
144 | dataTable.removeAllRows();
145 |
146 |
147 | ## 获取模型中的数据
148 |
149 | ### 获取所有数据
150 |
151 | var json = dataTable.getSimpleData();
152 |
153 | 获取到的json数据格式,与载入时的数据格式一致。一般是在提交数据时,调用此方法,获取数据后提交给后端。
154 | 在调用`getSimpleData`方法时可传递参数`type`来决定获取的数据类型。
155 |
156 | var json = dataTable.getSimpleData({type:'select'});
157 |
158 | type可设置为:
159 |
160 | + select: 处理选中状态的行数据
161 | + focus: 焦点状态的行数据
162 | + change: 发生改变的行数据
163 |
164 | 默认不传递参数则获取所有的数据。
165 |
166 | ### 获取某一行的数据
167 |
168 | var row = dataTable.getRow(index);
169 | var json = row.getSimpleData();
170 |
171 | ### 获取某一行中某个字段的值
172 |
173 | var row = dataTable.getRow(index);
174 | var value = row.getValue('name');
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
--------------------------------------------------------------------------------