From 837cb4ce63142341086b7f1cb628674bb4c40544 Mon Sep 17 00:00:00 2001 From: Dominic Kempf Date: Thu, 24 Feb 2022 18:16:40 +0100 Subject: [PATCH 1/2] Implement onesided minimum/maximum rules --- ipywidgets_jsonschema/form.py | 33 ++++++++++++++++++++-- tests/schemas/integer-onesided-max.json | 12 ++++++++ tests/schemas/integer-onesided-min.json | 12 ++++++++ tests/schemas/number-onesided-maximum.json | 12 ++++++++ tests/schemas/number-onesided-min.json | 12 ++++++++ 5 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 tests/schemas/integer-onesided-max.json create mode 100644 tests/schemas/integer-onesided-min.json create mode 100644 tests/schemas/number-onesided-maximum.json create mode 100644 tests/schemas/number-onesided-min.json diff --git a/ipywidgets_jsonschema/form.py b/ipywidgets_jsonschema/form.py index 0c29bda..e5502c2 100644 --- a/ipywidgets_jsonschema/form.py +++ b/ipywidgets_jsonschema/form.py @@ -25,6 +25,33 @@ def as_tuple(obj): return (obj,) +def minmax_schema_rule(widget, schema): + """This implements the minimum/maximum rules + + Only used for inputs bounded from one side, as ipywidgets + has dedicated widgets for inputs bound from both sides. Defined + in a separate function, because it used twice for number and + integer widgets. + """ + if "minimum" in schema: + + def min_handler(_): + if widget.value < schema["minimum"]: + widget.value = schema["minimum"] + + widget.observe(min_handler, names="value") + + if "maximum" in schema: + + def max_handler(_): + if widget.value > schema["maximum"]: + widget.value = schema["maximum"] + + widget.observe(max_handler, names="value") + + return widget + + class Form: def __init__( self, @@ -297,7 +324,8 @@ def _construct_number(self, schema, label=None, root=False): label=label, ) else: - return self._construct_simple(schema, ipywidgets.FloatText(), label=label) + widget = minmax_schema_rule(ipywidgets.FloatText(), schema) + return self._construct_simple(schema, widget, label=label) def _construct_integer(self, schema, label=None, root=False): # Inputs bounded only from below or above are currently not supported @@ -312,7 +340,8 @@ def _construct_integer(self, schema, label=None, root=False): label=label, ) else: - return self._construct_simple(schema, ipywidgets.IntText(), label=label) + widget = minmax_schema_rule(ipywidgets.IntText(), schema) + return self._construct_simple(schema, widget, label=label) def _construct_boolean(self, schema, label=None, root=False): # Extract the labelling for the checkbox diff --git a/tests/schemas/integer-onesided-max.json b/tests/schemas/integer-onesided-max.json new file mode 100644 index 0000000..5a37fa8 --- /dev/null +++ b/tests/schemas/integer-onesided-max.json @@ -0,0 +1,12 @@ +{ + "default": 42, + "schema": { + "default": 42, + "maximum": 45, + "type": "integer" + }, + "valid": [ + 45, + 42 + ] +} diff --git a/tests/schemas/integer-onesided-min.json b/tests/schemas/integer-onesided-min.json new file mode 100644 index 0000000..c3cb839 --- /dev/null +++ b/tests/schemas/integer-onesided-min.json @@ -0,0 +1,12 @@ +{ + "default": 42, + "schema": { + "default": 42, + "minimum": 40, + "type": "integer" + }, + "valid": [ + 40, + 45 + ] +} diff --git a/tests/schemas/number-onesided-maximum.json b/tests/schemas/number-onesided-maximum.json new file mode 100644 index 0000000..238f887 --- /dev/null +++ b/tests/schemas/number-onesided-maximum.json @@ -0,0 +1,12 @@ +{ + "default": 42, + "schema": { + "default": 42, + "maximum": 45, + "type": "number" + }, + "valid": [ + 45, + 42 + ] +} diff --git a/tests/schemas/number-onesided-min.json b/tests/schemas/number-onesided-min.json new file mode 100644 index 0000000..bb83793 --- /dev/null +++ b/tests/schemas/number-onesided-min.json @@ -0,0 +1,12 @@ +{ + "default": 42, + "schema": { + "default": 42, + "minimum": 40, + "type": "number" + }, + "valid": [ + 40, + 45 + ] +} From 5521c7111eb24a75a1efe89959964bc4819134ec Mon Sep 17 00:00:00 2001 From: Dominic Kempf Date: Thu, 24 Feb 2022 19:17:07 +0100 Subject: [PATCH 2/2] Ensure that a valid value is used in absence of default value --- ipywidgets_jsonschema/form.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ipywidgets_jsonschema/form.py b/ipywidgets_jsonschema/form.py index e5502c2..34bfda6 100644 --- a/ipywidgets_jsonschema/form.py +++ b/ipywidgets_jsonschema/form.py @@ -254,6 +254,11 @@ def _construct_simple(self, schema, widget, label=None, root=False): # Apply a potential default if "default" in schema: widget.value = schema["default"] + else: + if "minimum" in schema: + widget.value = schema["minimum"] + if "maximum" in schema: + widget.value = schema["maximum"] # Apply potential constant values without generating a widget if "const" in schema: