Browse Source

output support bind onclick callback

wangweimin 3 years ago
parent
commit
5d0f53a42b
4 changed files with 26 additions and 7 deletions
  1. 4 0
      pywebio/html/css/app.css
  2. 12 0
      pywebio/io_ctrl.py
  3. 2 5
      pywebio/output.py
  4. 8 2
      webiojs/src/models/output.ts

+ 4 - 0
pywebio/html/css/app.css

@@ -284,4 +284,8 @@ details[open]>summary {
   top: 0; left: 0; right: 0; bottom: 0;
   height: auto;
   z-index: 9;
+}
+
+.pywebio-clickable{
+    cursor: pointer;
 }

+ 12 - 0
pywebio/io_ctrl.py

@@ -128,6 +128,8 @@ class Output:
     def style(self, css_style):
         """Set css style for output
 
+        :param str css_style: CSS style string
+
         Example::
 
             put_text('hello').style('color: red; font-size: 20px')
@@ -142,6 +144,16 @@ class Output:
         self.spec['style'] += ';%s' % css_style
         return self
 
+    def onclick(self, callback):
+        """Add click callback to this widget.
+
+        :param callable callback: Callback which will be called when the widget is clicked.
+        """
+        callback_id = output_register_callback(lambda _: callback())
+        self.spec.setdefault('click_callback_id', '')
+        self.spec['click_callback_id'] += callback_id
+        return self
+
     def __del__(self):
         """返回值没有被变量接收时的操作:直接输出消息"""
         if not self.processed:

+ 2 - 5
pywebio/output.py

@@ -148,7 +148,7 @@ Layout and Style
 
 Other
 --------------
-.. autofunction::  output
+.. autofunction:: output
 
 """
 import html
@@ -207,8 +207,6 @@ class Scope:
 _scope_name_allowed_chars = set(string.ascii_letters + string.digits + '_-')
 
 
-
-
 def set_scope(name, container_scope=Scope.Current, position=OutputPosition.BOTTOM, if_exist=None):
     """Create a new scope.
 
@@ -1015,8 +1013,7 @@ def put_scrollable(content=[], height=400, keep_bottom=False, horizon_scroll=Fal
     if not isinstance(content, (list, tuple, OutputList)):
         content = [content]
 
-    for item in content:
-        assert isinstance(item, (str, Output)), "put_scrollable() content must be list of str/put_xxx()"
+    content = [i if isinstance(i, Output) else put_text(i) for i in content]
 
     if 'max_height' in kwargs:
         import warnings

+ 8 - 2
webiojs/src/models/output.ts

@@ -223,6 +223,12 @@ export function getWidgetElement(spec: any) {
         let old_style = elem.attr('style') || '';
         elem.attr({"style": old_style + ';' + spec.style});
     }
+    if (spec.click_callback_id) {
+        elem.on('click', (e) => {
+            pushData(null, spec.click_callback_id);
+        });
+        elem.addClass('pywebio-clickable');
+    }
     if (spec.container_dom_id) {
         if (spec.container_selector)
             elem.find(spec.container_selector).attr('id', spec.container_dom_id);
@@ -273,10 +279,10 @@ export function render_tpl(tpl: string, data: { [i: string]: any }) {
     let elem = parseHtml(html);
     for (let dom_id in placeholder2spec) {
         let spec = placeholder2spec[dom_id];
-        try{
+        try {
             let sub_elem = getWidgetElement(spec);
             elem.find(`#${dom_id}`).replaceWith(sub_elem);
-        }catch (e) {
+        } catch (e) {
             console.error('Error when render widget: \n%s', JSON.stringify(spec));
         }
     }