Support disabling items
parent
a3d1438243
commit
2e3f6a7ed4
|
@ -1,5 +1,5 @@
|
|||
// Menu-like Picker variant with keyboard control
|
||||
// Version 2021-08-20
|
||||
// Version 2021-08-30
|
||||
// License: LGPLv3.0+
|
||||
// (c) Vitaliy Filippov 2020+
|
||||
|
||||
|
@ -25,6 +25,8 @@ export default class PickerMenu extends Picker
|
|||
keepOnClick: PropTypes.bool,
|
||||
// menuitem name key - default empty (render the item itself)
|
||||
labelKey: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||
// menuitem "disabled" key - default none
|
||||
disabledKey: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||
// change theme (CSS module) for this input
|
||||
theme: PropTypes.object,
|
||||
}
|
||||
|
@ -34,11 +36,24 @@ export default class PickerMenu extends Picker
|
|||
if ((ev.which == 40 || ev.which == 38) && this.props.items.length)
|
||||
{
|
||||
// up / down
|
||||
this.setState({
|
||||
active: this.state.active == null ? 0 : (
|
||||
(this.state.active + (event.which === 40 ? 1 : this.props.items.length-1)) % this.props.items.length
|
||||
),
|
||||
});
|
||||
const dir = (event.which === 40 ? 1 : -1);
|
||||
let prev = this.state.active, active;
|
||||
if (prev == null)
|
||||
active = dir == 1 ? 0 : this.props.items.length-1;
|
||||
else
|
||||
active = (prev + this.props.items.length - dir) % this.props.items.length;
|
||||
if (this.props.disabledKey)
|
||||
{
|
||||
while (this.props.items[active][this.props.disabledKey] && active != prev)
|
||||
{
|
||||
active = (active + this.props.items.length - dir) % this.props.items.length;
|
||||
}
|
||||
if (this.props.items[active][this.props.disabledKey])
|
||||
{
|
||||
active = null;
|
||||
}
|
||||
}
|
||||
this.setState({ active });
|
||||
if (!this.state.focused)
|
||||
{
|
||||
this.focus();
|
||||
|
@ -87,13 +102,14 @@ export default class PickerMenu extends Picker
|
|||
onMouseOver = (ev) =>
|
||||
{
|
||||
let e = ev.target;
|
||||
while (e && e != ev.currentTarget && !e.id)
|
||||
while (e && e != ev.currentTarget && !e.getAttribute('data-idx'))
|
||||
{
|
||||
e = e.parentNode;
|
||||
}
|
||||
if (e && e.id)
|
||||
if (e && e.getAttribute('data-idx') &&
|
||||
(!this.props.disabledKey || !this.props.items[e.getAttribute('data-idx')][this.props.disabledKey]))
|
||||
{
|
||||
this.setState({ active: e.id });
|
||||
this.setState({ active: e.getAttribute('data-idx') });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -140,8 +156,10 @@ export default class PickerMenu extends Picker
|
|||
onKeyDown={this.onKeyDown}
|
||||
onMouseOver={this.onMouseOver}>
|
||||
{this.props.beforeItems}
|
||||
{this.props.items.map((e, i) => (<div key={i} id={i} onMouseDown={this.onMouseDown}
|
||||
className={theme.suggestion+(this.state.active == i ? ' '+theme.active : '')}>
|
||||
{this.props.items.map((e, i) => (<div key={i} data-idx={i} onMouseDown={this.onMouseDown}
|
||||
className={theme.suggestion+
|
||||
(this.props.disabledKey && e[this.props.disabledKey] ? ' '+theme.disabled : '')+
|
||||
(this.state.active == i ? ' '+theme.active : '')}>
|
||||
{!this.props.labelKey ? e : e[this.props.labelKey]}
|
||||
</div>))}
|
||||
{this.props.afterItems}
|
||||
|
|
10
Selectbox.js
10
Selectbox.js
|
@ -1,5 +1,5 @@
|
|||
// Simple Dropdown/Autocomplete with single/multiple selection and easy customisation via CSS modules
|
||||
// Version 2021-08-25
|
||||
// Version 2021-08-30
|
||||
// License: LGPLv3.0+
|
||||
// (c) Vitaliy Filippov 2019+
|
||||
|
||||
|
@ -32,6 +32,8 @@ export default class Selectbox extends React.PureComponent
|
|||
textKey: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||
// item id key - default "id"
|
||||
valueKey: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||
// item "disabled" key - default none
|
||||
disabledKey: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||
// automatically filter autocomplete options based on user input if `true`
|
||||
suggestionMatch: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['disabled'])]),
|
||||
// additional message to display below autocomplete options (arbitrary HTML, for example "...")
|
||||
|
@ -105,6 +107,11 @@ export default class Selectbox extends React.PureComponent
|
|||
this.picker.blur();
|
||||
}
|
||||
const sel = item[this.props.valueKey||'id'];
|
||||
if (this.props.disabledKey && item[this.props.disabledKey])
|
||||
{
|
||||
// item is disabled
|
||||
return;
|
||||
}
|
||||
let value = sel;
|
||||
if (this.props.multiple)
|
||||
{
|
||||
|
@ -279,6 +286,7 @@ export default class Selectbox extends React.PureComponent
|
|||
renderInput={this.renderInput}
|
||||
items={this.filtered_items}
|
||||
labelKey={this.props.labelKey||'name'}
|
||||
disabledKey={this.props.disabledKey}
|
||||
afterItems={this.props.suggestionMsg}
|
||||
onSelectItem={this.onSelectItem}
|
||||
/>);
|
||||
|
|
|
@ -75,6 +75,12 @@
|
|||
cursor: pointer;
|
||||
}
|
||||
|
||||
.suggestion.disabled
|
||||
{
|
||||
color: #aaa;
|
||||
background: #f4f6f8;
|
||||
}
|
||||
|
||||
.suggestion.active
|
||||
{
|
||||
background: #d6e8f6;
|
||||
|
|
Loading…
Reference in New Issue