Skip to content

Commit f0ddc7c

Browse files
committed
add pin.get_pin_values()
1 parent a1dccec commit f0ddc7c

File tree

4 files changed

+51
-16
lines changed

4 files changed

+51
-16
lines changed

docs/spec.rst

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -271,12 +271,14 @@ Unique attributes of different types:
271271
* template:
272272
* data:
273273

274-
pin_value
274+
pin_values
275275
^^^^^^^^^^^^^^^
276276

277-
The ``spec`` fields of ``pin_value`` commands:
277+
Get the value of the pin widgets. The ``spec`` fields of ``pin_values`` commands:
278278

279-
* name
279+
* names: list, The names of the pin widget
280+
281+
The client will respond with a ``js_yield`` event, with the data field containing ``{ pin_name: pin_value, ... }``
280282

281283
pin_update
282284
^^^^^^^^^^^^^^^

pywebio/pin.py

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@
118118
Use `pin.pin.use_strict()` to enable strict mode for getting pin widget value.
119119
An ``AssertionError`` will be raised when try to get value of pin widgets that are currently not in the page.
120120
121+
.. autofunction:: get_pin_values
121122
.. autofunction:: pin_wait_change
122123
.. autofunction:: pin_update
123124
.. autofunction:: pin_on_change
@@ -137,7 +138,7 @@
137138
_pin_name_chars = set(string.ascii_letters + string.digits + '_-')
138139

139140
__all__ = ['put_input', 'put_textarea', 'put_select', 'put_checkbox', 'put_radio', 'put_slider', 'put_actions',
140-
'put_file_upload', 'pin', 'pin_update', 'pin_wait_change', 'pin_on_change']
141+
'put_file_upload', 'pin', 'pin_update', 'pin_wait_change', 'pin_on_change', 'get_pin_values']
141142

142143

143144
def _pin_output(single_input_return, scope, position):
@@ -258,11 +259,32 @@ def get_client_val():
258259

259260

260261
@chose_impl
261-
def get_pin_value(name, strict):
262-
send_msg('pin_value', spec=dict(name=name))
262+
def _get_pin_value(name, strict):
263+
send_msg('pin_values', spec=dict(names=[name]))
263264
data = yield get_client_val()
264-
assert not strict or data, 'pin widget "%s" doesn\'t exist.' % name
265-
return (data or {}).get('value')
265+
if strict:
266+
assert name in data, 'pin widget "%s" doesn\'t exist.' % name
267+
return data.get(name)
268+
269+
270+
@chose_impl
271+
def _get_pin_values(names: list[str]):
272+
send_msg('pin_values', spec=dict(names=names))
273+
data = yield get_client_val()
274+
return data
275+
276+
277+
def get_pin_values(names: list[str]) -> dict[str, Any]:
278+
"""
279+
Get the value of multiple pin widgets.
280+
Compared to using the :data:`pin` object to get the value of the pin widget one by one,
281+
this function can get the value of multiple pin widgets at once and is more efficient
282+
when getting the value of multiple pin widgets.
283+
284+
:return: A dict, the key is the name of the pin widget, and the value is the value of the pin widget.
285+
If the pin widget does not exist, the dict will not contain the corresponding key.
286+
"""
287+
return _get_pin_values(names)
266288

267289

268290
class Pin_:
@@ -283,7 +305,7 @@ def __getattr__(self, name: str):
283305

284306
def __getitem__(self, name: str):
285307
check_dom_name_value(name, 'pin `name`')
286-
return get_pin_value(name, self._strict)
308+
return _get_pin_value(name, self._strict)
287309

288310
def __setattr__(self, name: str, value):
289311
"""

webiojs/src/handlers/pin.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {ClientEvent, Command, Session} from "../session";
22
import {CommandHandler} from "./base";
3-
import {GetPinValue, PinChangeCallback, PinUpdate, WaitChange, IsFileInput} from "../models/pin";
3+
import {GetPinValues, PinChangeCallback, PinUpdate, WaitChange, IsFileInput} from "../models/pin";
44
import {state} from "../state";
55
import {serialize_file, serialize_json} from "../utils";
66
import {t} from "../i18n";
@@ -9,18 +9,19 @@ import {t} from "../i18n";
99
export class PinHandler implements CommandHandler {
1010
session: Session;
1111

12-
accept_command = ['pin_value', 'pin_update', 'pin_wait', 'pin_onchange'];
12+
accept_command = ['pin_values', 'pin_update', 'pin_wait', 'pin_onchange'];
1313

1414
constructor(session: Session) {
1515
this.session = session;
1616
}
1717

1818
handle_message(msg: Command) {
19-
if (msg.command === 'pin_value') {
20-
let val = GetPinValue(msg.spec.name); // undefined or value
19+
if (msg.command === 'pin_values') {
20+
let values = GetPinValues(msg.spec.names);
2121
let send_msg = {
22-
event: "js_yield", task_id: msg.task_id,
23-
data: val === undefined ? null : {value: val}
22+
event: "js_yield",
23+
task_id: msg.task_id,
24+
data: values
2425
};
2526
this.submit(send_msg, IsFileInput(msg.spec.name));
2627
} else if (msg.command === 'pin_update') {

webiojs/src/models/pin.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,22 @@ export function IsFileInput(name: string): boolean {
1212
return name2input[name] !== undefined && name2input[name].spec.type == "file";
1313
}
1414

15-
export function GetPinValue(name: string) {
15+
function _getPinValue(name: string) {
1616
if (name2input[name] == undefined || !document.contains(name2input[name].element[0]))
1717
return undefined;
1818
return name2input[name].get_value();
1919
}
2020

21+
export function GetPinValues(names: string[]) {
22+
let values: { [k: string]: any } = {};
23+
for (let name of names) {
24+
let val = _getPinValue(name);
25+
if (val !== undefined)
26+
values[name] = val;
27+
}
28+
return values;
29+
}
30+
2131
export function PinUpdate(name: string, attributes: { [k: string]: any }) {
2232
name2input[name].update_input({attributes: attributes});
2333
}

0 commit comments

Comments
 (0)