Skip to content

Commit 5b9ec84

Browse files
committed
put_buttons() support disabled button, button value can be any type
1 parent cb5ac8d commit 5b9ec84

File tree

3 files changed

+37
-18
lines changed

3 files changed

+37
-18
lines changed

docs/spec.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ Unique attributes of different types:
228228
* type: buttons
229229

230230
* callback_id:
231-
* buttons:[ {value:, label:, [color:]},...]
231+
* buttons:[ {value:, label:, [color:], [disabled:]},...]
232232
* small: bool, Whether to enable small button
233233
* group: bool, Whether to group the buttons together
234234
* link: bool, Whether to make button seem as link.

pywebio/output.py

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -660,17 +660,18 @@ def put_table(tdata, header=None, scope=None, position=OutputPosition.BOTTOM) ->
660660

661661
def _format_button(buttons):
662662
"""
663-
Format `buttons` parameter in `put_buttons()`
663+
Format `buttons` parameter in `put_buttons()`, replace its value with its idx
664664
:param buttons:
665665
{label:, value:, }
666666
(label, value, )
667667
single value, label=value
668668
669-
:return: [{value:, label:, }, ...]
669+
:return: [{value:, label:, }, ...], values
670670
"""
671671

672672
btns = []
673-
for btn in buttons:
673+
values = []
674+
for idx, btn in enumerate(buttons):
674675
btn = copy.deepcopy(btn)
675676
if isinstance(btn, Mapping):
676677
assert 'value' in btn and 'label' in btn, 'actions item must have value and label key'
@@ -679,8 +680,10 @@ def _format_button(buttons):
679680
btn = dict(zip(('label', 'value'), btn))
680681
else:
681682
btn = dict(value=btn, label=btn)
683+
values.append(btn['value'])
684+
btn['value'] = idx
682685
btns.append(btn)
683-
return btns
686+
return btns, values
684687

685688

686689
def put_buttons(buttons, onclick, small=None, link_style=False, outline=False, group=False, scope=None,
@@ -690,11 +693,19 @@ def put_buttons(buttons, onclick, small=None, link_style=False, outline=False, g
690693
691694
:param list buttons: Button list. The available formats of list items are:
692695
693-
* dict: ``{label:(str)button label, value:(str)button value, color:(str, optional)button color}``
696+
* dict::
697+
698+
{
699+
"label":(str)button label,
700+
"value":(str)button value,
701+
"color":(str, optional)button color,
702+
"disabled":(bool, optional) whether the button is disabled
703+
}
704+
694705
* tuple or list: ``(label, value)``
695706
* single value: label and value of option use the same value
696707
697-
The ``value`` of button can be any JSON serializable object.
708+
The ``value`` of button can be any type.
698709
The ``color`` of button can be one of: `primary`, `secondary`, `success`, `danger`, `warning`, `info`, `light`, `dark`.
699710
700711
Example:
@@ -760,19 +771,23 @@ def delete():
760771
put_text("You click delete button")
761772
762773
put_buttons(['edit', 'delete'], onclick=[edit, delete])
774+
775+
.. versionchanged:: 1.5
776+
Add ``disabled`` button support.
777+
The ``value`` of button can be any object.
763778
"""
764-
btns = _format_button(buttons)
779+
btns, values = _format_button(buttons)
765780

766781
if isinstance(onclick, Sequence):
767782
assert len(btns) == len(onclick), "`onclick` and `buttons` must be same length."
768-
for idx, btn in enumerate(btns):
769-
btn['value'] = idx
770783

771-
def click_callback(btn_val):
784+
def click_callback(btn_idx):
772785
if isinstance(onclick, Sequence):
773-
return onclick[btn_val]()
786+
onclick[btn_idx]()
774787
else:
775-
return onclick(btn_val)
788+
btn_val = values[btn_idx]
789+
if not btns[btn_idx].get('disabled'):
790+
onclick(btn_val)
776791

777792
callback_id = output_register_callback(click_callback, **callback_options)
778793
spec = _get_output_spec('buttons', callback_id=callback_id, buttons=btns, small=small,
@@ -781,14 +796,15 @@ def click_callback(btn_val):
781796
return Output(spec)
782797

783798

784-
def put_button(label, onclick, color=None, small=None, link_style=False, outline=False, scope=None,
799+
def put_button(label, onclick, color=None, small=None, link_style=False, outline=False, disabled=False, scope=None,
785800
position=OutputPosition.BOTTOM) -> Output:
786801
"""Output a single button and bind click event to it.
787802
788803
:param str label: Button label
789804
:param callable onclick: Callback which will be called when button is clicked.
790805
:param str color: The color of the button,
791806
can be one of: `primary`, `secondary`, `success`, `danger`, `warning`, `info`, `light`, `dark`.
807+
:param bool disabled: Whether the button is disabled
792808
:param - small, link_style, outline, scope, position: Those arguments have the same meaning as for `put_buttons()`
793809
794810
Example:
@@ -800,9 +816,13 @@ def put_button(label, onclick, color=None, small=None, link_style=False, outline
800816
put_button("click me", onclick=lambda: toast("Clicked"), color='success', outline=True)
801817
802818
.. versionadded:: 1.4
819+
820+
.. versionchanged:: 1.5
821+
add ``disabled`` parameter
803822
"""
804-
return put_buttons([{'label': label, 'value': '', 'color': color or 'primary'}], onclick=[onclick],
805-
small=small, link_style=link_style, outline=outline, scope=scope, position=position)
823+
return put_buttons([{'label': label, 'value': '', 'color': color or 'primary', 'disabled': disabled}],
824+
onclick=[onclick], small=small, link_style=link_style, outline=outline, scope=scope,
825+
position=position)
806826

807827

808828
def put_image(src, format=None, title='', width=None, height=None,

webiojs/src/models/output.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ let Buttons = {
8585
handle_type: 'buttons',
8686
get_element: function (spec: any) {
8787
const btns_tpl = `<div{{#group}} class="btn-group" role="group"{{/group}}>{{#buttons}}
88-
<button class="btn {{#color}}btn-{{#outline}}outline-{{/outline}}{{color}}{{/color}}{{#small}} btn-sm{{/small}}">{{label}}</button>
88+
<button class="btn {{#color}}btn-{{#outline}}outline-{{/outline}}{{color}}{{/color}}{{#small}} btn-sm{{/small}}" {{#disabled}}disabled{{/disabled}}>{{label}}</button>
8989
{{/buttons}}</div>`;
9090
spec.color = "primary"; // fallback color
9191
if (spec.link) {
@@ -226,7 +226,6 @@ let ScrollableWidget = {
226226
}).on('focusout mouseleave', function (e) {
227227
stop = false
228228
});
229-
console.log(container)
230229
new MutationObserver(function (mutations, observe) {
231230
if (!stop) container.stop().animate({scrollTop: container.prop("scrollHeight")}, 200);
232231
}).observe(container[0], {childList: true, subtree: true});

0 commit comments

Comments
 (0)