release v2.8.18-beta (#1391)

release v2.8.18-beta
pull/1400/head v2.8.18-beta
贤心 2023-10-07 17:23:59 +08:00 committed by GitHub
commit 5ba2dfa5d7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
42 changed files with 812 additions and 427 deletions

View File

@ -1,6 +1,5 @@
name: 😇 问题反馈 name: 😇 问题反馈
description: 使用 Layui 过程中遇到的 Bug、异常或其他困惑。 description: 使用 Layui 过程中遇到的 Bug、异常或其他困惑。
title: ""
body: body:
- type: markdown - type: markdown
attributes: attributes:

View File

@ -1,5 +1,5 @@
blank_issues_enabled: false blank_issues_enabled: false
contact_links: contact_links:
- name: 📄 阅读文档 - name: 📄 官方文档
url: https://layui.dev/ url: https://layui.dev/
about: 建议你在创建 Issue 之前,仔细查阅 Layui 开发文档,以便对其有更深入的了解,和更好地分析问题。 about: 建议你在创建 Issue 之前,仔细查阅 Layui 开发文档,以便对其有更深入的了解,和更好地分析问题。

66
.github/ISSUE_TEMPLATE/bug.yml vendored Normal file
View File

@ -0,0 +1,66 @@
name: 😇 问题反馈
description: 使用 Layui 过程中遇到的 Bug、异常或其他困惑。
body:
- type: markdown
attributes:
value: |
**系统提示**:此处只接受 Layui 相关技术问题,其他如 layuiAdmin 或 LayIM 等主题相关问题请勿在此反馈。
- type: checkboxes
attributes:
label: 议题条件
options:
- label: 我确认已查看官方使用文档:**https://layui.dev** ,但没有找到相关解决方案。
required: true
- label: 我确认已在 **Issues** 中搜索过类似的问题,但没有找到相关解决方案。
required: true
- type: input
attributes:
label: 版本号
placeholder: 请提供您所使用的 Layui 版本号
validations:
required: true
- type: input
attributes:
label: 浏览器
placeholder: Chrome 116.0.5845.111(正式版本) 64 位)
validations:
required: true
- type: dropdown
id: type
attributes:
label: 问题类型
options:
- 疑是 BUG
- 报错提示
- 功能困惑
validations:
required: true
- type: textarea
attributes:
label: 问题描述
placeholder: 请提供详细的问题描述和操作步骤等信息,以便我们也能够更轻松地将问题复现。
validations:
required: true
- type: textarea
attributes:
label: 业务代码
description: 直接粘贴问题对应的 `HTML,CSS,JavaScript` 等代码到下面的文本框,无需书写 `Markdown`
placeholder: 请提供与该问题对应的业务代码片段,以便我们更好地排查问题。
render: auto
validations:
required: true
- type: textarea
attributes:
label: 截图补充
placeholder: 如上述仍然无法准确地表述问题,可提供必要的截图(可直接粘贴上传)
- type: input
attributes:
label: 演示地址
description: 若能提供 Stackblitz, CodePen 或自主搭建的页面演示地址,将更有助于解决问题
placeholder: URL
- type: checkboxes
attributes:
label: 友好承诺
options:
- label: 我承诺将本着相互尊重、理解和友善的态度进行交流,共同维护 Layui 良好的社区氛围。
required: true

5
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@ -0,0 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: 📄 官方文档
url: https://layui.dev/
about: 建议您在创建 Issue 之前,仔细查阅 Layui 开发文档,以便对其有更深入的了解,和更好地分析问题。

2
dist/css/layui.css vendored

File diff suppressed because one or more lines are too long

2
dist/layui.js vendored

File diff suppressed because one or more lines are too long

View File

@ -22,6 +22,16 @@
</td> </td>
<td>string/DOM</td> <td>string/DOM</td>
<td>-</td>
</tr>
<tr>
<td>code <sup>2.8.18+</sup></td>
<td>
设置原始 code 值,默认取目标元素中的内容
</td>
<td>string</td>
<td>-</td> <td>-</td>
</tr> </tr>
<tr> <tr>
@ -302,12 +312,14 @@ Code 文字是否自动换行
<td>highlighter <sup>2.8.17+</sup></td> <td>highlighter <sup>2.8.17+</sup></td>
<td> <td>
指定语法高亮器,可选值: 设置语法高亮器,可选值:
- `hljs` : 指定 `highlight.js` - `hljs` : 指定 `highlight.js`
- `prism` : 指定 `prism.js` - `prism` : 指定 `prism.js`
- `shiki` : 指定 `shiki.js` - `shiki` : 指定 `shiki.js`
注:对应的语法高亮器 JS 库和相关主题 CSS 需自主引入,该属性仅用于内部适配。
</td> </td>
<td>string</td> <td>string</td>
<td>-</td> <td>-</td>

View File

@ -3,6 +3,8 @@
<hr> <hr>
<input type="password" name="password" lay-verify="password" placeholder="密码" class="layui-input"> <input type="password" name="password" lay-verify="password" placeholder="密码" class="layui-input">
<hr> <hr>
<input type="text" name="motto" lay-verify="motto" placeholder="座右铭" class="layui-input">
<hr>
<button class="layui-btn" lay-submit lay-filter="demo-verify">提交</button> <button class="layui-btn" lay-submit lay-filter="demo-verify">提交</button>
</form> </form>
@ -11,25 +13,33 @@
layui.use(function(){ layui.use(function(){
var form = layui.form; var form = layui.form;
// 自定义验证规则,如下以验证用户名和密码为例 // 自定义验证规则
form.verify({ form.verify({
// 参数 value 为表单的值;参数 item 为表单元素 // 验证用户名,且为必填项
username: function(value, item){ username: function(value, elem){
if(!new RegExp("^[a-zA-Z0-9_\u4e00-\u9fa5\\s·]+$").test(value)){ if (!new RegExp("^[a-zA-Z0-9_\u4e00-\u9fa5\\s·]+$").test(value)) {
return '用户名不能有特殊字符'; return '用户名不能有特殊字符';
} }
if(/(^_)|(__)|(_+$)/.test(value)) return '用户名首尾不能出现 _ 下划线'; if (/(^_)|(__)|(_+$)/.test(value)) {
if(/^\d+$/.test(value)) return '用户名不能全为数字'; return '用户名首尾不能出现下划线';
}
// 若不想自动弹出默认提示框,可返回 true这时可通过其他提示方式替代v2.5.7 新增) if (/^\d+$/.test(value)) {
if(value === 'xxx'){ return '用户名不能全为数字';
alert('用户名不能为敏感词');
return true;
} }
}, },
password: function(value) { // 验证密码,且为必填项
if (!/^[\S]{6,12}$/.test(value)) { password: function(value, elem) {
return '密码必须为 6 到 12 位的非空字符'; if (!/^[\S]{6,16}$/.test(value)) {
return '密码必须为 6 到 16 位的非空字符';
}
},
// 验证座右铭,且为非必填项
motto: function(value, elem) {
if (!value) return; // 非必填
// 自定义规则
if (!new RegExp("^[a-zA-Z0-9_\u4e00-\u9fa5\\s·]+$").test(value)) {
return '座右铭不能有特殊字符';
} }
} }
}); });

View File

@ -207,18 +207,18 @@ layui.use('form', function(){
<h2 id="lay-verify" lay-toc="{hot: true, level: 2}">验证</h2> <h2 id="lay-verify" lay-toc="{hot: true, level: 2}">验证</h2>
Layui 对表单做了相对巧妙的支持,只需在表单元素上设置 `lay-verify=""` 属性值即可指定验证规则,如: Layui 对表单验证做了巧妙的支持,只需在表单元素上设置 `lay-verify=""` 属性值即可指定验证规则,如:
``` ```
<div class="layui-form"> <div class="layui-form">
<input type="text" lay-verify="required"> <input type="text" lay-verify="required" placeholder="必填项">
<input type="text" lay-verify="email"> <input type="text" lay-verify="email" placeholder="非必填项,但若有值则验证邮箱格式">
<input type="text" lay-verify="required|phone|number"> <input type="text" lay-verify="required|number" placeholder="必填项,并验证数字格式">
<button class="layui-btn" lay-submit>提交</button> <button class="layui-btn" lay-submit>提交</button>
</div> </div>
``` ```
其中,`lay-verify` 属性的内置规则值可参考上文的:[#属性介绍](#attr)。 当表单提交时,会自动触发验证。 注:上述代码指定的均为内置的验证规则,具体可参考:[#属性介绍](#attr)
<h3 id="verify" lay-toc="{level: 3, title: '定义验证规则'}" class="ws-bold">自定义验证规则</h3> <h3 id="verify" lay-toc="{level: 3, title: '定义验证规则'}" class="ws-bold">自定义验证规则</h3>
@ -226,7 +226,50 @@ Layui 对表单做了相对巧妙的支持,只需在表单元素上设置 `lay
- 参数 `obj` 是一个对象,用于定义验证规则的集合。 - 参数 `obj` 是一个对象,用于定义验证规则的集合。
当内置的验证规则无法满足业务需求时,我们可以通过该方法自定义验证规则。如: 除了内置的验证规则外form 还允许自定义验证规则,规则以函数命名,返回的参数如下:
```
// 自定义验证规则
form.verify({
rule: function(value, elem) {
console.log(value); // 当前进入验证的表单项的值
console.log(elem); // 当前进入验证的表单项的 DOM 元素
}
});
```
在自定义规则中,可根据规则函数返回的 value 自行判断是否必填,如:
```
form.verify({
// 必填项
rule1: function(value, elem) {
// 自定义规则
if (value.length < 6) {
return '不能小于 6 个字符';
}
},
// 非必填项,只有当值填写时才验证自定义规则
rule2: function(value, elem) {
if (!value) return; // 若值未填写,不进行后续规则验证
// 自定义规则
if (/^[A-Z]/.test(value)) {
return '必须用大写字符开头';
}
},
// 自定义提示方式
rule3: function(value, elem) {
// 自定义规则和自定义提示方式
if(value === 'xxx'){
alert('用户名不能为敏感词'); // 此处以系统自带的 alert 提示方式为例
return true; // 返回 true 即可阻止 form 默认的提示风格
}
}
});
```
以下是一个自定义验证规则的示例:
<pre class="layui-code" lay-options="{preview: true, codeStyle: 'height: 508px;', done: function(obj){ <pre class="layui-code" lay-options="{preview: true, codeStyle: 'height: 508px;', done: function(obj){
obj.render() obj.render()
@ -239,7 +282,6 @@ Layui 对表单做了相对巧妙的支持,只需在表单元素上设置 `lay
更多「自定义验证规则」示例参考: 更多「自定义验证规则」示例参考:
> - <a href="https://gitee.com/layui/layui/issues/I5HC2L#note_11673264_link" target="_blank">将 form 提示语显示在表单项旁边,并在提交时批量触发验证</a> > - <a href="https://gitee.com/layui/layui/issues/I5HC2L#note_11673264_link" target="_blank">将 form 提示语显示在表单项旁边,并在提交时批量触发验证</a>
> - <a href="https://gitee.com/layui/layui/issues/I42C7I#note_12020414_link" target="_blank">重置 form 内置验证规则,让其:当非空值才进行验证;加了 required 时才验证非空</a>
<h3 id="validate" lay-toc="{level: 3}" class="ws-bold">主动触发验证 <sup>2.7+</sup></h3> <h3 id="validate" lay-toc="{level: 3}" class="ws-bold">主动触发验证 <sup>2.7+</sup></h3>

View File

@ -1183,36 +1183,33 @@ toc: true
layui.use(function(){ layui.use(function(){
var $ = layui.jquery; var $ = layui.jquery;
var layer = layui.layer; var layer = layui.layer;
var lay = layui.lay;
var util = layui.util;
// click
$('.ws-docs-icon > div').on('click', function(e){
var elem = $(this);
var unicodeElem = elem.children('.docs-icon-code')
var classnameElem = elem.children('.docs-icon-fontclass')
var text = classnameElem.text();
var html = text;
$('.ws-docs-icon > div').on('click', function(){ if ($(e.target).is(unicodeElem)) {
var iconclass = $(this).find('.docs-icon-fontclass').text(); text = unicodeElem.text();
var copied = copy(iconclass); html = unicodeElem.html();
if(copied){
layer.msg('已复制 '+ iconclass, {
icon: 1,
offset: '5%',
anim: 'slideDown',
isOutAnim: false
});
} }
lay.clipboard.writeText({
text: text,
done: function() {
layer.msg('已复制 '+ html, {
icon: 1,
offset: '5%',
anim: 'slideDown',
isOutAnim: false
});
}
});
}); });
function copy(text){
var textarea = document.createElement('textarea');
textarea.value = text;
textarea.style.position = 'absolute';
textarea.style.opacity = '0';
document.body.appendChild(textarea);
textarea.select();
var copied = false;
try{
copied = document.execCommand('copy');
}catch(err){
console.log('error', err);
}
textarea.remove();
return copied;
}
}); });
</script> </script>
</textarea> </textarea>

View File

@ -1,6 +1,6 @@
<h2 lay-toc="{id: 'examples', level: 2, hot: true}" class="layui-hide">在线测试</h2> <h2 lay-toc="{id: 'examples', level: 2, hot: true}" class="layui-hide">在线测试</h2>
<pre class="layui-code" lay-options="{preview: true, text: {preview: '在线测试'}, layout: ['preview']}"> <pre class="layui-code" lay-options="{preview: true, text: {preview: '在线测试'}, copy: false, layout: ['preview']}">
<textarea> <textarea>
{{- d.include("/layer/detail/run.md") }} {{- d.include("/layer/detail/run.md") }}
</textarea> </textarea>

View File

@ -32,8 +32,8 @@ toc: true
| [layer.photos(options)](#photos) | 弹出 `page` 类型图片层。 | | [layer.photos(options)](#photos) | 弹出 `page` 类型图片层。 |
| [layer.tab(options)](#tab) | 弹出 `page` 类型标签页层。 | | [layer.tab(options)](#tab) | 弹出 `page` 类型标签页层。 |
| 关闭 : | - | | 关闭 : | - |
| [layer.close(index)](#close) | 关闭对应的层,核心方法。 | | [layer.close(index, callback)](#close) | 关闭对应的层,核心方法。 |
| [layer.closeAll(type)](#closeAll) | 关闭所有对应类型的层。 | | [layer.closeAll(type, callback)](#closeAll) | 关闭所有对应类型的层。 |
| [layer.closeLast(type)](#closeLast) <sup>2.8+</sup> | 关闭最近打开的对应类型的层。 | | [layer.closeLast(type)](#closeLast) <sup>2.8+</sup> | 关闭最近打开的对应类型的层。 |
| 其他 : | - | | 其他 : | - |
| [layer.config(options)](#config) | 全局配置默认属性。 | | [layer.config(options)](#config) | 全局配置默认属性。 |
@ -339,9 +339,10 @@ layer.tab({
<h2 id="close" lay-toc="{level: 2}">关闭弹层</h2> <h2 id="close" lay-toc="{level: 2}">关闭弹层</h2>
`layer.close(index);` `layer.close(index, callback);`
- 参数 `index` : 打开弹层时返回的唯一索引 - 参数 `index` : 打开弹层时返回的唯一索引
- 参数 `callback` : 关闭弹层后的回调函数
该方法用于关闭对应的弹层。 该方法用于关闭对应的弹层。
@ -366,9 +367,10 @@ parent.layer.close(index); // 再执行关闭
<h2 id="closeAll" lay-pid="api" class="ws-anchor ws-bold">关闭所有层</h2> <h2 id="closeAll" lay-pid="api" class="ws-anchor ws-bold">关闭所有层</h2>
`layer.closeAll(type);` `layer.closeAll(type, callback);`
- 参数 `type` : 弹层的类型。可选值:`dialog,page,iframe,loading,tips` - 参数 `type` : 弹层的类型。可选值:`dialog,page,iframe,loading,tips`
- 参数 `callback` : 关闭弹层后的回调函数
该方法用于关闭所有同类型的弹层。 该方法用于关闭所有同类型的弹层。

View File

@ -1,4 +1,4 @@
<pre class="layui-code" lay-options="{preview: true, layout: ['preview'], tools: ['full']}"> <pre class="layui-code" lay-options="{preview: true, layout: ['preview'], copy: false, tools: ['full'], addTools: null}">
<textarea> <textarea>
{{! {{!
<style> <style>
@ -132,4 +132,4 @@ layui.use(function(){
</script> </script>
!}} !}}
</textarea> </textarea>
</pre> </pre>

View File

@ -319,7 +319,7 @@ treeTable.expandAll('test', false); // 关闭全部节点
| opts | 描述 | 类型 | 默认值 | | opts | 描述 | 类型 | 默认值 |
| --- | --- | -- | --- | | --- | --- | -- | --- |
| index | 要设置选中状态的行下标或行数据 | number/object | - | | index | 要设置选中状态的行下标或行数据 | number/object | - |
| checked | 选中状态。`true` 选中;`false` 取消选中;`null` 切换。 其中,`radio` 框,则不支持 `null`(切换)。 | boolean | - | | checked | 选中状态。`true` 选中;`false` 取消选中;`null` 切换。 其中,`radio` 框,则不支持 `null`(切换)。 | boolean | - |
| callbackFlag | 是否触发事件,若为 `true`,则 `checked: false` 无效。其对应的事件跟 `table``radio,checkbox` 事件用法一样 | boolean | `false` | | callbackFlag | 是否触发事件,若为 `true`,则 `checked: false` 无效。其对应的事件跟 `table``radio,checkbox` 事件用法一样 | boolean | `false` |
```js ```js
@ -364,4 +364,4 @@ treeTable.checkAllNodes('test', true); // 全选
## 贴士 ## 贴士
> `treeTable` 基于 `table` 组件扩展而来,因此,熟练运用 `treeTable` 的前提是熟悉 `table` 组件。 亦可通过 `table` 提供的基础 `API` 操作 `treeTable` 组件,但 `treeTable` 无法操作 `table` > `treeTable` 基于 `table` 组件扩展而来,因此,熟练运用 `treeTable` 的前提是熟悉 `table` 组件。 亦可通过 `table` 提供的基础 `API` 操作 `treeTable` 组件,但 `treeTable` 无法操作 `table`

View File

@ -15,7 +15,7 @@ layui.use(function(){
// 渲染 // 渲染
upload.render({ upload.render({
elem: '#ID-upload-demo-drag', elem: '#ID-upload-demo-drag',
url: 'https://httpbin.org/post', // 此处用的是第三方的 http 请求演示,实际使用时改成您自己的上传接口即可。 url: '', // 实际使用时改成您自己的上传接口即可。
done: function(res){ done: function(res){
layer.msg('上传成功'); layer.msg('上传成功');
$('#ID-upload-demo-preview').removeClass('layui-hide') $('#ID-upload-demo-preview').removeClass('layui-hide')
@ -24,4 +24,4 @@ layui.use(function(){
} }
}); });
}); });
</script> </script>

View File

@ -31,7 +31,7 @@ layui.use(function(){
var uploadListIns = upload.render({ var uploadListIns = upload.render({
elem: '#ID-upload-demo-files', elem: '#ID-upload-demo-files',
elemList: $('#ID-upload-demo-files-list'), // 列表元素对象 elemList: $('#ID-upload-demo-files-list'), // 列表元素对象
url: 'https://httpbin.org/post', // 此处用的是第三方的 http 请求演示,实际使用时改成您自己的上传接口即可。 url: '', // 实际使用时改成您自己的上传接口即可。
accept: 'file', accept: 'file',
multiple: true, multiple: true,
number: 3, number: 3,
@ -96,4 +96,4 @@ layui.use(function(){
} }
}); });
}); });
</script> </script>

View File

@ -32,7 +32,7 @@ layui.use(function(){
// 单图片上传 // 单图片上传
var uploadInst = upload.render({ var uploadInst = upload.render({
elem: '#ID-upload-demo-btn', elem: '#ID-upload-demo-btn',
url: 'https://httpbin.org/post', // 此处用的是第三方的 http 请求演示,实际使用时改成您自己的上传接口即可。 url: '', // 实际使用时改成您自己的上传接口即可。
before: function(obj){ before: function(obj){
// 预读本地文件示例不支持ie8 // 预读本地文件示例不支持ie8
obj.preview(function(index, file, result){ obj.preview(function(index, file, result){
@ -71,7 +71,7 @@ layui.use(function(){
// 多图片上传 // 多图片上传
upload.render({ upload.render({
elem: '#ID-upload-demo-btn-2', elem: '#ID-upload-demo-btn-2',
url: 'https://httpbin.org/post', // 此处用的是第三方的 http 请求演示,实际使用时改成您自己的上传接口即可。 url: '', // 实际使用时改成您自己的上传接口即可。
multiple: true, multiple: true,
before: function(obj){ before: function(obj){
// 预读本地文件示例不支持ie8 // 预读本地文件示例不支持ie8
@ -84,4 +84,4 @@ layui.use(function(){
// … // …
} }
}); });
}); });

View File

@ -9,7 +9,7 @@ toc: true
<h2 id="examples" lay-toc="{hot: true, anchor: null}" style="margin-bottom: 0;">示例</h2> <h2 id="examples" lay-toc="{hot: true, anchor: null}" style="margin-bottom: 0;">示例</h2>
以下示例的部分上传接口由第三方网站 `https://httpbin.org` 提供,它可以模拟各类 HTTP 请求。若未配置上传接口的,每次上传都会报「请求上传接口出现异常」的提示,这属于正常现象 以下示例均没有设置上传接口,因此每次上传都会报异常提示,这属于正常现象。实际使用时设置成您的真实上传接口即可
<div class="ws-docs-showcase"></div> <div class="ws-docs-showcase"></div>

View File

@ -11,6 +11,43 @@ toc: true
> 导读:📑 [Layui 2.8 《升级指南》](/notes/2.8/upgrade-guide.html) · 📑 [Layui 新版文档站上线初衷](/notes/2.8/news.html) > 导读:📑 [Layui 2.8 《升级指南》](/notes/2.8/upgrade-guide.html) · 📑 [Layui 新版文档站上线初衷](/notes/2.8/news.html)
<h2 id="2.8.18" class="ws-anchor">
2.8.18-beta
<span class="layui-badge-rim">2023-10-07</span>
</h2>
- #### form
- 新增 `input` 数字输入框组件的特定属性 `lay-precision`,用于设置数值精度 # 1375/I81SY4
- 优化 `input` 数字输入框组件的失去焦点对值的有效范围约束 # 1375/I7KU6V
- 优化 `input` 数字输入框组件当值达到临界点时加减按钮的禁用视觉效果 # 1375
- 优化 `input` 数字输入框当表单验证失败时的边框颜色 # 1371
- #### nav
- 新增 垂直导航菜单展开和收缩时的过渡动画 # 1384
- #### layer
- 优化 移动端定位 # 1376
- #### table
- 新增 `complete` 属性,当数据接口请求完成后执行,无论成功还是失败均会触发 # 1379
- #### treeTable
- 修复 treeTable 组件 treeTable.setRowChecked 未逐层展开上级节点的问题 # 1385/I84RUT
- #### upload
- 修复 `unified: true` 时的报错问题
- 优化 渲染入口逻辑,以解决因重复渲染导致的若干问题
- 优化 实例的 `reload` 方法,可更好地进行完整重载
- #### laydate
- 优化 开启 `rangeLinked` 属性后,点击目标元素可重新渲染的问题
- #### carousel
- 优化 轮播切换时的动画效果 # 1378/I82STP
- #### rate / slider
- 优化 代码细节 # 1374
- #### code
- 新增 `code` 属性,用于设置原始 code 值,优先级高于目标元素中的内容
- 优化 若干小问题
### 下载: [layui-v2.8.18-beta.zip](https://gitee.com/layui/layui/attach_files/1545385/download)
---
<h2 id="2.8.17" class="ws-anchor"> <h2 id="2.8.17" class="ws-anchor">
2.8.17 2.8.17
<span class="layui-badge-rim">2023-09-11</span> <span class="layui-badge-rim">2023-09-11</span>

View File

@ -136,16 +136,20 @@ code line
</div> </div>
</pre> </pre>
<pre class="layui-code" lay-options="{about: 'About info'}"> <pre class="layui-code" lay-options="{about: 'AboutInfo'}">
About About
</pre> </pre>
<script src="../src/layui.js"></script> <!-- 第三方语法高亮库 -->
<script src="https://cdn.staticfile.org/highlight.js/11.8.0/highlight.min.js"></script> <script src="https://cdn.staticfile.org/highlight.js/11.8.0/highlight.min.js"></script>
<script src="https://cdn.staticfile.org/prism/1.29.0/prism.min.js"></script> <script src="https://cdn.staticfile.org/prism/1.29.0/prism.min.js"></script>
<!-- layui -->
<script src="../src/layui.js"></script>
<script> <script>
layui.use(['code', 'dropdown'], function(){ layui.use(['code', 'dropdown'], function(){
var dropdown = layui.dropdown; var dropdown = layui.dropdown;
var layer = layui.layer;
var $ = layui.$; var $ = layui.$;
// return; // return;
@ -173,6 +177,7 @@ layui.use(['code', 'dropdown'], function(){
}; };
}); });
// 创建实例
var codeInst = layui.code({ var codeInst = layui.code({
elem: '#test', elem: '#test',
preview: true, preview: true,
@ -183,12 +188,14 @@ layui.use(['code', 'dropdown'], function(){
// wordWrap: false, // 是否自动换行 // wordWrap: false, // 是否自动换行
lang: 'html', lang: 'html',
highlighter: "hljs", highlighter: "hljs",
/*codeRender: function (code, opts) { // code: '<div class="layui-btn">初始按钮</div>',
/*codeRender: function (code, opts) { // 初始高亮
layui.link(themeData[1].link, 'layui-code-theme'); layui.link(themeData[1].link, 'layui-code-theme');
return hljs.highlight(code, {language: opts.lang}).value; return hljs.highlight(code, {language: opts.lang}).value;
},*/ },*/
tools: [ tools: [
'full', 'full',
'window',
{ {
title: ['文字换行'], title: ['文字换行'],
type: 'form', type: 'form',
@ -244,19 +251,36 @@ layui.use(['code', 'dropdown'], function(){
} }
}); });
} }
},
{
title: ['编辑'],
type: 'edit',
event: function(obj) {
layer.prompt({
formType: 2,
value: obj.rawCode,
title: '编辑代码',
area: ['800px', '500px'],
maxlength: 9999999999
}, function(value, index) {
layer.close(index);
// 重载 code
codeInst.reloadCode({
code: value
});
});
}
} }
] ]
}); });
// 仅重载 code // 语法高亮重载
layui.debounce(function() { codeInst.reloadCode({
codeInst.reloadCode({ codeRender: function(code, opts) {
codeRender: function(code, opts) { layui.link(themeData[1].link, 'layui-code-theme');
layui.link(themeData[1].link, 'layui-code-theme'); return hljs.highlight(code, {language: opts.lang}).value;
return hljs.highlight(code, {language: opts.lang}).value; }
} });
});
}, 300)();
// 通用实例,根据元素属性定制化参数 // 通用实例,根据元素属性定制化参数

View File

@ -6,12 +6,10 @@
<title>导航 - 常用元素 - layui</title> <title>导航 - 常用元素 - layui</title>
<link rel="stylesheet" href="../src/css/layui.css"> <link rel="stylesheet" href="../src/css/layui.css">
<style> <style>
body{padding: 16px;}
.demo-nav-tree>.layui-inline{vertical-align: top;} .demo-nav-tree>.layui-inline{vertical-align: top;}
</style> </style>
</head> </head>
<body> <body class="layui-padding-3">
<ul class="layui-nav"> <ul class="layui-nav">
<li class="layui-nav-item"><a href="">最新活动</a></li> <li class="layui-nav-item"><a href="">最新活动</a></li>
@ -130,7 +128,7 @@
<div class="demo-nav-tree"> <div class="demo-nav-tree">
<div class="layui-inline"> <div class="layui-inline">
<ul class="layui-nav layui-nav-tree" lay-filter="test"> <ul class="layui-nav layui-nav-tree" lay-accordion lay-filter="test">
<li class="layui-nav-item"> <li class="layui-nav-item">
<a class="" href="javascript:;">产品</a> <a class="" href="javascript:;">产品</a>
<dl class="layui-nav-child"> <dl class="layui-nav-child">

View File

@ -17,7 +17,7 @@ body{padding: 50px 100px;}
<body> <body>
<div class="layui-inline"> <div class="layui-inline">
<input type="text" class="layui-input" id="test-first"> <input type="text" class="layui-input" id="test-first" placeholder="带遮罩">
</div> </div>
<br> <br>
@ -157,7 +157,7 @@ layui.use('laydate', function(laydate){
laydate.render({ laydate.render({
elem: '#test-first', elem: '#test-first',
min: 0, min: 0,
shade: [0.1, '#ddd'], shade: [0.1, '#000'],
//max: '2016-12-30', //max: '2016-12-30',
done: function(){ done: function(){
console.log('done',arguments); console.log('done',arguments);

View File

@ -24,6 +24,7 @@
<button class="layui-btn" lay-on="test7">Prompt</button> <button class="layui-btn" lay-on="test7">Prompt</button>
<button class="layui-btn" lay-on="test8">Tab</button> <button class="layui-btn" lay-on="test8">Tab</button>
<button class="layui-btn" lay-on="test9">Photo</button> <button class="layui-btn" lay-on="test9">Photo</button>
<button class="layui-btn" lay-on="test10">Drawer</button>
<button class="layui-btn" lay-on="testTime">自动关闭</button> <button class="layui-btn" lay-on="testTime">自动关闭</button>
<a href="https://layui.dev/docs/2.8/layer/" target="_blank" class="layui-btn">更多例子</a> <a href="https://layui.dev/docs/2.8/layer/" target="_blank" class="layui-btn">更多例子</a>
</div> </div>
@ -215,6 +216,19 @@ layui.use(['layer', 'util'], function(layer, util){
} }
}); });
} }
,test10: function(){
layer.open({
title:'drawer',
type: 1,
offset: 'b',
anim: 'slideUp', // 从下往上
area: ['100%', '160px'],
shade: 0.1,
shadeClose: true,
content: $('#test11111'),
maxmin: true,
});
}
}); });
// 相册层 // 相册层

View File

@ -5,11 +5,8 @@
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>树形表格 - layui</title> <title>树形表格 - layui</title>
<link rel="stylesheet" href="../src/css/layui.css"> <link rel="stylesheet" href="../src/css/layui.css">
<style>
body {padding: 32px;}
</style>
</head> </head>
<body> <body class="layui-padding-5">
<table class="layui-hide" id="test"></table> <table class="layui-hide" id="test"></table>
@ -19,15 +16,26 @@
</div> </div>
</script> </script>
<script type="text/html" id="TPL-treeTable-demo-tools">
<div class="layui-btn-container">
<a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="detail">查看</a>
<a class="layui-btn layui-btn-warm layui-btn-xs" lay-event="addChild">新增</a>
<a class="layui-btn layui-btn-xs" lay-event="more">更多 <i class="layui-icon layui-icon-down"></i></a>
</div>
</script>
<script src="../src/layui.js"></script> <script src="../src/layui.js"></script>
<script> <script>
layui.use(['treeTable'], function(){ layui.use(['treeTable', 'dropdown', 'layer'], function(){
var treeTable = layui.treeTable; var treeTable = layui.treeTable;
var dropdown = layui.dropdown;
var layer = layui.layer;
// 渲染 // 渲染
treeTable.render({ var inst = treeTable.render({
elem: '#test', elem: '#test',
url: './json/treeTable/demo-1.json', url: './json/treeTable/demo-1.json',
// data: createData(!0),
maxHeight: 'full-32', maxHeight: 'full-32',
toolbar: '#TPL-treeTable-demo', toolbar: '#TPL-treeTable-demo',
tree: { tree: {
@ -48,7 +56,8 @@ layui.use(['treeTable'], function(){
{field: 'score', title: '评分', width: 80, sort: true}, {field: 'score', title: '评分', width: 80, sort: true},
{field: 'city', title: '城市', width: 150}, {field: 'city', title: '城市', width: 150},
{field: 'description', title: '描述', minWidth: 200}, {field: 'description', title: '描述', minWidth: 200},
{field: 'createTime', title: '创建时间', width: 170, fixed: 'right'} {field: 'createTime', title: '创建时间', width: 170},
{ fixed: "right", title: "操作", width: 190, align: "center", toolbar: "#TPL-treeTable-demo-tools"}
]], ]],
page: true page: true
}); });
@ -57,14 +66,82 @@ layui.use(['treeTable'], function(){
treeTable.on('row(test)', function (obj) { treeTable.on('row(test)', function (obj) {
console.log(obj); console.log(obj);
}); });
// 表头工具栏工具事件
treeTable.on('toolbar('+ inst.config.id +')', function (obj) {
var config = obj.config;
var tableId = config.id;
var status = treeTable.checkStatus(tableId);
// 获取选中行
if (obj.event === "getChecked") {
if(!status.data.length) return layer.msg('无选中数据');
console.log(status);
layer.alert("当前数据选中已经输出到控制台,<br>您可按 F12 从控制台中查看结果。");
}
});
// 单元格工具事件
treeTable.on('tool('+ inst.config.id +')', function (obj) {
var layEvent = obj.event; // 获得 lay-event 对应的值
var trElem = obj.tr;
var trData = obj.data;
var tableId = obj.config.id;
if (layEvent === "detail") {
layer.msg("查看操作:" + trData.name);
} else if (layEvent === "addChild") {
var data = { id: Date.now(), name: "新节点" };
var newNode2 = treeTable.addNodes(tableId, {
parentIndex: trData["LAY_DATA_INDEX"],
index: -1,
data: data
});
} else if (layEvent === "more") {
// 下拉菜单
dropdown.render({
elem: this, // 触发事件的 DOM 对象
show: true, // 外部事件触发即显示
align: "right", // 右对齐弹出
data: [
{
title: "修改积分",
id: "edit"
},
{
title: "删除",
id: "del"
}
],
click: function (menudata) {
if (menudata.id === "del") {
console.log(trData);
layer.confirm("真的删除行么", function (index) {
obj.del(); // 等效如下
// treeTable.removeNode(tableId, trElem.attr('data-index'))
layer.close(index);
});
} else if (menudata.id === "edit") {
layer.prompt({
value: trData.experience,
title: "输入新的积分"
}, function (value, index) {
obj.update({ experience: value }); // 等效如下
// treeTable.updateNode(tableId, trElem.attr('data-index'), {experience: value});
layer.close(index);
});
}
}
});
}
});
}); });
</script> </script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Mock.js/1.0.0/mock-min.js"></script> <script src="https://cdn.staticfile.org/Mock.js/1.0.0/mock-min.js"></script>
<script> <script>
// 生成模拟数据 // 生成模拟数据
const createData = () => { const createData = (flat) => {
// 生成随机 ID 函数 // 生成随机 ID 函数
const createId = (() => { const createId = (() => {
let nextId = 1 let nextId = 1
@ -78,6 +155,7 @@ const createData = () => {
createNode.bind(null, id, level + 1) createNode.bind(null, id, level + 1)
] ]
}).array : [] }).array : []
const isParent = 'isParent';
return { return {
id, id,
name: `User-${id}`, name: `User-${id}`,
@ -89,17 +167,22 @@ const createData = () => {
city: Mock.Random.city(), city: Mock.Random.city(),
description: '-', description: '-',
createTime: Mock.mock('@datetime'), createTime: Mock.mock('@datetime'),
parentId, [flat || 'parentId']: parentId,
children, [flat || 'children']: children,
isParent: !!children.length [flat || isParent]: !!children.length
} }
} }
// 生成树
// 根节点
const rootNodes = Mock.mock({ const rootNodes = Mock.mock({
'array|10-20': [ 'array|10-20': [
createNode createNode
] ]
}).array }).array;
if (flat) return rootNodes
// 生成树
const getTreeData = function (nodes) { const getTreeData = function (nodes) {
let result = [] let result = []
nodes.forEach(node => { nodes.forEach(node => {

View File

@ -8,12 +8,11 @@
<link rel="stylesheet" href="../src/css/layui.css"> <link rel="stylesheet" href="../src/css/layui.css">
<style> <style>
body{padding: 50px 100px;}
.layui-upload-img{width: 92px; height: 92px; margin: 0 10px 10px 0;} .layui-upload-img{width: 92px; height: 92px; margin: 0 10px 10px 0;}
hr{margin: 30px 0;} hr{margin: 32px 0;}
</style> </style>
</head> </head>
<body> <body class="layui-padding-5">
<div class="layui-upload"> <div class="layui-upload">
<button type="button" class="layui-btn" id="test1" name="123">上传图片</button> <button type="button" class="layui-btn" id="test1" name="123">上传图片</button>
@ -89,16 +88,20 @@ hr{margin: 30px 0;}
绑定原始文件域:<input type="file" name="file" id="test9"> 绑定原始文件域:<input type="file" name="file" id="test9">
<script src="../src/layui.js" src1="https://cdn.staticfile.org/layui/2.6.8/layui.js"></script> <script src="../src/layui.js" src1="https://cdn.staticfile.org/layui/2.7.6/layui.js"></script>
<script> <script>
layui.use(['upload', 'element'], function(){ layui.use(['upload', 'element', 'form'], function(){
var $ = layui.$; var $ = layui.$;
var upload = layui.upload; var upload = layui.upload;
var element = layui.element; var element = layui.element;
// 模拟接口
var url = '' // 'https://httpbin.org/post';
// 创建实例
var uploadInst = upload.render({ var uploadInst = upload.render({
elem: '#test1', elem: '#test1',
url: 'https://httpbin.org/post', url: url, // 若需模拟上传过程,而不真实上传文件,可使用开源的 HTTP 模拟接口: httpbin
// size: 2000, //限制文件大小,单位 KB // size: 2000, //限制文件大小,单位 KB
// accept: 'file', // accept: 'file',
method: 'get', method: 'get',
@ -149,19 +152,19 @@ layui.use(['upload', 'element'], function(){
element.progress('demo', n + '%'); //可配合 layui 进度条元素使用 element.progress('demo', n + '%'); //可配合 layui 进度条元素使用
} }
}); });
// 重置上述 upload 实例 // 重载上述实例
uploadInst.reload({ uploadInst.reload({
name:'avatar', field: 'avatar',
accept: 'images', // 只允许上传图片 accept: 'images', // 只允许上传图片
acceptMime: 'image/*', // 只筛选图片 acceptMime: 'image/*', // 只筛选图片
//,size: 2 // size: 2,
}); });
// 演示多图片上传 // 演示多图片上传
upload.render({ upload.render({
elem: '#test2', elem: '#test2',
url: 'https://httpbin.org/post', url: url, // 实际使用时改成您自己的上传接口即可
multiple: true, // 多文件 multiple: true, // 多文件
unified: true, // 一起上传 --- 2.8.8+ unified: true, // 一起上传 --- 2.8.8+
accept: 'images', accept: 'images',
@ -188,7 +191,7 @@ layui.use(['upload', 'element'], function(){
var demoListView = $('#demoList'); var demoListView = $('#demoList');
var uploadListIns = upload.render({ var uploadListIns = upload.render({
elem: '#testList', elem: '#testList',
url: 'https://httpbin.org/post', url: url, // 实际使用时改成您自己的上传接口即可
accept: 'file', accept: 'file',
multiple: true, multiple: true,
number: 5, number: 5,
@ -252,17 +255,16 @@ layui.use(['upload', 'element'], function(){
element.progress('progress-'+ index, n + '%'); //进度条 element.progress('progress-'+ index, n + '%'); //进度条
} }
}); });
upload.render({ upload.render({
elem: '.test333', elem: '.test333',
url: 'a', url: url,
accept: 'file', accept: 'file',
before: function(obj){ choose: function(obj){
console.log(this.item); console.log(this.elem);
}, },
done: function(res){ done: function(res){
console.log(res) console.log(res);
} }
}); });
@ -271,6 +273,7 @@ layui.use(['upload', 'element'], function(){
done: function(res, index, upload){ done: function(res, index, upload){
//获取当前触发上传的元素,一般用于 elem 绑定 class 的情况,注意:此乃 layui 2.1.0 新增 //获取当前触发上传的元素,一般用于 elem 绑定 class 的情况,注意:此乃 layui 2.1.0 新增
var item = this.item; var item = this.item;
} }
}) })
@ -286,7 +289,7 @@ layui.use(['upload', 'element'], function(){
upload.render({ upload.render({
elem: '#test4', elem: '#test4',
url: '', url: url, // 实际使用时改成您自己的上传接口即可
accept: 'video', accept: 'video',
done: function(res){ done: function(res){
console.log(res) console.log(res)
@ -306,7 +309,7 @@ layui.use(['upload', 'element'], function(){
//手动上传 //手动上传
upload.render({ upload.render({
elem: '#test6', elem: '#test6',
url: '', url: url, // 实际使用时改成您自己的上传接口即可
auto: false, auto: false,
// multiple: true, // multiple: true,
bindAction: '#test7', bindAction: '#test7',
@ -328,7 +331,7 @@ layui.use(['upload', 'element'], function(){
upload.render({ upload.render({
elem: '#test8', elem: '#test8',
url: 'https://httpbin.org/post', url: url, // 实际使用时改成您自己的上传接口即可
done: function(res){ done: function(res){
console.log(res); console.log(res);
} }
@ -336,7 +339,7 @@ layui.use(['upload', 'element'], function(){
upload.render({ upload.render({
elem: '#test9', elem: '#test9',
url: '', url: url, // 实际使用时改成您自己的上传接口即可
done: function(res){ done: function(res){
console.log(res); console.log(res);
} }

View File

@ -1,6 +1,6 @@
{ {
"name": "layui", "name": "layui",
"version": "2.8.17", "version": "2.8.18-beta",
"description": "Classic modular Front-End UI library", "description": "Classic modular Front-End UI library",
"main": "dist/layui.js", "main": "dist/layui.js",
"license": "MIT", "license": "MIT",

View File

@ -805,6 +805,7 @@ a cite{font-style: normal; *cursor:pointer;}
.layui-input-wrap .layui-input-split{pointer-events: none;} .layui-input-wrap .layui-input-split{pointer-events: none;}
.layui-input-wrap .layui-input:hover + .layui-input-split{border-color: #d2d2d2;} .layui-input-wrap .layui-input:hover + .layui-input-split{border-color: #d2d2d2;}
.layui-input-wrap .layui-input:focus + .layui-input-split{border-color: #16b777;} .layui-input-wrap .layui-input:focus + .layui-input-split{border-color: #16b777;}
.layui-input-wrap .layui-input.layui-form-danger:focus + .layui-input-split{border-color: #ff5722;}
.layui-input-wrap .layui-input-prefix.layui-input-split{border-width: 0; border-right-width: 1px;} .layui-input-wrap .layui-input-prefix.layui-input-split{border-width: 0; border-right-width: 1px;}
/* 输入框动态点缀 */ /* 输入框动态点缀 */
@ -1273,6 +1274,7 @@ body .layui-table-tips .layui-layer-content{background: none; padding: 0; box-sh
.layui-nav .layui-nav-more{position: absolute; top: 0; right: 3px; left: auto !important; margin-top: 0; font-size: 12px; cursor: pointer; transition: all .2s; -webkit-transition: all .2s;} .layui-nav .layui-nav-more{position: absolute; top: 0; right: 3px; left: auto !important; margin-top: 0; font-size: 12px; cursor: pointer; transition: all .2s; -webkit-transition: all .2s;}
.layui-nav .layui-nav-mored, .layui-nav .layui-nav-mored,
.layui-nav-expand > a .layui-nav-more,
.layui-nav-itemed > a .layui-nav-more{transform: rotate(180deg);} .layui-nav-itemed > a .layui-nav-more{transform: rotate(180deg);}
@ -1305,16 +1307,17 @@ body .layui-table-tips .layui-layer-content{background: none; padding: 0; box-sh
.layui-nav-itemed>a{color: #fff !important;} .layui-nav-itemed>a{color: #fff !important;}
.layui-nav-tree .layui-nav-bar{background-color: #16baaa;} .layui-nav-tree .layui-nav-bar{background-color: #16baaa;}
.layui-nav-tree .layui-nav-child{position: relative; z-index: 0; top: 0; border: none; box-shadow: none;} .layui-nav-tree .layui-nav-child{position: relative; z-index: 0; top: 0; border: none; background-color: rgba(0,0,0,.3); box-shadow: none;}
.layui-nav-tree .layui-nav-child dd{margin: 0;} .layui-nav-tree .layui-nav-child dd{margin: 0;}
.layui-nav-tree .layui-nav-child a{color: #fff; color: rgba(255,255,255,.7);} .layui-nav-tree .layui-nav-child a{color: #fff; color: rgba(255,255,255,.7);}
.layui-nav-tree .layui-nav-child a:hover, .layui-nav-tree .layui-nav-child a:hover{background: none; color: #fff;}
.layui-nav-tree .layui-nav-child{background: none; color: #fff;}
.layui-nav-itemed>.layui-nav-child{display: block; background-color: rgba(0,0,0,.3) !important;} /* 垂直导航 - 展开状态 */
.layui-nav-itemed>.layui-nav-child,
.layui-nav-itemed>.layui-nav-child>.layui-this>.layui-nav-child{display: block;} .layui-nav-itemed>.layui-nav-child>.layui-this>.layui-nav-child{display: block;}
/* 侧边 */.layui-nav-side{position: fixed; top: 0; bottom: 0; left: 0; overflow-x: hidden; z-index: 999;} /* 垂直导航 - 侧边 */
.layui-nav-side{position: fixed; top: 0; bottom: 0; left: 0; overflow-x: hidden; z-index: 999;}
/* 导航浅色背景 */ /* 导航浅色背景 */
.layui-nav.layui-bg-gray .layui-nav-item a, .layui-nav.layui-bg-gray .layui-nav-item a,
@ -1322,7 +1325,7 @@ body .layui-table-tips .layui-layer-content{background: none; padding: 0; box-sh
.layui-nav-tree.layui-bg-gray{padding: 6px 0;} .layui-nav-tree.layui-bg-gray{padding: 6px 0;}
.layui-nav-tree.layui-bg-gray .layui-nav-itemed>a{color: #000 !important;} .layui-nav-tree.layui-bg-gray .layui-nav-itemed>a{color: #000 !important;}
.layui-nav.layui-bg-gray .layui-this a{color: #16b777;} .layui-nav.layui-bg-gray .layui-this a{color: #16b777;}
.layui-nav-tree.layui-bg-gray .layui-nav-itemed>.layui-nav-child{padding-left: 11px; background: none!important;} .layui-nav-tree.layui-bg-gray .layui-nav-child{padding-left: 11px; background: none;}
.layui-nav-tree.layui-bg-gray .layui-nav-item>a{padding-top: 0; padding-bottom: 0;} .layui-nav-tree.layui-bg-gray .layui-nav-item>a{padding-top: 0; padding-bottom: 0;}
.layui-nav-tree.layui-bg-gray .layui-nav-item>a .layui-nav-more{padding: 0;} .layui-nav-tree.layui-bg-gray .layui-nav-item>a .layui-nav-more{padding: 0;}
.layui-nav-tree.layui-bg-gray .layui-this, .layui-nav-tree.layui-bg-gray .layui-this,

View File

@ -37,7 +37,9 @@ html #layuicss-skincodecss{display: none; position: absolute; width: 1989px;}
.layui-code-view:hover > .layui-code-fixbar .layui-code-lang-marker{display: none;} .layui-code-view:hover > .layui-code-fixbar .layui-code-lang-marker{display: none;}
/* 深色主题 */ /* 深色主题 */
.layui-code-theme-dark{border-width: 1px; border-color: rgb(126 122 122 / 15%); background-color: #1f1f1f; color: #ccc;} .layui-code-theme-dark,
.layui-code-theme-dark > .layui-code-header{border-color: rgb(126 122 122 / 15%); background-color: #1f1f1f;}
.layui-code-theme-dark{border-width: 1px; color: #ccc;}
.layui-code-theme-dark > .layui-code-ln-side{border-right-color: #2a2a2a; background: none; color: #6e7681;} .layui-code-theme-dark > .layui-code-ln-side{border-right-color: #2a2a2a; background: none; color: #6e7681;}

View File

@ -16,7 +16,7 @@
}; };
var Layui = function(){ var Layui = function(){
this.v = '2.8.17'; // Layui 版本号 this.v = '2.8.18-beta'; // Layui 版本号
}; };
// 识别预先可能定义的指定全局对象 // 识别预先可能定义的指定全局对象

View File

@ -299,12 +299,12 @@ layui.define(['jquery', 'lay'], function(exports){
}, 50); }, 50);
} }
// 移除过 // 移除过
setTimeout(function(){ setTimeout(function(){
elemItem.removeClass(THIS + ' ' + ELEM_PREV + ' ' + ELEM_NEXT + ' ' + ELEM_LEFT + ' ' + ELEM_RIGHT); elemItem.removeClass(THIS + ' ' + ELEM_PREV + ' ' + ELEM_NEXT + ' ' + ELEM_LEFT + ' ' + ELEM_RIGHT);
elemItem.eq(options.index).addClass(THIS); elemItem.eq(options.index).addClass(THIS);
that.haveSlide = false; // 解锁 that.haveSlide = false; // 解锁
}, 300); }, 350);
// 指示器焦点 // 指示器焦点
that.elemInd.find('li').eq(options.index).addClass(THIS) that.elemInd.find('li').eq(options.index).addClass(THIS)

View File

@ -25,7 +25,6 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){
ELEM_LINE: 'layui-code-line', ELEM_LINE: 'layui-code-line',
ELEM_LINE_NUM: 'layui-code-line-number', ELEM_LINE_NUM: 'layui-code-line-number',
ELEM_LN_MODE: 'layui-code-ln-mode', ELEM_LN_MODE: 'layui-code-ln-mode',
CDDE_DATA_CODE: 'LayuiCodeDataCode',
CDDE_DATA_CLASS: 'LayuiCodeDataClass', CDDE_DATA_CLASS: 'LayuiCodeDataClass',
LINE_RAW_WIDTH: 45, // 行号初始宽度,需与 css 保持一致 LINE_RAW_WIDTH: 45, // 行号初始宽度,需与 css 保持一致
}; };
@ -113,11 +112,8 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){
// 未使用 codeRender 时若开启了预览,则强制开启编码 // 未使用 codeRender 时若开启了预览,则强制开启编码
options.encode = (options.encode || options.preview) && !options.codeRender; options.encode = (options.encode || options.preview) && !options.codeRender;
// 最终显示的代码
var finalCode;
// 获得初始 code // 获得初始 code
var rawCode = othis.data(CONST.CDDE_DATA_CODE) || function(){ options.code = options.code || function(){
var arr = []; var arr = [];
var textarea = othis.children('textarea'); var textarea = othis.children('textarea');
@ -131,12 +127,9 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){
arr.push(trim(othis.html())); arr.push(trim(othis.html()));
} }
return arr; return arr.join('');
}(); }();
// 记录初始 code
othis.data(CONST.CDDE_DATA_CODE, rawCode);
// 创建 code 行结构 // 创建 code 行结构
var createCode = function(html) { var createCode = function(html) {
// codeRender // codeRender
@ -171,13 +164,21 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){
}; };
}; };
// 原始 code
var rawCode = options.code;
// 最终 code
var finalCode = function(code) {
return typeof options.codeParse === 'function' ?
options.codeParse(code, options) :
code;
};
// 仅重载 code // 仅重载 code
if (mode === 'reloadCode') { if (mode === 'reloadCode') {
(function(html) { return othis.children('.layui-code-wrap').html(
var rst = createCode(html); createCode(finalCode(rawCode)).html
othis.children('.layui-code-wrap').html(rst.html); ), ret;
})(rawCode.join(''))
return ret;
} }
// 自增索引 // 自增索引
@ -195,21 +196,13 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){
othis.data(CONST.CDDE_DATA_CLASS, othis.attr('class')); othis.data(CONST.CDDE_DATA_CLASS, othis.attr('class'));
} }
// code
var html = finalCode = rawCode.join('');
// 外部重新解析 code
if(typeof options.codeParse === 'function'){
html = finalCode = options.codeParse(html);
}
// 工具栏 // 工具栏
var tools = { var tools = {
copy: { copy: {
className: 'file-b', className: 'file-b',
title: ['复制代码'], title: ['复制代码'],
event: function(obj){ event: function(obj){
var code = util.unescape(finalCode); var code = util.unescape(finalCode(options.code));
// 写入剪切板 // 写入剪切板
lay.clipboard.writeText({ lay.clipboard.writeText({
@ -282,19 +275,19 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){
var classNameFull = 'layui-icon-'+ this.className; var classNameFull = 'layui-icon-'+ this.className;
var classNameRestore = 'layui-icon-screen-restore'; var classNameRestore = 'layui-icon-screen-restore';
var title = this.title; var title = this.title;
var html = $('html,body'); var htmlElem = $('html,body');
var ELEM_SCROLLBAR_HIDE = 'layui-scrollbar-hide'; var ELEM_SCROLLBAR_HIDE = 'layui-scrollbar-hide';
if(el.hasClass(classNameFull)){ if(el.hasClass(classNameFull)){
elemView.addClass(CONST.ELEM_FULL); elemView.addClass(CONST.ELEM_FULL);
el.removeClass(classNameFull).addClass(classNameRestore); el.removeClass(classNameFull).addClass(classNameRestore);
el.attr('title', title[1]); el.attr('title', title[1]);
html.addClass(ELEM_SCROLLBAR_HIDE); htmlElem.addClass(ELEM_SCROLLBAR_HIDE);
} else { } else {
elemView.removeClass(CONST.ELEM_FULL); elemView.removeClass(CONST.ELEM_FULL);
el.removeClass(classNameRestore).addClass(classNameFull); el.removeClass(classNameRestore).addClass(classNameFull);
el.attr('title', title[0]); el.attr('title', title[0]);
html.removeClass(ELEM_SCROLLBAR_HIDE); htmlElem.removeClass(ELEM_SCROLLBAR_HIDE);
} }
} }
}, },
@ -303,7 +296,7 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){
title: ['在新窗口预览'], title: ['在新窗口预览'],
event: function(obj){ event: function(obj){
util.openWin({ util.openWin({
content: finalCode content: finalCode(options.code)
}); });
} }
} }
@ -329,8 +322,8 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){
elem: oi, elem: oi,
type: type, type: type,
options: options, // 当前属性选项 options: options, // 当前属性选项
rawCode: rawCode.join(''), // 原始 code rawCode: options.code, // 原始 code
finalCode: util.unescape(finalCode) // 最终 code finalCode: util.unescape(finalCode(options.code)) // 最终 code
}; };
// 内部 tools event // 内部 tools event
@ -341,8 +334,8 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){
}); });
// 增加工具栏 // 增加工具栏
if (options.addTools) { if (options.addTools && options.tools) {
options.tools = [].concat(options.tools || [], options.addTools); options.tools = [].concat(options.tools, options.addTools);
} }
// 渲染工具栏 // 渲染工具栏
@ -384,32 +377,33 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){
} }
// 执行预览 // 执行预览
var run = function(thisItemBody){ var runPreview = function(thisItemBody){
var iframe = thisItemBody.children('iframe')[0]; var iframe = thisItemBody.children('iframe')[0];
// 是否 iframe 方式预览
if(isIframePreview && iframe){ if(isIframePreview && iframe){
iframe.srcdoc = finalCode; iframe.srcdoc = finalCode(options.code);
} else { } else {
thisItemBody.html(rawCode.join('')); thisItemBody.html(options.code);
} }
// 回调的返回参数
var params = {
container: thisItemBody,
render: function(){
form.render(thisItemBody.find('.layui-form'));
element.render();
}
};
// 当前实例预览完毕后的回调 // 当前实例预览完毕后的回调
setTimeout(function(){ setTimeout(function(){
typeof options.done === 'function' && options.done(params); typeof options.done === 'function' && options.done({
container: thisItemBody,
options: options,
render: function(){
form.render(thisItemBody.find('.layui-form'));
element.render();
}
});
},3); },3);
}; };
if(layout[0] === 'preview'){ if(layout[0] === 'preview'){
elemPreviewView.addClass(CONST.ELEM_SHOW); elemPreviewView.addClass(CONST.ELEM_SHOW);
othis.before(elemPreviewView); othis.before(elemPreviewView);
run(elemPreviewView); runPreview(elemPreviewView);
} else { } else {
othis.addClass(CONST.ELEM_SHOW).after(elemPreviewView); othis.addClass(CONST.ELEM_SHOW).after(elemPreviewView);
} }
@ -429,7 +423,7 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){
thisItemBody.addClass(CONST.ELEM_SHOW); thisItemBody.addClass(CONST.ELEM_SHOW);
if($this.attr('lay-id') === 'preview'){ if($this.attr('lay-id') === 'preview'){
run(thisItemBody); runPreview(thisItemBody);
} }
setCodeLayout(); setCodeLayout();
@ -461,10 +455,10 @@ layui.define(['lay', 'util', 'element', 'form'], function(exports){
].join(' ')); ].join(' '));
} }
// 转义 HTML 标签 // 获取 code 行结构
if(options.encode) html = util.escape(html); // 编码 var createCodeRst = createCode(
options.encode ? util.escape(finalCode(rawCode)) : rawCode // 是否编码
var createCodeRst = createCode(html); );
var lines = createCodeRst.lines; var lines = createCodeRst.lines;
// 插入 code // 插入 code

View File

@ -272,14 +272,14 @@ layui.define('jquery', function(exports){
) )
*/ */
//点击菜单 - a标签触发 // 点击菜单 - a 标签触发
,clickThis: function(){ ,clickThis: function(){
var othis = $(this) var othis = $(this);
,parents = othis.parents(NAV_ELEM) var parents = othis.parents(NAV_ELEM);
,filter = parents.attr('lay-filter') var filter = parents.attr('lay-filter');
,parent = othis.parent() var parent = othis.parent() ;
,child = othis.siblings('.'+NAV_CHILD) var child = othis.siblings('.'+NAV_CHILD);
,unselect = typeof parent.attr('lay-unselect') === 'string'; //是否禁用选中 var unselect = typeof parent.attr('lay-unselect') === 'string'; // 是否禁用选中
if(!(othis.attr('href') !== 'javascript:;' && othis.attr('target') === '_blank') && !unselect){ if(!(othis.attr('href') !== 'javascript:;' && othis.attr('target') === '_blank') && !unselect){
if(!child[0]){ if(!child[0]){
@ -288,15 +288,27 @@ layui.define('jquery', function(exports){
} }
} }
//如果是垂直菜单 // 若为垂直菜单
if(parents.hasClass(NAV_TREE)){ if(parents.hasClass(NAV_TREE)){
var NAV_ITEMED = NAV_ITEM + 'ed';
var NAV_EXPAND = 'layui-nav-expand';
var isNone = child.css('display') === 'none';
child.removeClass(NAV_ANIM); child.removeClass(NAV_ANIM);
//如果有子菜单,则展开 //有子菜单,则展开
if(child[0]){ if(child[0]){
parent[child.css('display') === 'none' ? 'addClass': 'removeClass'](NAV_ITEM+'ed'); child.slideToggle(200, function() {
if(parents.attr('lay-shrink') === 'all'){ isNone || parent.removeClass(NAV_ITEMED);
parent.siblings().removeClass(NAV_ITEM + 'ed'); });
parent[isNone ? 'addClass': 'removeClass'](NAV_EXPAND);
// 手风琴
if(typeof parents.attr('lay-accordion') === 'string' || parents.attr('lay-shrink') === 'all'){
// 收缩兄弟项
parent.siblings().removeClass([
NAV_ITEMED,
NAV_EXPAND
].join(' ')).children('.'+NAV_CHILD).slideUp(200);
} }
} }
} }
@ -304,26 +316,16 @@ layui.define('jquery', function(exports){
layui.event.call(this, MOD_NAME, 'nav('+ filter +')', othis); layui.event.call(this, MOD_NAME, 'nav('+ filter +')', othis);
} }
//点击子菜单选中 // 折叠面板
/*
,clickChild: function(){
var othis = $(this), parents = othis.parents(NAV_ELEM)
,filter = parents.attr('lay-filter');
parents.find('.'+THIS).removeClass(THIS);
othis.addClass(THIS);
layui.event.call(this, MOD_NAME, 'nav('+ filter +')', othis);
}
*/
//折叠面板
,collapse: function(){ ,collapse: function(){
var othis = $(this), icon = othis.find('.layui-colla-icon') var othis = $(this);
,elemCont = othis.siblings('.layui-colla-content') var icon = othis.find('.layui-colla-icon');
,parents = othis.parents('.layui-collapse').eq(0) var elemCont = othis.siblings('.layui-colla-content');
,filter = parents.attr('lay-filter') var parents = othis.parents('.layui-collapse').eq(0);
,isNone = elemCont.css('display') === 'none'; var filter = parents.attr('lay-filter');
var isNone = elemCont.css('display') === 'none';
//是否手风琴 // 是否手风琴
if(typeof parents.attr('lay-accordion') === 'string'){ if(typeof parents.attr('lay-accordion') === 'string'){
var show = parents.children('.layui-colla-item').children('.'+SHOW); var show = parents.children('.layui-colla-item').children('.'+SHOW);
show.siblings('.layui-colla-title').children('.layui-colla-icon').html('&#xe602;'); show.siblings('.layui-colla-title').children('.layui-colla-icon').html('&#xe602;');

View File

@ -174,6 +174,48 @@ layui.define(['lay', 'layer', 'util'], function(exports){
// 初始化全局的 autocomplete // 初始化全局的 autocomplete
options.autocomplete && inputs.attr('autocomplete', options.autocomplete); options.autocomplete && inputs.attr('autocomplete', options.autocomplete);
var handleInputNumberEvents = function(elem, eventType){
var that = this;
var rawValue = elem.val();
var value = Number(rawValue);
var step = Number(elem.attr('step')) || 1; // 加减的数字间隔
var min = Number(elem.attr('min'));
var max = Number(elem.attr('max'));
var precision = Number(elem.attr('lay-precision'));
var noAction = eventType === 'blur' && rawValue === '' // 失焦时空值不作处理
if(isNaN(value)) return; // 若非数字,则不作处理
if(eventType === 'click'){
var isDecrement = !!$(that).index() // 0: icon-up, 1: icon-down
value = isDecrement ? value - step : value + step;
}
// 获取小数点后位数
var decimals = function(step){
var decimals = (step.toString().match(/\.(\d+$)/) || [])[1] || '';
return decimals.length;
};
precision = precision >= 0 ? precision : Math.max(decimals(step), decimals(rawValue));
if(!noAction){
if(value <= min) value = min;
if(value >= max) value = max;
if(precision) value = value.toFixed(precision);
elem.val(value)
}
// 更新按钮状态
var controlBtn = {
increment: elem.next().find('.layui-icon-up'),
decrement: elem.next().find('.layui-icon-down')
}
controlBtn.increment[(value >= max && !noAction) ? 'addClass' : 'removeClass'](DISABLED)
controlBtn.decrement[(value <= min && !noAction) ? 'addClass' : 'removeClass'](DISABLED)
}
// 初始化输入框动态点缀 // 初始化输入框动态点缀
elemForm.find('input[lay-affix],textarea[lay-affix]').each(function(){ elemForm.find('input[lay-affix],textarea[lay-affix]').each(function(){
var othis = $(this); var othis = $(this);
@ -248,6 +290,11 @@ layui.define(['lay', 'layer', 'util'], function(exports){
var value = this.value; var value = this.value;
opts.show === 'auto' && showAffix(elemAffix, value); opts.show === 'auto' && showAffix(elemAffix, value);
}); });
// 失去焦点事件
othis.on('blur', function(){
typeof opts.blur === 'function' && opts.blur.call(this, othis, opts);
});
// 点击动态后缀事件 // 点击动态后缀事件
elemIcon.on('click', function(){ elemIcon.on('click', function(){
@ -295,35 +342,11 @@ layui.define(['lay', 'layer', 'util'], function(exports){
className: 'layui-input-number', className: 'layui-input-number',
disabled: othis.is('[disabled]'), // 跟随输入框禁用状态 disabled: othis.is('[disabled]'), // 跟随输入框禁用状态
click: function(elem){ click: function(elem){
var index = $(this).index(); handleInputNumberEvents.call(this, elem, 'click')
var value = elem.val(); },
var rawValue = value; blur: function(elem){
var step = Number(elem.attr('step')) || 1; // 加减的数字间隔 handleInputNumberEvents.call(this, elem, 'blur')
var min = Number(elem.attr('min')); },
var max = Number(elem.attr('max'));
if(isNaN(value)) return; // 若非数字,则不作处理
value = Number(value);
value = index ? value - step : value + step;
// min max
if(value < min) value = min;
if(value > max) value = max;
// 获取小数点后位数
var decimals = function(step){
var decimals = (step.toString().match(/\.(\d+$)/) || [])[1] || '';
return decimals.length;
};
// 位数比较
var fixed = Math.max(decimals(step), decimals(rawValue));
if(fixed) value = value.toFixed(fixed);
elem.val(value);
}
} }
}; };

View File

@ -2178,9 +2178,9 @@
return that; return that;
}; };
//初始执行 // 初始执行
ready.run = function(lay){ ready.run = function(lay){
//绑定关闭控件事件 // 绑定关闭控件事件
lay(document).on('mousedown', function(e){ lay(document).on('mousedown', function(e){
if(!laydate.thisId) return; if(!laydate.thisId) return;
var that = thisModule.getThis(laydate.thisId); var that = thisModule.getThis(laydate.thisId);
@ -2191,7 +2191,8 @@
if( if(
e.target === options.elem[0] || e.target === options.elem[0] ||
e.target === options.eventElem[0] || e.target === options.eventElem[0] ||
e.target === lay(options.closeStop)[0] e.target === lay(options.closeStop)[0] ||
(options.elem[0] && options.elem[0].contains(e.target))
) return; ) return;
that.remove(); that.remove();

View File

@ -1719,6 +1719,23 @@ layer.photos = function(options, loop, key){
ready.run = function(_$){ ready.run = function(_$){
$ = _$; $ = _$;
win = $(window); win = $(window);
// 移动端兼容性处理
// https://gitee.com/layui/layui/issues/I81WGC
// https://github.com/jquery/jquery/issues/1729
var agent = navigator.userAgent.toLowerCase();
var isMobile = /android|iphone|ipod|ipad|ios/.test(agent)
var _win = $(window);
if(isMobile){
$.each({Height: "height", Width: "width"}, function(propSuffix, funcName){
var propName = 'inner' + propSuffix;
win[funcName] = function(){
return propName in window
? window[propName]
: _win[funcName]()
}
})
}
doms.html = $('html'); doms.html = $('html');
layer.open = function(deliver){ layer.open = function(deliver){
var o = new Class(deliver); var o = new Class(deliver);

View File

@ -19,7 +19,7 @@ layui.define(['jquery', 'lay'],function(exports){
that.config = $.extend({}, that.config, options); that.config = $.extend({}, that.config, options);
return that; return that;
}, },
//事件 //事件
on: function(events, callback){ on: function(events, callback){
return layui.onevent.call(this, MOD_NAME, events, callback); return layui.onevent.call(this, MOD_NAME, events, callback);
@ -64,14 +64,14 @@ layui.define(['jquery', 'lay'],function(exports){
readonly: false, //是否只读 readonly: false, //是否只读
half: false, //是否可以半星 half: false, //是否可以半星
value: 0, //星星选中个数 value: 0, //星星选中个数
theme: '' theme: '' //主题颜色
}; };
//评分渲染 //评分渲染
Class.prototype.render = function(){ Class.prototype.render = function(){
var that = this; var that = this;
var options = that.config; var options = that.config;
// 若 elem 非唯一,则拆分为多个实例 // 若 elem 非唯一,则拆分为多个实例
var elem = $(options.elem); var elem = $(options.elem);
if(elem.length > 1){ if(elem.length > 1){
@ -88,9 +88,9 @@ layui.define(['jquery', 'lay'],function(exports){
// 自定义主题 // 自定义主题
var style = options.theme ? ('style="color: '+ options.theme + ';"') : ''; var style = options.theme ? ('style="color: '+ options.theme + ';"') : '';
options.elem = $(options.elem); options.elem = $(options.elem);
//最大值不能大于总长度 //最大值不能大于总长度
if(options.value > options.length){ if(options.value > options.length){
options.value = options.length; options.value = options.length;
@ -121,12 +121,12 @@ layui.define(['jquery', 'lay'],function(exports){
//开始插入替代元素 //开始插入替代元素
var othis = options.elem; var othis = options.elem;
var hasRender = othis.next('.' + ELEM_VIEW); var hasRender = othis.next('.' + ELEM_VIEW);
//生成替代元素 //生成替代元素
hasRender[0] && hasRender.remove(); //如果已经渲染则Rerender hasRender[0] && hasRender.remove(); //如果已经渲染则Rerender
that.elemTemp = $(temp); that.elemTemp = $(temp);
options.span = that.elemTemp.next('span'); options.span = that.elemTemp.next('span');
options.setText && options.setText(options.value); options.setText && options.setText(options.value);
@ -136,7 +136,7 @@ layui.define(['jquery', 'lay'],function(exports){
othis.addClass("layui-inline"); othis.addClass("layui-inline");
//如果不是只读,那么进行触控事件 //如果不是只读,那么进行触控事件
if(!options.readonly) that.action(); if(!options.readonly) that.action();
}; };
@ -180,7 +180,7 @@ layui.define(['jquery', 'lay'],function(exports){
//移入 //移入
othis.on('mousemove', function(e){ othis.on('mousemove', function(e){
_ul.find("i").each(function(){ _ul.find("i").each(function(){
$(this).addClass(ICON_RATE).removeClass(ICON_SOLID_HALF) $(this).addClass(ICON_RATE).removeClass(ICON_SOLID_HALF)
}); });
_ul.find("i:lt(" + ind + ")").each(function(){ _ul.find("i:lt(" + ind + ")").each(function(){
@ -192,7 +192,7 @@ layui.define(['jquery', 'lay'],function(exports){
if(x <= wide / 2){ if(x <= wide / 2){
othis.children("i").addClass(ICON_RATE_HALF).removeClass(ICON_RATE_SOLID) othis.children("i").addClass(ICON_RATE_HALF).removeClass(ICON_RATE_SOLID)
} }
} }
}) })
//移出 //移出
@ -206,14 +206,14 @@ layui.define(['jquery', 'lay'],function(exports){
//如果设置可选半星,根据分数判断是否有半星 //如果设置可选半星,根据分数判断是否有半星
if(options.half){ if(options.half){
if(parseInt(options.value) !== options.value){ if(parseInt(options.value) !== options.value){
_ul.children("li:eq(" + Math.floor(options.value) + ")").children("i").addClass(ICON_RATE_HALF).removeClass(ICON_SOLID_RATE) _ul.children("li:eq(" + Math.floor(options.value) + ")").children("i").addClass(ICON_RATE_HALF).removeClass(ICON_SOLID_RATE)
} }
} }
}) })
}) })
}; };
//事件处理 //事件处理
Class.prototype.events = function () { Class.prototype.events = function () {
var that = this; var that = this;
@ -225,6 +225,6 @@ layui.define(['jquery', 'lay'],function(exports){
var inst = new Class(options); var inst = new Class(options);
return thisRate.call(inst); return thisRate.call(inst);
}; };
exports(MOD_NAME, rate); exports(MOD_NAME, rate);
}) })

View File

@ -19,13 +19,13 @@ layui.define(['jquery', 'lay'], function(exports){
that.config = $.extend({}, that.config, options); that.config = $.extend({}, that.config, options);
return that; return that;
} }
// 事件 // 事件
,on: function(events, callback){ ,on: function(events, callback){
return layui.onevent.call(this, MOD_NAME, events, callback); return layui.onevent.call(this, MOD_NAME, events, callback);
} }
}; };
// 操作当前实例 // 操作当前实例
var thisSlider = function(){ var thisSlider = function(){
var that = this var that = this
@ -97,25 +97,25 @@ layui.define(['jquery', 'lay'], function(exports){
// 合并 lay-options 属性上的配置信息 // 合并 lay-options 属性上的配置信息
$.extend(options, lay.options(elem[0])); $.extend(options, lay.options(elem[0]));
//间隔值不能小于 1 //间隔值不能小于 1
if(options.step < 1) options.step = 1; if(options.step < 1) options.step = 1;
//最大值不能小于最小值 //最大值不能小于最小值
if(options.max < options.min) options.max = options.min + options.step; if(options.max < options.min) options.max = options.min + options.step;
//判断是否开启双滑块 //判断是否开启双滑块
if(options.range){ if(options.range){
options.value = typeof(options.value) == 'object' ? options.value : [options.min, options.value]; options.value = typeof(options.value) == 'object' ? options.value : [options.min, options.value];
var minValue = Math.min(options.value[0], options.value[1]) var minValue = Math.min(options.value[0], options.value[1])
,maxValue = Math.max(options.value[0], options.value[1]); ,maxValue = Math.max(options.value[0], options.value[1]);
options.value[0] = minValue > options.min ? minValue : options.min; options.value[0] = Math.max(minValue,options.min);
options.value[1] = maxValue > options.min ? maxValue : options.min; options.value[1] = Math.max(maxValue,options.min);
options.value[0] = options.value[0] > options.max ? options.max : options.value[0]; options.value[0] = Math.min(options.value[0],options.max);
options.value[1] = options.value[1] > options.max ? options.max : options.value[1]; options.value[1] = Math.min(options.value[1],options.max);
var scaleFir = Math.floor((options.value[0] - options.min) / (options.max - options.min) * 100) var scaleFir = Math.floor((options.value[0] - options.min) / (options.max - options.min) * 100)
,scaleSec = Math.floor((options.value[1] - options.min) / (options.max - options.min) * 100) ,scaleSec = Math.floor((options.value[1] - options.min) / (options.max - options.min) * 100)
,scale = scaleSec - scaleFir + '%'; ,scale = scaleSec - scaleFir + '%';
@ -126,44 +126,44 @@ layui.define(['jquery', 'lay'], function(exports){
if(typeof options.value == 'object'){ if(typeof options.value == 'object'){
options.value = Math.min.apply(null, options.value); options.value = Math.min.apply(null, options.value);
} }
//初始值不能小于最小值且不能大于最大值 //初始值不能小于最小值且不能大于最大值
if(options.value < options.min) options.value = options.min; if(options.value < options.min) options.value = options.min;
if(options.value > options.max) options.value = options.max; if(options.value > options.max) options.value = options.max;
var scale = Math.floor((options.value - options.min) / (options.max - options.min) * 100) + '%'; var scale = Math.floor((options.value - options.min) / (options.max - options.min) * 100) + '%';
}; }
//如果禁用,颜色为统一的灰色 //如果禁用,颜色为统一的灰色
var theme = options.disabled ? '#c2c2c2' : options.theme; var theme = options.disabled ? '#c2c2c2' : options.theme;
//滑块 //滑块
var temp = '<div class="layui-slider '+ (options.type === 'vertical' ? 'layui-slider-vertical' : '') +'">'+ (options.tips ? '<div class="'+ SLIDER_TIPS +'"></div>' : '') + var temp = '<div class="layui-slider '+ (options.type === 'vertical' ? 'layui-slider-vertical' : '') +'">'+ (options.tips ? '<div class="'+ SLIDER_TIPS +'"></div>' : '') +
'<div class="layui-slider-bar" style="background:'+ theme +'; '+ (options.type === 'vertical' ? 'height' : 'width') +':'+ scale +';'+ (options.type === 'vertical' ? 'bottom' : 'left') +':'+ (scaleFir || 0) +';"></div><div class="layui-slider-wrap" style="'+ (options.type === 'vertical' ? 'bottom' : 'left') +':'+ (scaleFir || scale) +';">' + '<div class="layui-slider-bar" style="background:'+ theme +'; '+ (options.type === 'vertical' ? 'height' : 'width') +':'+ scale +';'+ (options.type === 'vertical' ? 'bottom' : 'left') +':'+ (scaleFir || 0) +';"></div><div class="layui-slider-wrap" style="'+ (options.type === 'vertical' ? 'bottom' : 'left') +':'+ (scaleFir || scale) +';">' +
'<div class="layui-slider-wrap-btn" style="border: 2px solid '+ theme +';"></div></div>'+ (options.range ? '<div class="layui-slider-wrap" style="'+ (options.type === 'vertical' ? 'bottom' : 'left') +':'+ scaleSec +';"><div class="layui-slider-wrap-btn" style="border: 2px solid '+ theme +';"></div></div>' : '') +'</div>'; '<div class="layui-slider-wrap-btn" style="border: 2px solid '+ theme +';"></div></div>'+ (options.range ? '<div class="layui-slider-wrap" style="'+ (options.type === 'vertical' ? 'bottom' : 'left') +':'+ scaleSec +';"><div class="layui-slider-wrap-btn" style="border: 2px solid '+ theme +';"></div></div>' : '') +'</div>';
var othis = $(options.elem) var othis = $(options.elem)
,hasRender = othis.next('.' + ELEM_VIEW); ,hasRender = othis.next('.' + ELEM_VIEW);
//生成替代元素 //生成替代元素
hasRender[0] && hasRender.remove(); //如果已经渲染则Rerender hasRender[0] && hasRender.remove(); //如果已经渲染则Rerender
that.elemTemp = $(temp); that.elemTemp = $(temp);
//把数据缓存到滑块上 //把数据缓存到滑块上
if(options.range){ if(options.range){
that.elemTemp.find('.' + SLIDER_WRAP).eq(0).data('value', options.value[0]); that.elemTemp.find('.' + SLIDER_WRAP).eq(0).data('value', options.value[0]);
that.elemTemp.find('.' + SLIDER_WRAP).eq(1).data('value', options.value[1]); that.elemTemp.find('.' + SLIDER_WRAP).eq(1).data('value', options.value[1]);
}else{ }else{
that.elemTemp.find('.' + SLIDER_WRAP).data('value', options.value); that.elemTemp.find('.' + SLIDER_WRAP).data('value', options.value);
}; }
//插入替代元素 //插入替代元素
othis.html(that.elemTemp); othis.html(that.elemTemp);
//垂直滑块 //垂直滑块
if(options.type === 'vertical'){ if(options.type === 'vertical'){
that.elemTemp.height(options.height + 'px'); that.elemTemp.height(options.height + 'px');
}; }
//显示间断点 //显示间断点
if(options.showstep){ if(options.showstep){
@ -173,9 +173,9 @@ layui.define(['jquery', 'lay'], function(exports){
if(step < 100){ if(step < 100){
item += '<div class="layui-slider-step" style="'+ (options.type === 'vertical' ? 'bottom' : 'left') +':'+ step +'%"></div>' item += '<div class="layui-slider-step" style="'+ (options.type === 'vertical' ? 'bottom' : 'left') +':'+ step +'%"></div>'
} }
}; }
that.elemTemp.append(item); that.elemTemp.append(item);
}; }
//插入输入框 //插入输入框
if(options.input && !options.range){ if(options.input && !options.range){
@ -191,7 +191,7 @@ layui.define(['jquery', 'lay'], function(exports){
} else { } else {
that.elemTemp.css("margin-right", elemInput.outerWidth() + 15); that.elemTemp.css("margin-right", elemInput.outerWidth() + 15);
} }
}; }
//给未禁止的滑块滑动事件 //给未禁止的滑块滑动事件
if(!options.disabled){ if(!options.disabled){
@ -199,7 +199,7 @@ layui.define(['jquery', 'lay'], function(exports){
}else{ }else{
that.elemTemp.addClass(DISABLED); that.elemTemp.addClass(DISABLED);
that.elemTemp.find('.' + SLIDER_WRAP_BTN).addClass(DISABLED); that.elemTemp.find('.' + SLIDER_WRAP_BTN).addClass(DISABLED);
}; }
//划过滑块显示数值 //划过滑块显示数值
var timer; var timer;
@ -216,21 +216,21 @@ layui.define(['jquery', 'lay'], function(exports){
timer = setTimeout(function(){ timer = setTimeout(function(){
if(options.type === 'vertical'){ if(options.type === 'vertical'){
that.elemTemp.find('.' + SLIDER_TIPS).css({ that.elemTemp.find('.' + SLIDER_TIPS).css({
"bottom": left + '%', "bottom": left + '%',
"margin-bottom": "20px", "margin-bottom": "20px",
"display": "inline-block" "display": "inline-block"
}); });
} else { } else {
that.elemTemp.find('.' + SLIDER_TIPS).css({ that.elemTemp.find('.' + SLIDER_TIPS).css({
"left": left + '%', "left": left + '%',
"display": "inline-block" "display": "inline-block"
}); });
}; }
}, 300); }, 300);
}).on('mouseout', function(){ }).on('mouseout', function(){
clearTimeout(timer); clearTimeout(timer);
that.elemTemp.find('.' + SLIDER_TIPS).css("display", "none"); that.elemTemp.find('.' + SLIDER_TIPS).css("display", "none");
}); });
}; };
//滑块滑动 //滑块滑动
@ -250,7 +250,7 @@ layui.define(['jquery', 'lay'], function(exports){
offsetValue = Math.ceil(offsetValue) * step offsetValue = Math.ceil(offsetValue) * step
}else{ }else{
offsetValue = Math.round(offsetValue) * step offsetValue = Math.round(offsetValue) * step
}; }
offsetValue = offsetValue > 100 ? 100: offsetValue; offsetValue = offsetValue > 100 ? 100: offsetValue;
offsetValue = offsetValue < 0 ? 0: offsetValue; offsetValue = offsetValue < 0 ? 0: offsetValue;
sliderWrap.eq(index).css((options.type === 'vertical' ?'bottom':'left'), offsetValue + '%'); sliderWrap.eq(index).css((options.type === 'vertical' ?'bottom':'left'), offsetValue + '%');
@ -262,7 +262,7 @@ layui.define(['jquery', 'lay'], function(exports){
secLeft = options.range ? valueTo(sliderWidth() - sliderWrap[1].offsetTop - sliderWrap.height()) : 0; secLeft = options.range ? valueTo(sliderWidth() - sliderWrap[1].offsetTop - sliderWrap.height()) : 0;
}else{ }else{
sliderAct.find('.' + SLIDER_TIPS).css("left",offsetValue + '%'); sliderAct.find('.' + SLIDER_TIPS).css("left",offsetValue + '%');
}; }
firLeft = firLeft > 100 ? 100: firLeft; firLeft = firLeft > 100 ? 100: firLeft;
secLeft = secLeft > 100 ? 100: secLeft; secLeft = secLeft > 100 ? 100: secLeft;
var minLeft = Math.min(firLeft, secLeft) var minLeft = Math.min(firLeft, secLeft)
@ -271,13 +271,13 @@ layui.define(['jquery', 'lay'], function(exports){
sliderAct.find('.' + SLIDER_BAR).css({"height":wrapWidth + '%', "bottom":minLeft + '%'}); sliderAct.find('.' + SLIDER_BAR).css({"height":wrapWidth + '%', "bottom":minLeft + '%'});
}else{ }else{
sliderAct.find('.' + SLIDER_BAR).css({"width":wrapWidth + '%', "left":minLeft + '%'}); sliderAct.find('.' + SLIDER_BAR).css({"width":wrapWidth + '%', "left":minLeft + '%'});
}; }
var selfValue = options.min + Math.round((options.max - options.min) * offsetValue / 100); var selfValue = options.min + Math.round((options.max - options.min) * offsetValue / 100);
inputValue = selfValue; inputValue = selfValue;
sliderTxt.children('.' + SLIDER_INPUT_TXT).children('input').val(inputValue); sliderTxt.children('.' + SLIDER_INPUT_TXT).children('input').val(inputValue);
sliderWrap.eq(index).data('value', selfValue); sliderWrap.eq(index).data('value', selfValue);
sliderAct.find('.' + SLIDER_TIPS).html(options.setTips ? options.setTips(selfValue) : selfValue); sliderAct.find('.' + SLIDER_TIPS).html(options.setTips ? options.setTips(selfValue) : selfValue);
//如果开启范围选择,则返回数组值 //如果开启范围选择,则返回数组值
if(options.range){ if(options.range){
var arrValue = [ var arrValue = [
@ -298,10 +298,10 @@ layui.define(['jquery', 'lay'], function(exports){
,left = Math.round(oldLeft) * step; ,left = Math.round(oldLeft) * step;
if(value == sliderWidth()){ if(value == sliderWidth()){
left = Math.ceil(oldLeft) * step; left = Math.ceil(oldLeft) * step;
}; }
return left; return left;
} }
//拖拽元素 //拖拽元素
,elemMove = $(['<div class="layui-auxiliar-moving" id="LAY-slider-moving"></div'].join('')) ,elemMove = $(['<div class="layui-auxiliar-moving" id="LAY-slider-moving"></div'].join(''))
,createMoveElem = function(move, up){ ,createMoveElem = function(move, up){
@ -314,7 +314,7 @@ layui.define(['jquery', 'lay'], function(exports){
elemMove.on('mousemove', move); elemMove.on('mousemove', move);
elemMove.on('mouseup', upCall).on('mouseleave', upCall); elemMove.on('mouseup', upCall).on('mouseleave', upCall);
}; };
//动态赋值 //动态赋值
if(setValue === 'set') return change(value - options.min, i, 'done'); if(setValue === 'set') return change(value - options.min, i, 'done');
@ -323,14 +323,14 @@ layui.define(['jquery', 'lay'], function(exports){
var othis = $(this); var othis = $(this);
othis.on('mousedown', function(e){ othis.on('mousedown', function(e){
e = e || window.event; e = e || window.event;
var oldleft = othis.parent()[0].offsetLeft var oldleft = othis.parent()[0].offsetLeft
,oldx = e.clientX; ,oldx = e.clientX;
if(options.type === 'vertical'){ if(options.type === 'vertical'){
oldleft = sliderWidth() - othis.parent()[0].offsetTop - sliderWrap.height() oldleft = sliderWidth() - othis.parent()[0].offsetTop - sliderWrap.height()
oldx = e.clientY; oldx = e.clientY;
}; }
var move = function(e){ var move = function(e){
e = e || window.event; e = e || window.event;
var left = oldleft + (options.type === 'vertical' ? (oldx - e.clientY) : (e.clientX - oldx)); var left = oldleft + (options.type === 'vertical' ? (oldx - e.clientY) : (e.clientX - oldx));
@ -342,23 +342,23 @@ layui.define(['jquery', 'lay'], function(exports){
sliderAct.find('.' + SLIDER_TIPS).show(); sliderAct.find('.' + SLIDER_TIPS).show();
e.preventDefault(); e.preventDefault();
}; };
var up = function(){ var up = function(){
othis.removeClass(ELEM_HOVER); othis.removeClass(ELEM_HOVER);
sliderAct.find('.' + SLIDER_TIPS).hide(); sliderAct.find('.' + SLIDER_TIPS).hide();
}; };
createMoveElem(move, up) createMoveElem(move, up)
}); });
}); });
// 点击滑块 // 点击滑块
sliderAct.on('click', function(e){ sliderAct.on('click', function(e){
var main = $('.' + SLIDER_WRAP_BTN); var main = $('.' + SLIDER_WRAP_BTN);
var othis = $(this); var othis = $(this);
if(!main.is(event.target) && main.has(event.target).length === 0 && main.length){ if(!main.is(event.target) && main.has(event.target).length === 0 && main.length){
var index; var index;
var offset = options.type === 'vertical' var offset = options.type === 'vertical'
? (sliderWidth() - e.clientY + othis.offset().top - $(window).scrollTop()) ? (sliderWidth() - e.clientY + othis.offset().top - $(window).scrollTop())
:(e.clientX - othis.offset().left - $(window).scrollLeft()); :(e.clientX - othis.offset().left - $(window).scrollLeft());
@ -373,30 +373,30 @@ layui.define(['jquery', 'lay'], function(exports){
} }
} else { } else {
index = 0; index = 0;
}; }
change(reaLeft, index, 'done'); change(reaLeft, index, 'done');
e.preventDefault(); e.preventDefault();
} }
}); });
//点击加减输入框 //点击加减输入框
sliderTxt.children('.' + SLIDER_INPUT_BTN).children('i').each(function(index){ sliderTxt.children('.' + SLIDER_INPUT_BTN).children('i').each(function(index){
$(this).on('click', function(){ $(this).on('click', function(){
inputValue = sliderTxt.children('.' + SLIDER_INPUT_TXT).children('input').val(); inputValue = sliderTxt.children('.' + SLIDER_INPUT_TXT).children('input').val();
if(index == 1){ //减 if(index == 1){ //减
inputValue = inputValue - options.step < options.min inputValue = inputValue - options.step < options.min
? options.min ? options.min
: Number(inputValue) - options.step; : Number(inputValue) - options.step;
}else{ }else{
inputValue = Number(inputValue) + options.step > options.max inputValue = Number(inputValue) + options.step > options.max
? options.max ? options.max
: Number(inputValue) + options.step; : Number(inputValue) + options.step;
}; }
var inputScale = (inputValue - options.min) / (options.max - options.min) * 100 / step; var inputScale = (inputValue - options.min) / (options.max - options.min) * 100 / step;
change(inputScale, 0, 'done'); change(inputScale, 0, 'done');
}); });
}); });
//获取输入框值 //获取输入框值
var getInputValue = function(){ var getInputValue = function(){
var realValue = this.value; var realValue = this.value;
@ -412,7 +412,7 @@ layui.define(['jquery', 'lay'], function(exports){
e.preventDefault(); e.preventDefault();
getInputValue.call(this); getInputValue.call(this);
} }
}).on('change', getInputValue); }).on('change', getInputValue);
}; };
//事件处理 //事件处理
@ -423,9 +423,9 @@ layui.define(['jquery', 'lay'], function(exports){
//核心入口 //核心入口
slider.render = function(options){ slider.render = function(options){
var inst = new Class(options); var inst = new Class(options);
return thisSlider.call(inst); return thisSlider.call(inst);
}; };
exports(MOD_NAME, slider); exports(MOD_NAME, slider);
}) })

View File

@ -572,8 +572,13 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
'{'+ lineStyle +'}', '{'+ lineStyle +'}',
'.layui-table-cell{height: auto; max-height: '+ cellMaxHeight +'; white-space: normal; text-overflow: clip;}', '.layui-table-cell{height: auto; max-height: '+ cellMaxHeight +'; white-space: normal; text-overflow: clip;}',
'> td:hover > .layui-table-cell{overflow: auto;}' '> td:hover > .layui-table-cell{overflow: auto;}'
], function(i, val) { ].concat(
text.push(trClassName + ' ' + val); device.ie ? [
'.layui-table-edit{height: '+ cellMaxHeight +';}',
'td[data-edit]:hover:after{height: '+ cellMaxHeight +';}'
] : []
), function(i, val) {
val && text.push(trClassName + ' ' + val);
}); });
})(options.lineStyle); })(options.lineStyle);
@ -1027,6 +1032,9 @@ layui.define(['lay', 'laytpl', 'laypage', 'form', 'util'], function(exports){
dataType: options.dataType || 'json', dataType: options.dataType || 'json',
jsonpCallback: options.jsonpCallback, jsonpCallback: options.jsonpCallback,
headers: options.headers || {}, headers: options.headers || {},
complete: function(xhr,ts){
typeof options.complete === 'function' && options.complete(xhr, ts);
},
success: function(res){ success: function(res){
// 若有数据解析的回调,则获得其返回的数据 // 若有数据解析的回调,则获得其返回的数据
if(typeof options.parseData === 'function'){ if(typeof options.parseData === 'function'){

View File

@ -56,7 +56,7 @@ layui.define(['laytpl', 'form'], function(exports){
var getThisModuleConfig = function(id){ var getThisModuleConfig = function(id){
var config = thisModule.config[id]; var config = thisModule.config[id];
if(!config) hint.error('The ID option was not found in the '+ MOD_NAME +' instance'); if(!config) hint.error('The ID option was not found in the '+ MOD_NAME +' instance');
return; config || null; return config || null;
}; };
// 字符常量 // 字符常量

View File

@ -1791,14 +1791,30 @@ layui.define(['table'], function (exports) {
// 目前只能处理当前页的数据 // 目前只能处理当前页的数据
return; return;
} }
var collectNeedExpandNodeIndex = function(index){
needExpandIndex.push(index);
var trElem = tableView.find('tr[lay-data-index="' + index + '"]');
if (!trElem.length) {
var nodeData = that.getNodeDataByIndex(index);
var parentIndex = nodeData[LAY_PARENT_INDEX];
parentIndex && collectNeedExpandNodeIndex(parentIndex);
}
}
// 判断是否展开过 // 判断是否展开过
var trElem = tableView.find('tr[lay-data-index="' + dataIndex + '"]'); var trElem = tableView.find('tr[lay-data-index="' + dataIndex + '"]');
if (!trElem.length) { if (!trElem.length) {
var parentIndex = nodeData[LAY_PARENT_INDEX];
var needExpandIndex = [];
collectNeedExpandNodeIndex(parentIndex);
// 如果还没有展开没有渲染的要先渲染出来 // 如果还没有展开没有渲染的要先渲染出来
treeTable.expandNode(id, { layui.each(needExpandIndex.reverse(),function(index, nodeIndex){
index: nodeData[LAY_PARENT_INDEX], treeTable.expandNode(id, {
expandFlag: true index: nodeIndex,
}); expandFlag: true
});
})
trElem = tableView.find('tr[lay-data-index="' + dataIndex + '"]'); trElem = tableView.find('tr[lay-data-index="' + dataIndex + '"]');
} }
checkNode.call(that, trElem, checked, callbackFlag); checkNode.call(that, trElem, checked, callbackFlag);

View File

@ -3,16 +3,22 @@
* 上传组件 * 上传组件
*/ */
layui.define(['lay','layer'], function(exports){ layui.define(['lay', 'layer'], function(exports){
"use strict"; "use strict";
var $ = layui.$; var $ = layui.$;
var lay = layui.lay;
var layer = layui.layer; var layer = layui.layer;
var device = layui.device(); var device = layui.device();
// 模块名
var MOD_NAME = 'upload';
var MOD_INDEX = 'layui_'+ MOD_NAME +'_index'; // 模块索引名
// 外部接口 // 外部接口
var upload = { var upload = {
config: {}, // 全局配置项 config: {}, // 全局配置项
index: layui[MOD_NAME] ? (layui[MOD_NAME].index + 10000) : 0, // 索引
// 设置全局项 // 设置全局项
set: function(options){ set: function(options){
var that = this; var that = this;
@ -26,8 +32,13 @@ layui.define(['lay','layer'], function(exports){
}; };
// 操作当前实例 // 操作当前实例
var thisUpload = function(){ var thisModule = function(){
var that = this; var that = this;
var options = that.config;
var id = options.id;
thisModule.that[id] = that; // 记录当前实例对象
return { return {
upload: function(files){ upload: function(files){
that.upload.call(that, files); that.upload.call(that, files);
@ -40,7 +51,6 @@ layui.define(['lay','layer'], function(exports){
}; };
// 字符常量 // 字符常量
var MOD_NAME = 'upload';
var ELEM = 'layui-upload'; var ELEM = 'layui-upload';
var THIS = 'layui-this'; var THIS = 'layui-this';
var SHOW = 'layui-show'; var SHOW = 'layui-show';
@ -57,6 +67,7 @@ layui.define(['lay','layer'], function(exports){
// 构造器 // 构造器
var Class = function(options){ var Class = function(options){
var that = this; var that = this;
that.index = ++upload.index;
that.config = $.extend({}, that.config, upload.config, options); that.config = $.extend({}, that.config, upload.config, options);
that.render(); that.render();
}; };
@ -86,15 +97,51 @@ layui.define(['lay','layer'], function(exports){
"limit-size": null // 限制 size 属性的提示 --- function "limit-size": null // 限制 size 属性的提示 --- function
} }
}; };
// 重载实例
Class.prototype.reload = function(options){
var that = this;
that.config = $.extend({}, that.config, options);
that.render(true);
};
// 初始渲染 // 初始渲染
Class.prototype.render = function(){ Class.prototype.render = function(rerender){
var that = this; var that = this;
var options = that.config; var options = that.config;
// 若 elem 非唯一
var elem = $(options.elem);
if (elem.length > 1) {
layui.each(elem, function() {
upload.render($.extend({}, options, {
elem: this
}));
});
return that;
}
// 合并 lay-options 属性上的配置信息
$.extend(options, lay.options(elem[0], {
attr: elem.attr('lay-data') ? 'lay-data' : null // 兼容旧版的 lay-data 属性
}));
// 若重复执行 render则视为 reload 处理
if (!rerender && elem[0] && elem.data(MOD_INDEX)) {
var newThat = thisModule.getThis(elem.data(MOD_INDEX));
if(!newThat) return;
return newThat.reload(options);
}
options.elem = $(options.elem); options.elem = $(options.elem);
options.bindAction = $(options.bindAction); options.bindAction = $(options.bindAction);
// 初始化 id 属性 - 优先取 options > 元素 id > 自增索引
options.id = 'id' in options ? options.id : (
elem.attr('id') || that.index
);
that.file(); that.file();
that.events(); that.events();
}; };
@ -219,11 +266,14 @@ layui.define(['lay','layer'], function(exports){
var request = function(sets){ var request = function(sets){
var formData = new FormData(); var formData = new FormData();
// 删除正在上传中的文件队列 // 恢复文件状态
var removeUploaded = function(index, file) { var resetFileState = function(file) {
if (file[UPLOADING]) { if (sets.unified) {
delete items[index]; layui.each(items, function(index, file){
return true; delete file[UPLOADING];
});
} else {
delete file[UPLOADING];
} }
}; };
@ -234,35 +284,36 @@ layui.define(['lay','layer'], function(exports){
}); });
/* /*
*添加 file 到表单域 * 添加 file 到表单域
*/ */
// 是否统一上传 // 是否统一上传
if (sets.unified) { if (sets.unified) {
layui.each(items, function(index, file){ layui.each(items, function(index, file){
if (removeUploaded(index, file)) return; if (file[UPLOADING]) return;
file[UPLOADING] = true; file[UPLOADING] = true; // 上传中的标记
formData.append(options.field, file); formData.append(options.field, file);
}); });
} else { // 逐一上传 } else { // 逐一上传
if (removeUploaded(sets.index, sets.file)) return; if (sets.file[UPLOADING]) return;
formData.append(options.field, sets.file); formData.append(options.field, sets.file);
sets.file[UPLOADING] = true; // 上传中的标记
} }
sets.file[UPLOADING] = true; // 上传中的标记
// ajax 参数 // ajax 参数
var opts = { var opts = {
url: options.url, url: options.url,
type: 'post', // 统一采用 post 上传 type: 'post', // 统一采用 post 上传
data: formData, data: formData,
dataType: options.dataType || 'json',
contentType: false, contentType: false,
processData: false, processData: false,
headers: options.headers || {}, headers: options.headers || {},
success: function(res){ // 成功回调 success: function(res){ // 成功回调
options.unified ? (successful += that.fileLength) : successful++; options.unified ? (successful += that.fileLength) : successful++;
done(sets.index, res); done(sets.index, res);
allDone(); allDone(sets.index);
resetFileState(sets.file);
}, },
error: function(e){ // 异常回调 error: function(e){ // 异常回调
options.unified ? (failed += that.fileLength) : failed++; options.unified ? (failed += that.fileLength) : failed++;
@ -271,15 +322,11 @@ layui.define(['lay','layer'], function(exports){
'status: '+ (e.status || '') +' - '+ (e.statusText || 'error') 'status: '+ (e.status || '') +' - '+ (e.statusText || 'error')
].join('<br>')); ].join('<br>'));
error(sets.index); error(sets.index);
allDone(); allDone(sets.index);
resetFileState(sets.file);
} }
}; };
// dataType
if (options.dataType) {
opts.dataType = options.dataType;
} else if (options.force === 'json') {
opts.dataType = options.force;
}
// 进度条 // 进度条
if(typeof options.progress === 'function'){ if(typeof options.progress === 'function'){
opts.xhr = function(){ opts.xhr = function(){
@ -360,7 +407,7 @@ layui.define(['lay','layer'], function(exports){
}; };
// 统一网络异常回调 // 统一网络异常回调
var error = function(index){ var error = function(index){
if(options.auto){ if(options.auto){
elemFile.value = ''; elemFile.value = '';
} }
@ -408,7 +455,7 @@ layui.define(['lay','layer'], function(exports){
}; };
// 提交上传 // 提交上传
var send = function(){ var send = function(){
// 上传前的回调 - 如果回调函数明确返回 false则停止上传 // 上传前的回调 - 如果回调函数明确返回 false则停止上传
if(options.before && (options.before(args) === false)) return; if(options.before && (options.before(args) === false)) return;
@ -433,7 +480,8 @@ layui.define(['lay','layer'], function(exports){
? ((elemFile.value.match(/[^\/\\]+\..+/g)||[]) || '') ? ((elemFile.value.match(/[^\/\\]+\..+/g)||[]) || '')
: value; : value;
if(value.length === 0) return; // 若文件域值为空
if (value.length === 0) return;
// 根据文件类型校验 // 根据文件类型校验
switch(options.accept){ switch(options.accept){
@ -520,24 +568,6 @@ layui.define(['lay','layer'], function(exports){
send(); send();
}; };
// 重置方法
Class.prototype.reload = function(opts){
opts = opts || {};
delete opts.elem;
delete opts.bindAction;
var that = this;
var options = that.config = $.extend({}, that.config, upload.config, opts);
var next = options.elem.next();
// 更新文件域相关属性
next.attr({
name: options.name,
accept: options.acceptMime,
multiple: options.multiple
});
};
//事件处理 //事件处理
Class.prototype.events = function(){ Class.prototype.events = function(){
var that = this; var that = this;
@ -568,23 +598,10 @@ layui.define(['lay','layer'], function(exports){
elemFile.after('<span class="layui-inline '+ ELEM_CHOOSE +'">'+ value +'</span>'); elemFile.after('<span class="layui-inline '+ ELEM_CHOOSE +'">'+ value +'</span>');
}; };
// 合并 lay-options/lay-data 属性配置项
var extendAttrs = function(){
var othis = $(this);
var data = othis.attr('lay-data') || othis.attr('lay-options'); // 优先兼容旧版本
if(data){
that.config = $.extend({}, options, lay.options(this, {
attr: othis.attr('lay-data') ? 'lay-data' : null
}));
}
};
// 点击上传容器 // 点击上传容器
options.elem.off('upload.start').on('upload.start', function(){ options.elem.off('upload.start').on('upload.start', function(){
var othis = $(this); var othis = $(this);
extendAttrs.call(this);
that.config.item = othis; that.config.item = othis;
that.elemFile[0].click(); that.elemFile[0].click();
}); });
@ -604,7 +621,6 @@ layui.define(['lay','layer'], function(exports){
var files = param.originalEvent.dataTransfer.files || []; var files = param.originalEvent.dataTransfer.files || [];
othis.removeAttr('lay-over'); othis.removeAttr('lay-over');
extendAttrs.call(this);
setChooseFile(files); setChooseFile(files);
options.auto ? that.upload() : setChooseText(files); // 是否自动触发上传 options.auto ? that.upload() : setChooseText(files); // 是否自动触发上传
@ -612,12 +628,11 @@ layui.define(['lay','layer'], function(exports){
} }
// 文件选择 // 文件选择
that.elemFile.off('upload.change').on('upload.change', function(){ that.elemFile.on('change', function(){
var files = this.files || []; var files = this.files || [];
if(files.length === 0) return; if(files.length === 0) return;
extendAttrs.call(this);
setChooseFile(files); setChooseFile(files);
options.auto ? that.upload() : setChooseText(files); // 是否自动触发上传 options.auto ? that.upload() : setChooseText(files); // 是否自动触发上传
@ -627,19 +642,19 @@ layui.define(['lay','layer'], function(exports){
options.bindAction.off('upload.action').on('upload.action', function(){ options.bindAction.off('upload.action').on('upload.action', function(){
that.upload(); that.upload();
}); });
// 防止事件重复绑定 // 防止事件重复绑定
if(options.elem.data('haveEvents')) return; if(options.elem.data(MOD_INDEX)) return;
that.elemFile.on('change', function(){
$(this).trigger('upload.change'); // 目标元素 click 事件
});
options.elem.on('click', function(){ options.elem.on('click', function(){
if(that.isFile()) return; if(that.isFile()) return;
$(this).trigger('upload.start'); $(this).trigger('upload.start');
}); });
// 目标元素 drop 事件
if(options.drag){ if(options.drag){
options.elem.on('dragover', function(e){ options.elem.on('dragover', function(e){
e.preventDefault(); e.preventDefault();
@ -652,17 +667,29 @@ layui.define(['lay','layer'], function(exports){
}); });
} }
// 手动上传时触发上传的元素 click 事件
options.bindAction.on('click', function(){ options.bindAction.on('click', function(){
$(this).trigger('upload.action'); $(this).trigger('upload.action');
}); });
options.elem.data('haveEvents', true); // 绑定元素索引
options.elem.data(MOD_INDEX, options.id);
};
// 记录所有实例
thisModule.that = {}; // 记录所有实例对象
// 获取当前实例对象
thisModule.getThis = function(id){
var that = thisModule.that[id];
if(!that) hint.error(id ? (MOD_NAME +' instance with ID \''+ id +'\' not found') : 'ID argument required');
return that;
}; };
// 核心入口 // 核心入口
upload.render = function(options){ upload.render = function(options){
var inst = new Class(options); var inst = new Class(options);
return thisUpload.call(inst); return thisModule.call(inst);
}; };
exports(MOD_NAME, upload); exports(MOD_NAME, upload);

View File

@ -1,13 +1,13 @@
/** /**
* util 工具组件 * util 工具组件
*/ */
layui.define('jquery', function(exports){ layui.define('jquery', function(exports){
"use strict"; "use strict";
var $ = layui.$; var $ = layui.$;
var hint = layui.hint(); var hint = layui.hint();
// 外部接口 // 外部接口
var util = { var util = {
// 固定块 // 固定块
@ -28,8 +28,8 @@ layui.define('jquery', function(exports){
var $target = $(options.target); var $target = $(options.target);
// 滚动条所在元素对象 // 滚动条所在元素对象
var $scroll = options.scroll var $scroll = options.scroll
? $(options.scroll) ? $(options.scroll)
: $(options.target === 'body' ? $doc : $target) : $(options.target === 'body' ? $doc : $target)
// 是否提供默认图标 // 是否提供默认图标
@ -72,8 +72,8 @@ layui.define('jquery', function(exports){
var type = $(this).attr('lay-type'); var type = $(this).attr('lay-type');
if(type === 'top'){ if(type === 'top'){
( (
options.target === 'body' options.target === 'body'
? $('html,body') ? $('html,body')
: $scroll : $scroll
).animate({ ).animate({
scrollTop : 0 scrollTop : 0
@ -130,9 +130,9 @@ layui.define('jquery', function(exports){
timer = setTimeout(function(){ timer = setTimeout(function(){
setTopBar(); setTopBar();
}, 100); }, 100);
}); });
}, },
// 倒计时 // 倒计时
countdown: function(options){ countdown: function(options){
var that = this; var that = this;
@ -198,27 +198,27 @@ layui.define('jquery', function(exports){
if(countTime <= 0){ if(countTime <= 0){
clearTimeout(inst.timer); clearTimeout(inst.timer);
typeof options.done === 'function' && options.done(result, inst); typeof options.done === 'function' && options.done(result, inst);
}; }
return fn; return fn;
})(); })();
return inst; return inst;
}, },
// 某个时间在当前时间的多久前 // 某个时间在当前时间的多久前
timeAgo: function(time, onlyDate){ timeAgo: function(time, onlyDate){
var that = this; var that = this;
var arr = [[], []]; var arr = [[], []];
var stamp = new Date().getTime() - new Date(time).getTime(); var stamp = new Date().getTime() - new Date(time).getTime();
// 返回具体日期 // 返回具体日期
if(stamp > 1000*60*60*24*31){ if(stamp > 1000*60*60*24*31){
stamp = new Date(time); stamp = new Date(time);
arr[0][0] = that.digit(stamp.getFullYear(), 4); arr[0][0] = that.digit(stamp.getFullYear(), 4);
arr[0][1] = that.digit(stamp.getMonth() + 1); arr[0][1] = that.digit(stamp.getMonth() + 1);
arr[0][2] = that.digit(stamp.getDate()); arr[0][2] = that.digit(stamp.getDate());
// 是否输出时间 // 是否输出时间
if(!onlyDate){ if(!onlyDate){
arr[1][0] = that.digit(stamp.getHours()); arr[1][0] = that.digit(stamp.getHours());
@ -227,7 +227,7 @@ layui.define('jquery', function(exports){
} }
return arr[0].join('-') + ' ' + arr[1].join(':'); return arr[0].join('-') + ' ' + arr[1].join(':');
} }
// 30 天以内,返回「多久前」 // 30 天以内,返回「多久前」
if(stamp >= 1000*60*60*24){ if(stamp >= 1000*60*60*24){
return ((stamp/1000/60/60/24)|0) + ' 天前'; return ((stamp/1000/60/60/24)|0) + ' 天前';
@ -241,7 +241,7 @@ layui.define('jquery', function(exports){
return '刚刚'; return '刚刚';
} }
}, },
// 数字前置补零 // 数字前置补零
digit: function(num, length){ digit: function(num, length){
var str = ''; var str = '';
@ -252,13 +252,13 @@ layui.define('jquery', function(exports){
} }
return num < Math.pow(10, length) ? str + (num|0) : num; return num < Math.pow(10, length) ? str + (num|0) : num;
}, },
// 转化为日期格式字符 // 转化为日期格式字符
toDateString: function(time, format, options){ toDateString: function(time, format, options){
// 若 null 或空字符,则返回空字符 // 若 null 或空字符,则返回空字符
if(time === null || time === '') return ''; if(time === null || time === '') return '';
// 引用自 dayjs // 引用自 dayjs
// https://github.com/iamkun/dayjs/blob/v1.11.9/src/constant.js#L30 // https://github.com/iamkun/dayjs/blob/v1.11.9/src/constant.js#L30
var REGEX_FORMAT = /\[([^\]]+)]|y{1,4}|M{1,2}|d{1,2}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|SSS/g; var REGEX_FORMAT = /\[([^\]]+)]|y{1,4}|M{1,2}|d{1,2}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|SSS/g;
var that = this; var that = this;
@ -267,7 +267,7 @@ layui.define('jquery', function(exports){
return isNaN(time) ? time : (typeof time === 'string' ? parseInt(time) : time) return isNaN(time) ? time : (typeof time === 'string' ? parseInt(time) : time)
}() || new Date()) }() || new Date())
if(!date.getDate()) return hint.error('Invalid Msec for "util.toDateString(Msec)"'), ''; if(!date.getDate()) return hint.error('Invalid millisecond for "util.toDateString(millisecond)"'), '';
var years = date.getFullYear(); var years = date.getFullYear();
var month = date.getMonth(); var month = date.getMonth();
@ -313,14 +313,14 @@ layui.define('jquery', function(exports){
ss: function(){return that.digit(seconds);}, ss: function(){return that.digit(seconds);},
SSS: function(){return that.digit(milliseconds, 3);} SSS: function(){return that.digit(milliseconds, 3);}
} }
format = format || 'yyyy-MM-dd HH:mm:ss'; format = format || 'yyyy-MM-dd HH:mm:ss';
return format.replace(REGEX_FORMAT, function(match, $1) { return format.replace(REGEX_FORMAT, function(match, $1) {
return $1 || (matches[match] && matches[match]()) || match; return $1 || (matches[match] && matches[match]()) || match;
}); });
}, },
// 转义 html // 转义 html
escape: function(html){ escape: function(html){
var exp = /[<"'>]|&(?=#[a-zA-Z0-9]+)/g; var exp = /[<"'>]|&(?=#[a-zA-Z0-9]+)/g;
@ -333,7 +333,7 @@ layui.define('jquery', function(exports){
.replace(/</g, '&lt;').replace(/>/g, '&gt;') .replace(/</g, '&lt;').replace(/>/g, '&gt;')
.replace(/'/g, '&#39;').replace(/"/g, '&quot;'); .replace(/'/g, '&#39;').replace(/"/g, '&quot;');
}, },
// 还原转义的 html // 还原转义的 html
unescape: function(html){ unescape: function(html){
if(html === undefined || html === null) html = ''; if(html === undefined || html === null) html = '';
@ -354,7 +354,7 @@ layui.define('jquery', function(exports){
win.document.write(options.content || ''); win.document.write(options.content || '');
win.document.close(); win.document.close();
}, },
// 让指定的元素保持在可视区域 // 让指定的元素保持在可视区域
toVisibleArea: function(options){ toVisibleArea: function(options){
options = $.extend({ options = $.extend({
@ -362,9 +362,9 @@ layui.define('jquery', function(exports){
duration: 200, // 动画持续毫秒数 duration: 200, // 动画持续毫秒数
type: 'y' // 触发方向x 水平、y 垂直 type: 'y' // 触发方向x 水平、y 垂直
}, options); }, options);
if(!options.scrollElem[0] || !options.thisElem[0]) return; if(!options.scrollElem[0] || !options.thisElem[0]) return;
var scrollElem = options.scrollElem // 滚动元素 var scrollElem = options.scrollElem // 滚动元素
var thisElem = options.thisElem // 目标元素 var thisElem = options.thisElem // 目标元素
var vertical = options.type === 'y' // 是否垂直方向 var vertical = options.type === 'y' // 是否垂直方向
@ -372,29 +372,29 @@ layui.define('jquery', function(exports){
var OFFSET_NAME = vertical ? 'top' : 'left' // 坐标方式 var OFFSET_NAME = vertical ? 'top' : 'left' // 坐标方式
var scrollValue = scrollElem[SCROLL_NAME]() // 当前滚动距离 var scrollValue = scrollElem[SCROLL_NAME]() // 当前滚动距离
var size = scrollElem[vertical ? 'height' : 'width']() // 滚动元素的尺寸 var size = scrollElem[vertical ? 'height' : 'width']() // 滚动元素的尺寸
var scrollOffet = scrollElem.offset()[OFFSET_NAME] // 滚动元素所处位置 var scrollOffset = scrollElem.offset()[OFFSET_NAME] // 滚动元素所处位置
var thisOffset = thisElem.offset()[OFFSET_NAME] - scrollOffet // 目标元素当前的所在位置 var thisOffset = thisElem.offset()[OFFSET_NAME] - scrollOffset // 目标元素当前的所在位置
var obj = {}; var obj = {};
// 边界满足条件 // 边界满足条件
if(thisOffset > size - options.margin || thisOffset < options.margin){ if(thisOffset > size - options.margin || thisOffset < options.margin){
obj[SCROLL_NAME] = thisOffset - size/2 + scrollValue obj[SCROLL_NAME] = thisOffset - size/2 + scrollValue
scrollElem.animate(obj, options.duration); scrollElem.animate(obj, options.duration);
} }
}, },
// 批量事件 // 批量事件
event: function(attr, obj, eventType){ event: function(attr, obj, eventType){
var _body = $('body'); var _body = $('body');
eventType = eventType || 'click'; eventType = eventType || 'click';
// 记录事件回调集合 // 记录事件回调集合
obj = util.event[attr] = $.extend(true, util.event[attr], obj) || {}; obj = util.event[attr] = $.extend(true, util.event[attr], obj) || {};
// 清除委托事件 // 清除委托事件
util.event.UTIL_EVENT_CALLBACK = util.event.UTIL_EVENT_CALLBACK || {}; util.event.UTIL_EVENT_CALLBACK = util.event.UTIL_EVENT_CALLBACK || {};
_body.off(eventType, '*['+ attr +']', util.event.UTIL_EVENT_CALLBACK[attr]) _body.off(eventType, '*['+ attr +']', util.event.UTIL_EVENT_CALLBACK[attr])
// 绑定委托事件 // 绑定委托事件
util.event.UTIL_EVENT_CALLBACK[attr] = function(){ util.event.UTIL_EVENT_CALLBACK[attr] = function(){
var othis = $(this); var othis = $(this);
@ -404,13 +404,13 @@ layui.define('jquery', function(exports){
// 清除旧事件,绑定新事件 // 清除旧事件,绑定新事件
_body.on(eventType, '*['+ attr +']', util.event.UTIL_EVENT_CALLBACK[attr]); _body.on(eventType, '*['+ attr +']', util.event.UTIL_EVENT_CALLBACK[attr]);
return obj; return obj;
} }
}; };
util.on = util.event; util.on = util.event;
// 输出接口 // 输出接口
exports('util', util); exports('util', util);
}); });