单选图标自定义
可以把搜索框放置到label上
修改update方法无法更新远程
This commit is contained in:
maplemei 2020-07-31 12:11:39 +08:00
parent 369ae57b85
commit 6b24d608ee
10 changed files with 85 additions and 47 deletions

2
dist/static/2.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

@ -8,31 +8,30 @@
var demo1 = xmSelect.render({ var demo1 = xmSelect.render({
el: '#demo1', el: '#demo1',
autoRow: true, autoRow: true,
height: '300px', toolbar: { show: true },
radio: true,
tree: {
show: false,
simple: true,
expandedKeys: [-1],
},
toolbar: {
show: true,
list: ['ALL', 'REVERSE', 'CLEAR']
},
filterable: true,
paging: true, paging: true,
pageRemote: true, pageRemote: true,
filterable: true,
remoteSearch: true, remoteSearch: true,
remoteMethod(val, cb, show, pageIndex){ remoteMethod: function(val, cb, show){
cb([ //这里如果val为空, 则不触发搜索
{name: '张三11111111111', value: 1, selected: true, children: []}, /* if(!val){
{name: '李四1', value: 2, selected: true}, return cb([]);
{name: '王五1', value: 3, disabled: false}, } */
]) //这里引入了一个第三方插件axios, 相当于$.ajax
}, axios({
data(){ method: 'get',
return [] url: 'https://www.fastmock.site/mock/98228b1f16b7e5112d6c0c87921eabc1/xmSelect/search',
params: {
keyword: val,
} }
}).then(response => {
var res = response.data;
cb(res.data, 80)
}).catch(err => {
cb([]);
});
},
}) })
</script> </script>

View File

@ -27,7 +27,7 @@
"markdown-it-anchor": "^5.2.4", "markdown-it-anchor": "^5.2.4",
"markdown-it-chain": "^1.3.0", "markdown-it-chain": "^1.3.0",
"markdown-it-container": "^2.0.0", "markdown-it-container": "^2.0.0",
"preact": "^10.0.5", "preact": "^10.4.6",
"style-loader": "^0.23.1", "style-loader": "^0.23.1",
"transliteration": "^2.1.7", "transliteration": "^2.1.7",
"url-loader": "^2.1.0", "url-loader": "^2.1.0",

View File

@ -314,6 +314,14 @@ class Framework extends Component{
//重置class //重置class
if(type === 'class'){ if(type === 'class'){
this.setState({ bodyClass: data }) this.setState({ bodyClass: data })
}else
//聚焦label搜索框
if(type === 'labelSearchBlur'){
this.labelView.blur(data);
}else
//聚焦label搜索框
if(type === 'labelSearch'){
this.generalView.labelSearch(data);
} }
} }
@ -379,18 +387,18 @@ class Framework extends Component{
//普通多选数据 //普通多选数据
const valueProp = prop.value; const valueProp = prop.value;
const labelProps = { ...config, data, sels, ck: this.itemClick.bind(this), title: sels.map(sel => sel[prop.name]).join(',') } const labelProps = { ...config, data, sels, ck: this.itemClick.bind(this), title: sels.map(sel => sel[prop.name]).join(','), onReset: this.onReset.bind(this) }
const bodyProps = { ...config, data, dataObj, flatData, sels, ck: this.itemClick.bind(this), show, onReset: this.onReset.bind(this) } const bodyProps = { ...config, data, dataObj, flatData, sels, ck: this.itemClick.bind(this), show, onReset: this.onReset.bind(this) }
//渲染组件 //渲染组件
let Body = content ? <Custom { ...bodyProps } /> : tree.show ? <Tree { ...bodyProps } /> : config.cascader.show ? <Cascader { ...bodyProps } /> : <General { ...bodyProps } />; let Body = content ? <Custom { ...bodyProps } /> : tree.show ? <Tree { ...bodyProps } /> : config.cascader.show ? <Cascader { ...bodyProps } /> : <General { ...bodyProps } ref={ ref => this.generalView = ref } />;
return ( return (
<xm-select { ...xmSelectProps } > <xm-select { ...xmSelectProps } >
<input class="xm-select-default" lay-verify={ config.layVerify } lay-verType={ config.layVerType } name={ config.name } value={ sels.map(item => item[prop.value]).join(',') }></input> <input class="xm-select-default" lay-verify={ config.layVerify } lay-verType={ config.layVerType } name={ config.name } value={ sels.map(item => item[prop.value]).join(',') }></input>
<i class={ show ? 'xm-icon xm-icon-expand' : 'xm-icon' } /> <i class={ show ? 'xm-icon xm-icon-expand' : 'xm-icon' } />
{ sels.length === 0 && <div class="xm-tips">{ config.tips }</div> } { sels.length === 0 && <div class="xm-tips">{ config.tips }</div> }
<Label { ...labelProps } /> <Label { ...labelProps } ref={ ref => this.labelView = ref } />
<div class={ ['xm-body', bodyClass, config.model.type, show ? '':'dis', ].join(' ') } ref={ ref => this.bodyView = ref}> <div class={ ['xm-body', bodyClass, config.model.type, show ? '':'dis', ].join(' ') } ref={ ref => this.bodyView = ref}>
{ Body } { Body }
</div> </div>

View File

@ -32,6 +32,11 @@ class Label extends Component{
} }
} }
blur(){
let input = this.base.querySelector('.label-search-input');
input && input.blur();
}
componentDidMount(){ componentDidMount(){
if (this.labelRef.addEventListener) { if (this.labelRef.addEventListener) {
this.labelRef.addEventListener('DOMMouseScroll', this.scrollFunc.bind(this), false); this.labelRef.addEventListener('DOMMouseScroll', this.scrollFunc.bind(this), false);
@ -97,6 +102,23 @@ class Label extends Component{
</div> </div>
) )
} }
}else if(type == 'search'){
innerHTML = false;
let one = list[0][name];
html = (
<input class="label-search-input" type="text" placeholder={ config.searchTips } style={{ width: '100%', border: 'none' }} value={
one
} onInput={ e => {
this.props.onReset(e, 'labelSearch')
}} onCompositionstart={ e => {
this.props.onReset(e, 'labelSearch')
}} compositionupdate={ e => {
this.props.onReset(e, 'labelSearch')
}} compositionend={ e => {
this.props.onReset(e, 'labelSearch')
}}></input>
)
}else{ }else{
if(list.length && conf && conf.template){ if(list.length && conf && conf.template){
html = conf.template(data, list); html = conf.template(data, list);

View File

@ -151,7 +151,7 @@ class Cascader extends Component{
} }
return ( return (
<div onClick={ this.blockClick } class="xm-body-cascader" style={{ width: cascader.indent + 'px', height: config.height }}> <div onClick={ this.blockClick } class="xm-body-cascader" style={{ width: cascader.indent + 'px', maxHeight: config.height }}>
{ arr } { arr }
</div> </div>
) )
@ -160,13 +160,10 @@ class Cascader extends Component{
//组件完成挂载 //组件完成挂载
componentDidMount(){ componentDidMount(){
this.props.onReset('cascader', 'class'); this.props.onReset('cascader', 'class');
} }
//此时页面又被重新渲染了 //此时页面又被重新渲染了
componentDidUpdate(){ // componentDidUpdate(){}
}
} }
export default Cascader; export default Cascader;

View File

@ -79,6 +79,14 @@ class General extends Component{
}) })
} }
labelSearch(e){
if(e.type == 'input'){
this.searchInput(e)
}else{
this.handleComposition(e)
}
}
searchInput(e){ searchInput(e){
let v = e.target.value; let v = e.target.value;
@ -86,7 +94,7 @@ class General extends Component{
return ; return ;
} }
clearTimeout(this.searchCid); this.searchCid && clearTimeout(this.searchCid);
if(this.inputOver){ if(this.inputOver){
//保证输入框内的值是实时的 //保证输入框内的值是实时的
this.__value = v; this.__value = v;
@ -112,7 +120,7 @@ class General extends Component{
if(type === 'compositionstart'){ if(type === 'compositionstart'){
this.inputOver = false; this.inputOver = false;
clearTimeout(this.searchCid); this.searchCid && clearTimeout(this.searchCid);
}else if(type === 'compositionend'){ }else if(type === 'compositionend'){
this.inputOver = true; this.inputOver = true;
this.searchInput(e); this.searchInput(e);
@ -203,10 +211,13 @@ class General extends Component{
this.setState({ filterValue: '', val: emptyVal }); this.setState({ filterValue: '', val: emptyVal });
this.__value = ''; this.__value = '';
this.searchInputRef && (this.searchInputRef.value = ''); this.searchInputRef && (this.searchInputRef.value = '');
this.props.onReset('', 'labelSearchBlur')
}else{ }else{
//聚焦输入框 //聚焦输入框
setTimeout(() => { setTimeout(() => {
if(props.filterable){ if(props.model.label.type === 'search'){
}else if(props.filterable){
this.focus() this.focus()
}else{ }else{
this.base.focus() this.base.focus()
@ -214,6 +225,9 @@ class General extends Component{
}, 0); }, 0);
} }
} }
if(this.props.__update != props.__update){
this.setState({ remote: true })
}
} }
render(config) { render(config) {
@ -256,7 +270,7 @@ class General extends Component{
} }
const search = ( const search = (
<div class={ filterable ? 'xm-search' : 'xm-search dis' }> <div class={ filterable && config.model.label.type != 'search' ? 'xm-search' : 'xm-search dis' }>
<i class="xm-iconfont xm-icon-sousuo"></i> <i class="xm-iconfont xm-icon-sousuo"></i>
<input class="xm-input xm-search-input" placeholder={ searchTips } /> <input class="xm-input xm-search-input" placeholder={ searchTips } />
</div> </div>
@ -449,8 +463,6 @@ class General extends Component{
return 0; return 0;
})() || ('xm-iconfont ' + (radio ? 'xm-icon-danx' : 'xm-icon-duox'))].join(' '); })() || ('xm-iconfont ' + (radio ? 'xm-icon-danx' : 'xm-icon-duox'))].join(' ');
console.log(iconClass)
//处理鼠标选择的背景色 //处理鼠标选择的背景色
const hoverChange = e => { const hoverChange = e => {
if(e.type === 'mouseenter'){ if(e.type === 'mouseenter'){

View File

@ -44,7 +44,7 @@ class xmOptions {
return ; return ;
} }
render(<Framework { ...this.options } updateData={ updateData } />, dom); render(<Framework { ...this.options } __update={ Date.now() } updateData={ updateData } />, dom);
//返回多选对象 //返回多选对象
return this; return this;

View File

@ -154,9 +154,9 @@ export default function (lan = 'zn') {
}, },
//自定义选中的图标 //自定义选中的图标
iconfont: { iconfont: {
select: 'layui-icon layui-icon-cellphone', select: '',
unselect: 'layui-icon layui-icon-cellphone', unselect: '',
half: 'xm-iconfont xm-icon-banxuan', half: '',
}, },
// 展开下拉框 // 展开下拉框
show(){ show(){