Parcourir la source

feat: add `pin.put_actions()`

wangweimin il y a 3 ans
Parent
commit
c5b2526675
3 fichiers modifiés avec 25 ajouts et 4 suppressions
  1. 19 2
      pywebio/pin.py
  2. 3 1
      test/18.pin_test.py
  3. 3 1
      webiojs/src/models/input/actions.ts

+ 19 - 2
pywebio/pin.py

@@ -86,6 +86,7 @@ The following is the difference between the two in parameters:
 .. autofunction:: put_checkbox
 .. autofunction:: put_radio
 .. autofunction:: put_slider
+.. autofunction:: put_actions
 
 Pin utils
 ------------------
@@ -128,8 +129,8 @@ from .session import next_client_event, chose_impl
 
 _html_value_chars = set(string.ascii_letters + string.digits + '_')
 
-__all__ = ['put_input', 'put_textarea', 'put_select', 'put_checkbox', 'put_radio', 'put_slider', 'pin', 'pin_update',
-           'pin_wait_change']
+__all__ = ['put_input', 'put_textarea', 'put_select', 'put_checkbox', 'put_radio', 'put_slider', 'put_actions',
+           'pin', 'pin_update', 'pin_wait_change']
 
 
 def check_name(name):
@@ -204,6 +205,22 @@ def put_slider(name, *, label='', value=0, min_value=0, max_value=100, step=1, r
     return _pin_output(single_input_return, scope, position)
 
 
+def put_actions(name, *, label='', buttons=None, help_text=None,
+                scope=Scope.Current, position=OutputPosition.BOTTOM) -> Output:
+    """Output a group of action button. Refer to: `pywebio.input.actions()`
+
+    Unlike the ``actions()``, ``put_actions()`` won't submit any form, it will only set the value of the pin widget.
+    Only 'submit' type button is available in pin widget version.
+    """
+    from pywebio.input import actions
+    check_name(name)
+    single_input_return = actions(name=name, label=label, buttons=buttons, help_text=help_text)
+    input_kwargs = single_input_kwargs(single_input_return)
+    for btn in input_kwargs['item_spec']['buttons']:
+        assert btn['type'] == 'submit', "The `put_actions()` pin widget only accept 'submit' type button."
+    return _pin_output(input_kwargs, scope, position)
+
+
 @chose_impl
 def get_client_val():
     res = yield next_client_event()

+ 3 - 1
test/18.pin_test.py

@@ -31,6 +31,7 @@ def target():
                  help_text='help_text')
     put_radio('radio', options=options, label='radio', inline=False, value=None, help_text='help_text')
     put_radio('radio_inline', options=options, label='radio_inline', inline=True, value='B', help_text='help_text')
+    put_actions('actions', buttons=['action_a', 'action_b'], label='actions')
 
     pin_update('input', help_text='This is help text')
     pin_update('select_multiple', value=['B', 'C'])
@@ -39,7 +40,7 @@ def target():
     assert (yield pin['radio']) == (yield pin.radio) == 'B'
 
     names = ['input', 'textarea', 'code', 'select', 'select_multiple', 'checkbox', 'checkbox_inline', 'radio',
-             'radio_inline']
+             'radio_inline', 'actions']
     values = {}
 
     while len(names) != len(values):
@@ -70,6 +71,7 @@ def test_one_page(browser: Chrome):
     browser.find_element_by_css_selector('[name=checkbox_inline]').click()
     browser.find_element_by_css_selector('[name=radio]').click()
     browser.find_element_by_css_selector('[name=radio_inline]').click()
+    browser.find_element_by_css_selector('button').click()
     codeMirror = browser.find_element_by_css_selector(".CodeMirror pre")
     action_chains = ActionChains(browser)
     action_chains.move_to_element(codeMirror).click(codeMirror).send_keys('3').perform()

+ 3 - 1
webiojs/src/models/input/actions.ts

@@ -34,8 +34,10 @@ export class Actions extends InputItem {
         this.element.find('button').on('click', function (e) {
             let btn = $(this);
             if (btn.data('type') === 'submit') {
-                that.submit_value = JSON.parse(btn.val() as string);
                 // 不可以使用 btn.parents('form').submit(), 会导致input 的required属性失效
+                that.submit_value = JSON.parse(btn.val() as string);
+                if(that.spec.onchange)  // the `onchange` of spec will be only set in pin widget
+                    that.on_input_event("change", that);
             } else if (btn.data('type') === 'reset') {
                 btn.parents('form').trigger("reset");
             } else if (btn.data('type') === 'cancel') {