This commit is contained in:
maplemei 2019-10-17 21:21:39 +08:00
parent 9416e64e7e
commit de672117e1
19 changed files with 257 additions and 70 deletions

View File

@ -1,5 +1,20 @@
## 更新日志 ## 更新日志
### 1.0.9
*2019-10-17*
#### 新增
- 新增`size`尺寸设置, `large`, `medium`, `small`, `mini`
- 新增`warning`方法, 可以闪烁边框提示
- 新增搜索完成回调参数, `list`:当前过滤后的数据
#### Bug fixes
- 修复远程搜索模式下 搜索完成回调错误
### 1.0.8 ### 1.0.8
*2019-10-16* *2019-10-16*

2
dist/static/2.js vendored

File diff suppressed because one or more lines are too long

2
dist/static/3.js vendored

File diff suppressed because one or more lines are too long

4
dist/static/docs.js vendored

File diff suppressed because one or more lines are too long

2
dist/xm-select.js vendored

File diff suppressed because one or more lines are too long

View File

@ -178,6 +178,11 @@ button, input, select, textarea {
display: inline-block; display: inline-block;
width: 300px; width: 300px;
} }
.xm-select-size{
vertical-align: top;
display: inline-block;
width: 150px;
}
.xm-select-demo-alert:extend(.xm-select-demo){ .xm-select-demo-alert:extend(.xm-select-demo){
margin: 20px; margin: 20px;
} }

View File

@ -168,8 +168,8 @@ var demo5 = xmSelect.render({
var demo6 = xmSelect.render({ var demo6 = xmSelect.render({
el: '#demo6', el: '#demo6',
filterable: true, filterable: true,
filterDone: function(val){ filterDone: function(val, list){
alert('搜索完毕') alert(`搜索完毕, 搜索关键词: ${val}, 过滤数据: ${list.length}个`)
}, },
data: [ data: [
{name: '水果', value: 1}, {name: '水果', value: 1},

61
docs/mds/XM24.md Normal file
View File

@ -0,0 +1,61 @@
## 尺寸
### 四种尺寸变换
:::demo `large`, `medium`, `small`, `mini`
```html
<div id="demo1" class="xm-select-size"></div>
<div id="demo2" class="xm-select-size"></div>
<div id="demo3" class="xm-select-size"></div>
<div id="demo4" class="xm-select-size"></div>
<script>
var demo1 = xmSelect.render({
el: '#demo1',
size: 'large',
data: [
{name: 'large', value: 1, selected: true},
{name: '李四1', value: 2},
{name: '王五1', value: 3, disabled: true},
{name: '苹果2', value: 4},
]
})
var demo2 = xmSelect.render({
el: '#demo2',
size: 'medium',
data: [
{name: 'medium', value: 1, selected: true},
{name: '李四1', value: 2},
{name: '默认尺寸', value: 3, selected: true, disabled: true},
{name: '苹果2', value: 4},
]
})
var demo3 = xmSelect.render({
el: '#demo3',
size: 'small',
data: [
{name: 'small', value: 1, selected: true},
{name: '李四1', value: 2},
{name: '王五1', value: 3, disabled: true},
{name: '苹果2', value: 4},
]
})
var demo4 = xmSelect.render({
el: '#demo4',
size: 'mini',
data: [
{name: 'mini', value: 1, selected: true},
{name: '李四1', value: 2},
{name: '王五1', value: 3, disabled: true},
{name: '苹果2', value: 4},
]
})
</script>
```
:::

55
docs/mds/XM25.md Normal file
View File

@ -0,0 +1,55 @@
## 警告
### 警告提示
放下她, 让我来!!! 默认颜色`#e54d42`, 多选上限的样色
:::demo
```html
<div id="demo1" class="xm-select-demo"></div>
<button class="btn" id="demo1-warning">警告</button>
<script>
var demo1 = xmSelect.render({
el: '#demo1',
data: [
{name: '张三', value: 1, selected: true},
{name: '李四', value: 2},
{name: '王五', value: 3, disabled: true},
]
})
document.getElementById('demo1-warning').onclick = function(){
demo1.warning();
}
</script>
```
:::
### 自定义闪烁颜色
:::demo
```html
<div id="demo2" class="xm-select-demo"></div>
<button class="btn" id="demo2-warning">警告</button>
<script>
var demo2 = xmSelect.render({
el: '#demo2',
data: [
{name: '张三', value: 1, selected: true},
{name: '李四', value: 2},
{name: '王五', value: 3, disabled: true},
]
})
document.getElementById('demo2-warning').onclick = function(){
demo2.warning('#6739b6');
}
</script>
```
:::

View File

@ -85,22 +85,15 @@ var demo2 = xmSelect.render({
document.getElementById('demo2-getValue').onclick = function(){ document.getElementById('demo2-getValue').onclick = function(){
//获取当前多选选中的值 //获取当前多选选中的值
var selectArr = demo2.getValue(); var selectArr = demo2.getValue();
document.getElementById('demo2-value').innerHTML = JSON.stringify(selectArr, null, 2); document.getElementById('demo2-value').innerHTML = `\ndemo2.getValue()\n\n` + JSON.stringify(selectArr, null, 2);
} }
document.getElementById('name').onclick = function(){
//获取当前多选选中的值
var selectArr = demo2.getValue('name');
document.getElementById('demo2-value').innerHTML = JSON.stringify(selectArr, null, 2);
}
var types = ['name', 'nameStr', 'value', 'valueStr']; var types = ['name', 'nameStr', 'value', 'valueStr'];
types.forEach(function(type){ types.forEach(function(type){
document.getElementById(type).onclick = function(){ document.getElementById(type).onclick = function(){
//获取当前多选选中的值 //获取当前多选选中的值
var selectArr = demo2.getValue(type); var selectArr = demo2.getValue(type);
document.getElementById('demo2-value').innerHTML = JSON.stringify(selectArr, null, 2); document.getElementById('demo2-value').innerHTML = `\ndemo2.getValue('${type}')\n\n` + JSON.stringify(selectArr, null, 2);
} }
}); });

View File

@ -5,31 +5,32 @@
<div id="demo1"></div> <div id="demo1"></div>
<script> <script>
var demo1 = xmSelect.render({ var demo1 = xmSelect.render({
el: '#demo1', el: '#demo1',
autoRow: true, autoRow: true,
toolbar: { show: true }, toolbar: { show: true },
filterable: true, filterable: true,
remoteSearch: true, remoteSearch: true,
remoteMethod: function(val, cb, show){ remoteMethod: function(val, cb, show){
//这里如果val为空, 则不触发搜索 //这里如果val为空, 则不触发搜索
if(!val){ if(!val){
return cb([]); return cb([]);
} }
axios({ //这里引入了一个第三方插件axios, 相当于$.ajax
method: 'get', axios({
url: 'https://www.fastmock.site/mock/98228b1f16b7e5112d6c0c87921eabc1/xmSelect/search', method: 'get',
params: { url: 'https://www.fastmock.site/mock/98228b1f16b7e5112d6c0c87921eabc1/xmSelect/search',
keyword: val, params: {
} keyword: val,
}).then(response => { }
var res = response.data; }).then(response => {
cb(res.data) var res = response.data;
}).catch(err => { cb(res.data)
cb([]); }).catch(err => {
}); cb([]);
}, });
}) },
})
</script> </script>
``` ```
::: :::

View File

@ -15,7 +15,7 @@
| searchTips | 搜索提示 | string | - | 请选择 | | searchTips | 搜索提示 | string | - | 请选择 |
| delay | 搜索延迟 ms | int | - | 500 | | delay | 搜索延迟 ms | int | - | 500 |
| filterMethod | 搜索回调函数 | function(val, item, index, prop) val: 当前搜索值, item: 每个option选项, index: 位置数据中的下标, prop: 定义key | - | - | | filterMethod | 搜索回调函数 | function(val, item, index, prop) val: 当前搜索值, item: 每个option选项, index: 位置数据中的下标, prop: 定义key | - | - |
| filterDone | 搜索完成函数 | function(val) val: 当前搜索值 | - | - | | filterDone | 搜索完成函数 | function(val, list) val: 当前搜索值, list: 过滤后的数据 | - | - |
| remoteSearch | 是否开启自定义搜索 (远程搜索)| boolean | true / false | false | | remoteSearch | 是否开启自定义搜索 (远程搜索)| boolean | true / false | false |
| remoteMethod | 自定义搜索回调函数 | function(val, cb, show) val: 当前搜索值, cb: 回调函数, 需要回调一个数组, 结构同data, show: 下拉框显示状态 | - | - | | remoteMethod | 自定义搜索回调函数 | function(val, cb, show) val: 当前搜索值, cb: 回调函数, 需要回调一个数组, 结构同data, show: 下拉框显示状态 | - | - |
| direction | 下拉方向| string | auto / up / down | auto | | direction | 下拉方向| string | auto / up / down | auto |
@ -39,6 +39,7 @@
| toolbar | 工具条, 具体看下表 | object | - | - | | toolbar | 工具条, 具体看下表 | object | - | - |
| showCount | 展示在下拉框中的最多选项数量 | int | - | 0 | | showCount | 展示在下拉框中的最多选项数量 | int | - | 0 |
| autoRow | 是否开启自动换行(选项过多时) | boolean | - | false | | autoRow | 是否开启自动换行(选项过多时) | boolean | - | false |
| size | 尺寸 | string | large / medium / small / mini | medium |
### prop ### prop
@ -177,3 +178,4 @@ xmSelect.render()后会返回一个xmSelect对象, 可以进行方法调用
| closed | 主动关闭下拉 | - | | closed | 主动关闭下拉 | - |
| reset | 重置为上一次的render状态 | - | | reset | 重置为上一次的render状态 | - |
| update | 更新多选选中, reset不保留 | (options: 见配置项) | | update | 更新多选选中, reset不保留 | (options: 见配置项) |
| warning | 警告 | (color: 默认同theme.maxColor) |

View File

@ -69,6 +69,8 @@ export default [{
{ path: '/example/XM21', name: 'Optgroup 分组', component: importMd('/XM21') }, { path: '/example/XM21', name: 'Optgroup 分组', component: importMd('/XM21') },
{ path: '/example/XM22', name: 'AutoRow 自动换行', component: importMd('/XM22') }, { path: '/example/XM22', name: 'AutoRow 自动换行', component: importMd('/XM22') },
{ path: '/example/XM23', name: 'HiddenIcon 隐藏图标', component: importMd('/XM23') }, { path: '/example/XM23', name: 'HiddenIcon 隐藏图标', component: importMd('/XM23') },
{ path: '/example/XM24', name: 'Size 尺寸', component: importMd('/XM24') },
{ path: '/example/XM25', name: 'Warning 警告', component: importMd('/XM25') },
] ]
}, { }, {
path: '/example-custom', path: '/example-custom',

View File

@ -1,6 +1,6 @@
{ {
"name": "xm-select", "name": "xm-select",
"version": "1.0.7", "version": "1.0.9",
"description": "始于Layui的select多选解决方案", "description": "始于Layui的select多选解决方案",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {

View File

@ -11,6 +11,8 @@ export default function (lan = 'zn') {
data: [], data: [],
//表单提交的name //表单提交的name
name: 'select', name: 'select',
//尺寸
size: 'medium',
//默认选中数据, 优先级大于selected //默认选中数据, 优先级大于selected
initValue: null, initValue: null,
//默认提示 //默认提示

View File

@ -147,6 +147,14 @@ class xmOptions {
return this; return this;
} }
/**
* 闪烁警告边框
*/
warning(color){
childs[this.options.el].updateBorderColor(color || this.options.theme.maxColor);
return this;
}
} }
export default xmOptions; export default xmOptions;

View File

@ -176,7 +176,7 @@ class Framework extends Component{
render(config, { sels, show }) { render(config, { sels, show }) {
const { tips, theme, prop, style, radio, repeat, clickClose, on, max, maxMethod } = config; const { tips, theme, prop, style, radio, repeat, clickClose, on, max, maxMethod } = config;
const borderStyle = { borderColor: this.state.tmpColor || theme.color }; const borderStyle = { borderColor: theme.color };
//最外层边框的属性 //最外层边框的属性
const xmSelectProps = { const xmSelectProps = {
style: { style: {
@ -185,7 +185,16 @@ class Framework extends Component{
}, },
onClick: this.onClick.bind(this), onClick: this.onClick.bind(this),
ua: checkUserAgent(), ua: checkUserAgent(),
size: config.size,
} }
if(this.state.tmpColor){
xmSelectProps.style.borderColor = this.state.tmpColor;
setTimeout(() => {
xmSelectProps.style.borderColor = '';
this.updateBorderColor('')
}, 300);
}
//右边下拉箭头的变化class //右边下拉箭头的变化class
const iconClass = show ? 'xm-icon xm-icon-expand' : 'xm-icon'; const iconClass = show ? 'xm-icon xm-icon-expand' : 'xm-icon';
//提示信息的属性 //提示信息的属性
@ -214,8 +223,6 @@ class Framework extends Component{
let maxCount = toNum(max); let maxCount = toNum(max);
if(maxCount > 0 && sels.length >= maxCount){ if(maxCount > 0 && sels.length >= maxCount){
this.updateBorderColor(theme.maxColor); this.updateBorderColor(theme.maxColor);
//恢复正常
setTimeout(() => this.updateBorderColor(''), 300);
//查看是否需要回调 //查看是否需要回调
maxMethod && isFunction(maxMethod) && maxMethod(sels, item); maxMethod && isFunction(maxMethod) && maxMethod(sels, item);
return ; return ;

View File

@ -81,11 +81,10 @@ class General extends Component{
this.__value = v; this.__value = v;
//让搜索变成异步的 //让搜索变成异步的
this.searchCid = setTimeout(() => this.setState({ this.searchCid = setTimeout(() => {
filterValue: this.__value, this.callback = true;
remote: true, this.setState({ filterValue: this.__value, remote: true })
callback: true, }, this.props.delay);
}), this.props.delay);
} }
} }
@ -124,12 +123,12 @@ class General extends Component{
} }
componentDidUpdate(){ componentDidUpdate(){
if(this.state.callback){ if(this.callback){
this.setState({ callback: false }); this.callback = false;
let done = this.props.filterDone; let done = this.props.filterDone;
if(isFunction(done)){ if(isFunction(done)){
done(this.state.filterValue); done(this.state.filterValue, this.tempData || []);
} }
} }
} }
@ -145,6 +144,7 @@ class General extends Component{
if(filterable){ if(filterable){
if(remoteSearch){//是否进行远程搜索 if(remoteSearch){//是否进行远程搜索
if(this.state.remote){ if(this.state.remote){
this.callback = false;
this.setState({ loading: true, remote: false }); this.setState({ loading: true, remote: false });
//让输入框失去焦点 //让输入框失去焦点
this.blur(); this.blur();
@ -152,6 +152,7 @@ class General extends Component{
//回调后可以重新聚焦 //回调后可以重新聚焦
this.focus(); this.focus();
this.callback = true;
this.setState({ loading: false }); this.setState({ loading: false });
this.props.onReset(result, 'data'); this.props.onReset(result, 'data');
}, this.props.show); }, this.props.show);
@ -260,6 +261,7 @@ class General extends Component{
} }
let safetyArr = deepMerge([], arr); let safetyArr = deepMerge([], arr);
this.tempData = safetyArr;
//工具条操作 //工具条操作
const toolbar = ( const toolbar = (
@ -302,8 +304,7 @@ class General extends Component{
const selected = !!sels.find(sel => sel[value] == item[value]) const selected = !!sels.find(sel => sel[value] == item[value])
const iconStyle = selected ? { const iconStyle = selected ? {
color: theme.color, color: theme.color,
border: 'none', border: 'none'
fontSize: '18px'
} : { } : {
borderColor: theme.color, borderColor: theme.color,
}; };

View File

@ -2,8 +2,6 @@
@defaultBorderColor: #E6E6E6; @defaultBorderColor: #E6E6E6;
@disabledColor: #C2C2C2; @disabledColor: #C2C2C2;
@border: 1px solid @defaultBorderColor; @border: 1px solid @defaultBorderColor;
@height: 36px;
@heightLabel: 30px;
@-webkit-keyframes xm-upbit { @-webkit-keyframes xm-upbit {
from {-webkit-transform: translate3d(0, 30px, 0);opacity: .3} from {-webkit-transform: translate3d(0, 30px, 0);opacity: .3}
@ -54,8 +52,6 @@ xm-select{
position: relative; position: relative;
border: @border; border: @border;
border-radius: 2px; border-radius: 2px;
min-height: @height;
line-height: @height;
display: block; display: block;
width: 100%; width: 100%;
cursor: pointer; cursor: pointer;
@ -117,7 +113,6 @@ xm-select{
.scroll{ .scroll{
.label-content{ .label-content{
display: flex; display: flex;
line-height: @heightLabel;
padding: 3px 30px 3px 10px; padding: 3px 30px 3px 10px;
} }
} }
@ -127,8 +122,6 @@ xm-select{
position: relative; position: relative;
padding: 0px 5px; padding: 0px 5px;
margin: 2px 5px 2px 0; margin: 2px 5px 2px 0;
height: 26px;
line-height: 26px;
border-radius: 3px; border-radius: 3px;
align-items: baseline; align-items: baseline;
color: #FFF; color: #FFF;
@ -196,8 +189,10 @@ xm-select{
} }
.xm-group{ .xm-group{
cursor: default;
&-item{ &-item{
cursor: default; display: inline-block;
cursor: pointer;
padding: 0 10px; padding: 0 10px;
color: #999; color: #999;
font-size: 12px; font-size: 12px;
@ -219,8 +214,6 @@ xm-select{
display: flex; display: flex;
border: @border; border: @border;
border-radius: 3px; border-radius: 3px;
height: 18px;
width: 18px;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
} }
@ -306,8 +299,6 @@ xm-select{
justify-content: center; justify-content: center;
vertical-align: middle; vertical-align: middle;
padding: 0 15px; padding: 0 15px;
height: 28px;
line-height: 28px;
margin: 0 -1px 0 0; margin: 0 -1px 0 0;
background-color: #fff; background-color: #fff;
color: #333; color: #333;
@ -358,7 +349,6 @@ xm-select{
width: 100%; width: 100%;
box-sizing: border-box; box-sizing: border-box;
background-color: #FFF; background-color: #FFF;
height: 36px;
line-height: 1.3; line-height: 1.3;
padding-left: 10px; padding-left: 10px;
outline: 0; outline: 0;
@ -402,6 +392,51 @@ xm-select{
} }
//不同尺寸下的数据调整
.mixin(@size){
@height: @size;
@heightLabel: @height - 6px;
@heightItem: @heightLabel - 4px;
@iconSize: @size / 2;
min-height: @height;
line-height: @height;
.xm-input{
height: @height;
}
.xm-label{
.scroll .label-content{
line-height: @heightLabel;
}
.xm-label-block{
height: @heightItem;
line-height: @heightItem;
}
}
.xm-body .xm-option .xm-option-icon{
height: @iconSize;
width: @iconSize;
font-size: @iconSize;
}
.xm-paging>span{
height: @heightLabel;
line-height: @heightLabel;
}
}
xm-select[size='large']{
.mixin(40px)
}
xm-select{//[size='medium']
.mixin(36px)
}
xm-select[size='small']{
.mixin(32px)
}
xm-select[size='mini']{
.mixin(28px)
}
//layui的一些样式兼容 //layui的一些样式兼容
.layui-form-pane{ .layui-form-pane{
xm-select{ xm-select{