UI Tools¶
UI Tools程序版说明、本地安装和配置¶
UI Tools程序版是依赖网页版,支持用户在浏览器中使用网页版的功能并实现浏览器和本地文件系统双向同步的程序。程序版定期发布压缩包,包含程序、程序配置文件和项目依赖文件夹。
压缩文件说明¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | node.zip │ └───www # 项目依赖的样式和脚本文件 │ │ │ └───css │ └───fonts │ └───html │ └───js │ └───noide.bin.zip # 程序文件和配置文件 │ noide.config.json # 配置文件,配置说明参见noide.config.md │ noide.config.md # 配置说明文件 │ noide.exe # 程序文件 │ RunHide.vbs # 支持程序后台运行的脚本文件,可忽略 │ shutdown.bat # 关闭脚本 │ startup.bat # 启动脚本 |
本地安装和配置¶
双击noide.exe启动程序,程序前台运行,程序启动时右侧文件树列表是当前程序所在路径的文件树。程序支持多实例,启动时绑定不同的端口。双击startup.bat启动程序,程序后台运行。双击shutup.bat关闭所有运行的程序实例。如果需要同时启动多个实例,同时支持单独关闭,请双击noide.exe启动程序,并通过右上角关闭想要关闭的程序。
功能介绍¶
页面分为左右两部分,左侧为文件树列表,右侧是工作区域。工作区域可以分别以编辑器模式和UI Tools模式显示。
快捷菜单支持新增、删除和重命名文件和文件夹操作,并根据文件类型显示不同的菜单。
后缀名为html的页面右键点击时,支持以Builder模式打开,打开后右侧工作区展示与网页版相同的内容。用户可以在右侧工作区域进行与网页版相同的操作,所有的修改变化会同步到本地的文件。左键单击文件时,文件以编辑器模式打开,可以查看文件变化,同时可以进行编辑操作,所有的编辑操作会同步到本地的文件中。
Add blank custom
和Add blank general
两个快捷菜单分别创建空白的定制和通用模板文件,用户可以通过Builder模式打开对应的文件,进行编辑操作。
压缩包www/js/shared.js
文件中包含压缩包打包时最新的公共脚本文件。程序公共脚本因为需要支持新功能和修复问题,可能需要不定期更新。为了确保shared.js
保证最新,右击后缀名为js的文件,显示Update shared JavaScript菜单。单击后,程序会使用最新的公共脚本覆盖原有文件。
警告
更新脚本文件时,请确保更新的是公共脚本文件。请不要将定制的逻辑代码写入公共的脚本文件,更新操作会覆盖原有的文件。
Builder模式¶
工作区域以Builder模式打开后,界面和操作方式与网页版类似,将在Components组件介绍中详细介绍具体使用方式。
编辑器模式¶
编辑器模式快捷键支持¶
PC (Windows/Linux) | Mac | action |
---|---|---|
Ctrl+S | Cmd+S | Save the current file |
Ctrl+Shift+S, | Cmd+Option+S, | Save all files |
Ctrl+B | Cmd+B | Beautify (js, css, html files only) |
Ctrl | Cmd | Show the settings menu |
Ctrl+Alt+Up | Ctrl+Option+Up | add multi+cursor above |
Ctrl+Alt+Down | Ctrl+Option+Down | add multi+cursor below |
Ctrl+Alt+Right | Ctrl+Option+Right | add next occurrence to multi+selection |
Ctrl+Alt+Left | Ctrl+Option+Left | add previous occurrence to multi+selection |
Ctrl+L | center selection | |
Ctrl+Shift+U | Ctrl+Shift+U | change to lower case |
Ctrl+U | Ctrl+U | change to upper case |
Alt+Shift+Down | Cmd+Option+Down | copy lines down |
Alt+Shift+Up | Cmd+Option+Up | copy lines up |
Del | delete | |
Ctrl+Shift+D | Cmd+Shift | duplicate selection |
Ctrl+F | Cmd | find |
Ctrl+K | Cmd+G | find next |
Ctrl+Shift+K | Cmd+Shift+G | find previous |
Alt+0 | Cmd+Option+0 | fold all |
Alt+L, Ctrl+F1 | Cmd+Option+L, Cmd+F1 | fold selection |
Down | Down, Ctrl+N | go line down |
Up | Up, Ctrl+P | go line up |
Ctrl+End | Cmd+End, Cmd+Down | go to end |
Left | Left, Ctrl+B | go to left |
Ctrl+L | Cmd+L | go to line |
Alt+Right, End | Cmd+Right, End, Ctrl+E | go to line end |
Alt+Left, Home | Cmd+Left, Home, Ctrl+A | go to line start |
Ctrl+P | go to matching bracket | |
Page Down | Option+Page Down, Ctrl+V | go to page down |
Page Up | Option+Page Up | go to page up |
Right | Right, Ctrl+F | go to right |
Ctrl+Home | Cmd+Home, Cmd+Up | go to start |
Ctrl+Left | Option+Left | go to word left |
Ctrl+Right | Option+Right | go to word right |
Tab | Tab | indent |
Ctrl+Alt+E | macros recording | |
Ctrl+Shift+E | Cmd+Shift+E | macros replay |
Alt+Down | Option+Down | move lines down |
Alt+Up | Option+Up | move lines up |
Ctrl+Alt+Shift+Up | Ctrl+Option+Shift+Up | move multicursor from current line to the line above |
Ctrl+Alt+Shift+Down | Ctrl+Option+Shift+Down | move multicursor from current line to the line below |
Shift+Tab | Shift+Tab | outdent |
Ins | Ins | overwrite |
Ctrl+Shift+Z, Ctrl+Y | Cmd+Shift+Z, Cmd+Y | redo |
Ctrl+Alt+Shift+Right | Ctrl+Option+Shift+Right | remove current occurrence from multi+selection and move to next |
Ctrl+Alt+Shift+Left | Ctrl+Option+Shift+Left | remove current occurrence from multi+selection and move to previous |
Ctrl+D | Cmd+D | remove line |
Alt+Del | Ctrl+K | remove to line end |
Alt+Backspace | Cmd+Backspace | remove to linestart |
Ctrl+Backspace | Option+Backspace, Ctrl+Option+Backspace | remove word left |
Ctrl+Del | Option+Del | remove word right |
Ctrl+R | Cmd+Option+F | replace |
Ctrl+Shift+R | Cmd+Shift+Option+F | replace all |
Ctrl+Down | Cmd+Down | scroll line down |
Ctrl+Up | scroll line up | |
Option+Page Down | scroll page down | |
Option+Page Up | scroll page up | |
Ctrl+A | Cmd+A | select all |
Ctrl+Shift+L | Ctrl+Shift+L | select all from multi+selection |
Shift+Down | Shift+Down | select down |
Shift+Left | Shift+Left | select left |
Shift+End | Shift+End | select line end |
Shift+Home | Shift+Home | select line start |
Shift+Page Down | Shift+Page Down | select page down |
Shift+Page Up | Shift+Page Up | select page up |
Shift+Right | Shift+Right | select right |
Ctrl+Shift+End | Cmd+Shift+Down | select to end |
Alt+Shift+Right | Cmd+Shift+Right | select to line end |
Alt+Shift+Left | Cmd+Shift+Left | select to line start |
Ctrl+Shift+P | select to matching bracket | |
Ctrl+Shift+Home | Cmd+Shift+Up | select to start |
Shift+Up | Shift+Up | select up |
Ctrl+Shift+Left | Option+Shift+Left | select word left |
Ctrl+Shift+Right | Option+Shift+Right | select word right |
Ctrl+O | split line | |
Ctrl+/ | Cmd+/ | toggle comment |
Ctrl+T | Ctrl+T | transpose letters |
Ctrl+Z | Cmd+Z | undo |
Alt+Shift+L, Ctrl+Shift+F1 | Cmd+Option+Shift+L, Cmd+Shift+F1 | unfold |
Alt+Shift+0 | Cmd+Option+Shift+0 | unfold all |
Ctrl+Enter | Cmd+Enter | enter full screen |
UI Tools网页版说明和使用¶
UI Tools网页版说明¶
UI Tools网页版是程序版依赖的服务,界面和功能和程序版使用Builder模式打开工作空间类似。
由于浏览器不支持直接的文件访问,UI Tools需要用户显式地进行文件的导入和导出操作。UI Tools网页版在组件列表上方会显式页面文件树。页面文件树中,显示的页面包含通用和定制的模板文件、用户基于模板文件创建的新页面和导入的页面。用户创建的页面通过localStorage
保存到浏览器本地,支持在文件树列表删除已创建的页面。
UI Tools网页版快捷菜单¶
菜单 | 功能说明 | 快捷键 |
---|---|---|
Undo | 撤销上一步操作 | Ctrl+Z |
Redo | 重做上一步操作 | Ctrl+Y |
Fullscreen | 全屏显示,进入全屏模式后,按F1推出全屏 | |
Preview | 隐藏右侧功能区,全屏预览效果,此时左侧工作空间处于不可操作状态 | |
Check generated file | 模态框预览导出文件内容 | |
Upload | 上传页面到UI Tools中打开 | |
Download | 下载当前工作空间的页面到本地 | |
Mobile View | 预览当前页面在手机视图中的效果 | |
Tablet View | 预览当前页面在平板视图中的效果 | |
Desktop View | 预览当前页面在桌面视图中的效果 |
UI Tools网页版模板¶
定制模板¶
定制模板是具有固定页面布局的预置模板。左侧是表单,右侧是表格或图表。
通用模板¶
通用模板以布局块为基本单位,允许用户新增、删除布局块、调整布局块的大小、拖拽改变布局块在页面的位置并拖拽组件到布局块中定位。
UI Tools网页版设置¶
定制设置¶
定制设置是对应不同组件的设置。
通用设置¶
通用设置是所有元素通用属性的设置。按其功能分成了General、Border、Padding、Display、Typography、Size、Margin等设置。方便用户对元素id
、class
和style
属性进行可视化的修改。
UI Tools网页版导出文件说明¶
UI Tools网页版支持导出不同类型的文件
导出文件 | 文件说明 |
---|---|
bundled.html | 包含公共脚本文件的html |
index.html | 移除公共脚本文件的html,只包含必要的表格初始化文件,如需后期引入,可加入shared.js |
shared.js | 公共脚本文件 |
index.zip | 包含index.html和shared.js的压缩文件 |
Components¶
组件是布局的最小单位。用户可以拖拽组件到对应的区域、调整它们的属性并预览效果。
定制组件¶
定制组件是为pds模板设计的一套具有固定宽度和高度的输入组件。
定制组件 | 组件说明 |
---|---|
Custom Text Input Field | 定制文本输入 |
Custom Datetime Input Field | 定制日期时间输入 |
Custom File Input field | 定制文件输入 |
Custom Auto Select Field | 定制自动填充下拉框选项输入 |
Custom Manual Select Field | 定制手动输入下拉框选项输入 |
Custom Multi-value Select Field | 定制多选下拉 |
Custom Textarea Field | 定制文本域输入 |
Custom Radio Field | 定制radio输入 |
Custom Checkbox Field | 定制checkbox输入 |
Custom Popup Text Input | 定制弹出框文本输入 |
Custom Popup Manual Select | 定制弹出框手动输入下拉框选项输入 |
Custom Text Input Field¶
Custom Datetime Input Field¶
Custom File Input Field¶
定制文件输入。
提示
文件输入在用户选择上传文件后,自动执行文件上传,成功后弹窗提示。查看如何覆盖通用代码一节了解如何实现自定义文件上传逻辑。
Custom Auto Select Field¶
定制自动填充下拉框选项输入,可以通过指定url地址,设置value和text映射,在页面加载后自动填充下拉框选项。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | function generateOptions(el, response) { var value = $(el).attr('data-value-mapping') || 'value'; var text = $(el).attr('data-text-mapping') || 'text'; response.forEach(function (option) { $('<option></option>') .val(option[value]) .text(option[text]) .appendTo($(el)); }); } [].slice.call($('body').find('[data-auto-select-id]')) .filter(function (el) { return $(el).attr('data-url'); }).forEach(function (el) { $.ajax({ url: config.fundodooApiDomainUrl + $(el).attr('data-url'), dataType: 'json', method: 'POST', async: true, success: function (response) { generateOptions(el, response.data); } }); }); |
Custom Manual Select Field¶
定制手动输入下拉框选项输入,允许用户在设置菜单手动添加或删除下拉框选项。
Custom Multi-value Select Field¶
Custom Textarea Field¶
Custom Radio Field¶
定制radio输入。
提示
通过选中radio元素后弹出的快捷菜单,点击复制按钮实现快速复制radio元素。
Custom Checkbox Field¶
定制checkbox输入。
提示
通过选中checkbox元素后弹出的快捷菜单,点击复制按钮实现快速复制checkbox元素。
Custom Popup Text Input¶
定制弹出框文本输入适用于定制模板弹出框。
Custom Popup Manual Select¶
定制弹出框手动输入下拉框选项输入适用于定制模板弹出框。
提示
设置输入组件title属性,当鼠标在输入组件悬浮时,在组件右侧显示title的内容。
通用组件¶
定制组件 | 组件说明 |
---|---|
Container | container |
Form | 表单 |
Grid Row | 栅格 |
Tabs | 标签页 |
Common ag-Grid | 集成表格组件ag-Grid |
Button | 按钮 |
Rounded Button | 圆形按钮 |
Button Group | 按钮组 |
Text Input Field | 文本输入 |
Datetime Input Field | 日期时间输入 |
File Input Field | 文件输入 |
Auto Select Field | 自动填充下拉框选项输入 |
Manual Select Field | 手动输入下拉框选项输入 |
Textarea Field | 文本域输入 |
Radio Field | radio输入 |
Checkbox Field | checkbox输入 |
Static Table | 静态表格 |
Chart | 图表占位符 |
Heading | Heading元素 |
Alert | 告警框 |
Horizontal Rule | 水平分割线 |
Image | 图片组件 |
Progress Bar | 进度条 |
Container¶
Container是基于Bootstrap中的Container
实现的组件。该组件主要是为了HTML
的语义化,帮助用户将其他组件统一放在Container
组件中,提供了几种不同的主题背景颜色。
Form¶
Form是基于Bootstrap中的Form
实现的表单组件。表单组件中可以放入不同的输入控件并设置它们的样式。参考定制组件中类型相同的输入控件的属性设置。
示例Form表单HTML代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | <form> <div class="form-group"> <label for="exampleFormControlInput1">Email address</label> <input type="email" class="form-control" id="exampleFormControlInput1" placeholder="name@example.com"> </div> <div class="form-group"> <label for="exampleFormControlSelect1">Example select</label> <select class="form-control" id="exampleFormControlSelect1"> <option>1</option> <option>2</option> <option>3</option> <option>4</option> <option>5</option> </select> </div> <div class="form-group"> <label for="exampleFormControlSelect2">Example multiple select</label> <select multiple class="form-control" id="exampleFormControlSelect2"> <option>1</option> <option>2</option> <option>3</option> <option>4</option> <option>5</option> </select> </div> <div class="form-group"> <label for="exampleFormControlTextarea1">Example textarea</label> <textarea class="form-control" id="exampleFormControlTextarea1" rows="3"></textarea> </div> </form> |
警告
UI Tools没有限制输入组件一定要拖入form
元素内。实际上,用户可以选择将输入组件放入页面内的任何可拖拽区域,并能正确呈现样式。但为了HTML的语义化,将输入组件放入form
元素内是更合理的做法。
Text Input Field¶
Datetime Input Field¶
File Input Field¶
Auto Select Field¶
Manual Select Field¶
Textarea Field¶
Radio Field¶
Checkbox Field¶
设置输入组件的Required属性有什么作用?
设置输入组件的Required属性,当表单提交时,如果表单中存在设置了Required的输入组件且该组件值为空,将弹窗提示用户输入不能为空。
Grid Row¶
栅格是基于Bootstrap中的Grid
实现的可视化、可配置的布局组件。支持栅格的新增和删除操作,支持改变栅格中列在不同分辨率下的大小。支持拖拽其他组件到栅格中的对应位置。
Tabs¶
Tabs组件基于jQuery UI Tabs实现。允许用户新增、删除标签页和修改标签页的标题,支持拖拽其他组件到标签页中,支持标签页的嵌套。
Common ag-Grid¶
表格组件基于ag-Grid实现。用户可以通过元素快捷菜单,新增、删除、修改表头,属性设置菜单修改表格颜色主题。支持ag-Grid常用属性设置。
常用属性设置说明1
属性 | 说明 | 示例 |
---|---|---|
Header | 表头名称、字段映射、宽度、是否隐藏、禁用改变大小、删除表头 | |
Checkbox Selection | 第一列数据是否显示checkbox | |
Header Checkbox Selection | 第一列表头是否显示checkbox,可以快速进行全选 | |
Enable Resize | 是否启用使用鼠标改变表头宽度 | |
Auto Size Columns | 表格是否根据数据列自适应改变宽度 | |
Populate Headers | 是否根据返回数据自动填充表头,启用后现有的Header设置失效 | |
Pagination | 是否分页显示数据 | |
Page Size | 分页后每页显示的数据数目 | |
Theme | 集成全部官方颜色主题 | ![]() |
Related Table | 关联的其他表格,用于表格联动逻辑 | |
Transpose Key | 表格行列翻转的基准 | |
Table Key | 表格唯一标识,只读 | |
Enable Row Click | 是否响应行点击事件,默认行为是弹框,可覆盖默认行为。查看如何覆盖默认行为 | |
Row Click Url | 行点击弹框中有新的表格时,数据请求的地址 | |
Enable Cell Click | 是否响应单元格点击事件,默认行为是弹框,可覆盖默认行为。查看如何覆盖默认行为 | |
Cell Click Url | 单元格点击弹框中有新的表格时,数据请求的地址 | |
Data Key | 查询返回多个表格数据时,数据和表格的映射关系 |
Button¶
Button是基于Bootstrap中的Button
实现的按钮组件。支持常用样式属性的设置。支持点击弹出框操作,用户可以拖拽其他组件到弹出框。
Rounded Button¶
Rounded Button是基于Bootstrap中的Button
实现的圆形按钮组件。图标基于Font Awesome。用户如果需要设置其他图标,可以点击Rounded Button
中的i
元素,在属性设置中的Text -> Icon
下拉框中选择常用的图标。如果需要设置其他图标,可以在General -> Class
中修改为Font Awesome支持的图标。
Button Group¶
Button Group是基于Bootstrap中的Button Group
实现的按钮组件。支持常用样式属性的设置。
Static Table¶
静态表格是基于Bootstrap中的Table
实现的静态表格。设置菜单里可以设置表格的多种不同样式。用户可以利用元素复制和删除功能,新增或删除表头和数据列。表格的表头和数据是静态数据。
Chart¶
Chart组件是图表占位组件。由于图表图例和数据一般是后台数据经代码渲染生成,UI Tools暂时不提供统一可视化设置功能。
Heading¶
Heading组件支持heading
元素。
Alert¶
静态表格是基于Bootstrap中的Alert
实现的告警组件。支持改变告警样式。
Horizontal Rule¶
Horizontal Rule组件支持hr
元素。
Image¶
信息
图片组件是img元素的占位组件。用户可以利用设置中的上传功能预览图片效果,图片以base64
编码在页面中呈现。图片不会保存到导出页面或上传到服务器。
Progress Bar¶
Progress Bar是基于Bootstrap中的Progress
实现的进度条组件。支持改变进度条样式。
Label Field¶
JavaScript代码生成¶
UI Tools生成页面时,支持生成通用的和适用于单独页面的脚本。
通用代码¶
UI Tools为简化用户的开发流程,会为一些通用的业务逻辑自动生成代码。如果用户使用网页版导出功能时,选择bundled.html导出,通用代码会包含在导出文件中。由于通用代码内容相同,为便于统一更新,不建议以bundled.html导出。网页版中,用户可以选择shared.js导出最新的通用代码。程序版www/js/shared.js
已包含shared.js
文件,用户可以右键更新到最新的通用代码。
通用代码功能
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | function onFileInputChange() { var formData = new FormData(); formData.append(this.name, this.files[0]); $.ajax({ url: config.fundodooApiDomainUrl + $(this).attr('data-url'), dataType: 'json', contentType: false, method : 'POST', async: true, processData: false, traditional: true, data: formData, fundodooAjax: true, //true:开启计时功能,false(或去掉此属性):不开启计时功能 success: function (response, status, xhr) { layer.alert('文件上传成功', { icon: 1, shadeClose: true, title: '提示' }); } }); } $('form.form-box').find('input[type=file][data-url]').on('change', onFileInputChange); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | function generateOptions(el, response) { var value = $(el).attr('data-value-mapping') || 'value'; var text = $(el).attr('data-text-mapping') || 'text'; response.forEach(function (option) { $('<option></option>') .val(option[value]) .text(option[text]) .appendTo($(el)); }); } [].slice.call($('body').find('[data-auto-select-id]')) .filter(function (el) { return $(el).attr('data-url'); }).forEach(function (el) { var data = { owner: 'Common', queryId: 'findIdType', version: '10001', paramSource: null }; $.ajax({ url: config.fundodooApiDomainUrl + $(el).attr('data-url'), dataType: 'json', method: 'POST', data: data, async: true, success: function (response) { generateOptions(el, response.data); } }); }); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | function submitForm(form, url, successCb, errorCb) { var valid = true; form.find('input[required], select[required], textarea[required]') .each(function () { if (!this.value) { valid = false; layer.alert(this.name + '输入不能为空', { icon: 2, shadeClose: true, title: '提示' }); return false; } }); if (valid) { var formData = new FormData(); var data = form.serializeJSON(); data.tok = sessionStorage.getItem('FUNDODOO_TOKEN'); $.each($('input[type=file]'), function (i, element) { formData.append(element.name, element.files[0]); }); Object.keys(data).forEach(function (value) { formData.append(value, data[value]); }); var containsFileInput = form.find('input[type=file]').length > 0; $.ajax({ url: config.fundodooApiDomainUrl + url, dataType: 'json', contentType: containsFileInput ? false : 'application/x-www-form-urlencoded', method : 'POST', async: true, processData: !containsFileInput, traditional: true, data: containsFileInput ? formData : data, fundodooAjax: true, //true:开启计时功能,false(或去掉此属性):不开启计时功能 success: successCb, error: errorCb }); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 | // 新增弹出框只适用于定制模板 function popupAdd() { layer.open({ type: 1, title: '新增', area: ['600px', '350px'], skin: 'layui-layer-rim', //加上边框 content: $('div.popup-window#add'), end: function end() { $('div.popup-window#add form').trigger('reset'); } }); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | // 编辑弹出框只适用于定制模板 function popupEdit() { var openPopup = function openPopup() { layer.open({ type: 1, title: '修改', area: ['600px', '350px'], skin: 'layui-layer-rim', //加上边框 content: $('div.popup-window#edit'), end: function end() { $('div.popup-window#edit form').trigger('reset'); } }); }; var setFormValues = function setFormValues(selectedRow) { $('div.popup-window#edit form').find('input:not([type=submit]), select, textarea').each(function () { var field = $(this).attr('data-row-field') || $(this).attr('name'); $(this).val(selectedRow[field]); }); }; if (grids.length) { var selectedRows = grids[0].gridOptions.api.getSelectedRows(); if (selectedRows.length == 0) { layer.msg('请选择需要修改的数据', { icon: 5 }); } else if (selectedRows.length > 1) { layer.msg('只允许同时修改一条数据', { icon: 5 }); } else { setFormValues(selectedRows[0]); openPopup(); } } else { layer.msg('请选择需要修改的数据', { icon: 5 }); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | // 删除弹出框只适用于定制模板 function popupDelete() { var openPopup = function openPopup() { layer.confirm('您确定需要删除吗?', { btn: ['确定', '取消'] }, function () { $.ajax({ url: config.fundodooApiDomainUrl + $('button#delete').attr('data-url'), dataType: 'json', contentType: 'application/x-www-form-urlencoded', method: 'POST', async: true, traditional: true, data: grids[0].gridOptions.api.getSelectedRows(), fundodooAjax: true, //true:开启计时功能,false(或去掉此属性):不开启计时功能 success: function success() { layer.closeAll(); $('form button#dataSearch').click(); }, error: function error() {} }); }, function () {}); }; if (grids.length) { var selectedRows = grids[0].gridOptions.api.getSelectedRows(); if (selectedRows.length == 0) { layer.msg('请选择需要删除的数据', { icon: 5 }); } else { openPopup(); } } else { layer.msg('请选择需要删除的数据', { icon: 5 }); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | // 详情弹出框目前适用于固定的业务逻辑,实际开发中可能需要根据业务需求做改动 function popupDetail(url, data, popup) { // Compatible with previous only one detail popup window var content = popup && popup.length ? popup : $('div.popup-window#detail'); var openPopup = function openPopup() { layer.open({ type: 1, title: '信息', area: ['660px', '330px'], skin: 'layui-layer-rim', //加上边框 content: content, end: function end() {} }); }; if (content.length) { if (url && data) { $.ajax({ url: config.fundodooApiDomainUrl + url, dataType: 'json', contentType: 'application/x-www-form-urlencoded', method: 'POST', async: true, traditional: true, data: data, fundodooAjax: true, //true:开启计时功能,false(或去掉此属性):不开启计时功能 success: function success(response) { content.find('[data-component-id="html/labelfield@common"]').each(function (_, element) { var key = $(element).children('span:last-child').attr('data-key-mapping'); $(element).children('span:last-child').text(key ? response.data[key] || '' : ''); }); content.find('img').each(function (_, image) { var $image = $(image); var data = response.data[$image.attr('data-key-mapping')]; if (data) { $image.attr('src', 'data:image/' + $image.attr('data-image-format') + ';base64,' + data); } else { $image.attr('src', $image.attr('data-image-placeholder')); } }); openPopup(); }, error: function error() {} }); } else { openPopup(); } } } |
1 2 3 4 5 | function exportData() { if (grids.length) { grids[0].gridOptions.api.exportDataAsCsv(); } } |
1 2 3 4 5 6 7 8 9 10 11 | // 弹出框中表单提交后,回调函数中关闭弹出框,重新查询数据渲染表格 function popupFormSubmitCallback() { submitForm($(this).parents('form'), $('button#' + $(this).parents('form').attr('data-related-button')).attr('data-url'), function (response) { layer.closeAll(); $('form button#dataSearch').click(); }, function () { }); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | // 函数中根据用户对表格设置的不同属性,实现不同的数据填充 // 支持数据填充表头、支持行列翻转、支持表头宽度根据内容自适应 function setAgGridData(grid, data) { var gridOptions = grid.gridOptions; var transposeKey = grid.transposeKey; var populateHeaders = grid.populateHeaders; var autoSizeColumns = grid.autoSizeColumns; if (populateHeaders) { if (data.length) { var colDefs = Object.keys(data[0]).map(function (key) { return { headerName: key, field: key }; }); gridOptions.api.setColumnDefs(colDefs); gridOptions.api.setRowData(data); } } else { if (transposeKey) { var transposedData = gridOptions.columnDefs .filter(function (colDef) { return colDef.field !== transposeKey; }) .map(function (colDef) { var key = colDef.field; var transposed = {}; transposed[transposeKey] = colDef.headerName; data.forEach(function (item) { transposed[item[transposeKey]] = item[key]; }); return transposed; }); var newColDefs = [ { headerName: '', field: transposeKey, cellStyle: { 'font-size': 'large' }, pinned: 'left' } ].concat(data.map(function (item) { return { headerName: item[transposeKey], field: $.isNumeric(item[transposeKey]) ? item[transposeKey].toString() : item[transposeKey] }; })); gridOptions.api.setColumnDefs(newColDefs); gridOptions.api.setRowData(transposedData); } else { gridOptions.api.setRowData(data); } } if (autoSizeColumns) { var allColumnIds = []; gridOptions.columnApi.getAllColumns().forEach(function(column) { allColumnIds.push(column.colId); }); gridOptions.columnApi.autoSizeColumns(allColumnIds); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | function query() { var queryForm = $(this).parents('form'); var queryUrl = $(this).attr('data-url'); submitForm(queryForm, queryUrl, function (response) { if (Array.isArray(response.data)) { if (grids.length) { setAgGridData(grids[0], response.data); } } else { $.each(response.data, function (key, value) { $.each(grids, function (i, grid) { if (grid.key == key) { setAgGridData(grid, value); return false; } }); }); } }, function () { }); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | // 注册弹出框表单提交回调函数,只适用于定制模板 $('form.popup-form input[type=submit]').on('click', popupFormSubmitCallback); // 注册定制模板左侧表单提交回调函数,只适用于定制模板 $('form button#dataSearch').on('click', query); // 注册文件输入框选择本地文件回调函数,文件自动上传到通过`data-url`指定的路径 $('form.form-box').find('input[type=file][data-url]').on('change', onFileInputChange); // 注册通用模板表单中按钮元素点击回调函数 $('div.gridster div form button[data-enable-button-click-popup!=true]').on('click', query); // 注册启用弹出框的按钮元素点击回调函数 function buttonClickedPopupCallback() { if ($(this).attr('data-enable-button-click-popup') === 'true') { popupDetail(null, null, $('#' + 'button_clicked_popup' + $(this).attr('data-button-key'))); } } $('body').on('click', 'button', buttonClickedPopupCallback); |
1 2 3 4 5 6 7 | // 输入组件悬浮提示框初始化 $(function () { $('input, select, textarea').tooltip({"position":{"my":"left top","at":"right+5 top-5","collision":"none"}}); }); // Tabs组件初始化 $('[data-component-id="html/tabs@common"]').tabs(); |
如何覆盖通用代码¶
通用代码一般只适用于一些通用、简单的逻辑。如果要实现自定义逻辑,用户可以覆盖原有的实现。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | // 移除原有绑定的事件回调 $('form.popup-form input[type=submit]').off('click', popupFormSubmitCallback); // 注册自定义事件回调 $('form.popup-form input[type=submit]').on('click', function () {}); // 移除原有绑定的事件回调 $('form.form-box').find('input[type=file][data-url]').off('change', onFileInputChange); // 注册自定义事件回调 $('form.form-box').find('input[type=file][data-url]').on('change', function () {}); // 移除原有绑定的事件回调 $('form button#dataSearch').off('click', query); // 注册自定义事件回调 $('form button#dataSearch').on('click', function () {}); // 移除原有绑定的事件回调 $('div.gridster div form button[data-enable-button-click-popup!=true]').off('click', query); // 注册自定义事件回调 $('div.gridster div form button[data-enable-button-click-popup!=true]').on('click', function () {}); // 移除原有绑定的事件回调 $('body').off('click', 'button', buttonClickedPopupCallback); // 注册自定义事件回调 $('body').on('click', 'button', function () {}); |
提示
通用代码中大部分代码需要通过用户操作触发,这部分代码可以实现覆盖原有实现。但下拉框数据初始化会在页面加载完成后执行,这部分代码如果用户需要重写,请不要引入shared.js
文件。
定制代码¶
ag-Grid Code¶
UI Tools功能中,只有使用ag-Grid组件初始化的表格是必须包含在生成的页面里的。
备注
如果使用了ag-Grid组件,请不要修改导出的表格初始化代码。UI Tools在实现页面导入功能时,需要依赖这部分代码实现表格的初始化工作。同时,UI Tools为表格增加新功能时,需要覆盖这部分代码。与此同时,UI Tools没有限制用户覆盖原有代码逻辑的能力。下面会通过例子说明如何重写表格代码,实现自定义逻辑。
1 2 3 4 5 6 7 | <div data-component-id="html/commontable@common" data-enable-row-click="true" style="width: 100%; height: 100%; z-index: 15; left: 0px; top: 0px;" class="resize-drag draggable ag-theme-blue ui-sortable-handle" data-table-id="_fl" id="table_fl"> </div> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | var gridOptions_fl = { columnDefs: [{ "headerName": "Athelete", "field": "athelete", "width": "", "checkboxSelection": true, "headerCheckboxSelection": false, "suppressMovable": true }], enableSorting: true, enableFilter: false, rowSelection: 'multiple', suppressRowClickSelection: true, suppressFieldDotNotation: true, pagination: undefined, paginationAutoPageSize: undefined, paginationPageSize: undefined, onCellClicked: function (event) { if (eGridDiv_fl.attr('data-enable-cell-click') == 'true') { if (typeof popupCommon !== 'undefined' && typeof popupCommon == 'function') { var popup = $('#' + 'cell_clicked_popup' + '_fl'); popupCommon(event, popup, eGridDiv_fl); } } }, onRowClicked: function (event) { if (eGridDiv_fl.attr('data-enable-row-click') == 'true') { popupDetail(eGridDiv_fl.attr('data-row-click-url'), event.data, $('#' + 'row_clicked_popup' + '_fl')); } }, onRowSelected: function (event) { if (event.node.isSelected() && eGridDiv_fl.attr('data-related-table')) { if (window['gridOptions' + eGridDiv_fl.attr('data-related-table')]) { window['gridOptions' + eGridDiv_fl.attr('data-related-table')].api.setRowData([event.data]); } } } }; new agGrid.Grid(eGridDiv_fl.get(0), gridOptions_fl); gridOptions_fl.api.setRowData([]); |
上面的HTML片段和JavaScript代码用于初始化页面中的一个ag-Grid表格组件。默认的行点击和单元格点击事件是弹出对话框(需要在表格属性设置中开启弹出框)。
1 2 3 4 5 6 7 | gridOptions_fl.onCellClicked = function () { // 自定义逻辑 }; gridOptions_fl.onRowSelected = function () { // 自定义逻辑 } |
用户可以重新设置onCellClicked和onRowSelected属性,实现用户自定义逻辑。
参考ag-Grid文档了解更多使用方式。
样式主题制作器¶
样式主题制作器是一款通过可视化界面制作Bootstrap主题的网页应用,允许用户在线制作、导出和上传样式主题。该应用与UI Tools集成,允许用户在UI Tools中使用已上传到服务器的主题。