Skip to content

Releases: jpmanson/codeforms

v0.3.0 — HTML escaping and a working JS validation generator

Choose a tag to compare

@jpmanson jpmanson released this 27 Aug 16:59

Security

The HTML exporter escaped nothing. Labels, help text, placeholders, values, select and radio option labels, and group/step titles were interpolated into the markup raw. Any form definition built from external data could inject arbitrary HTML, and values placed into attributes could close the attribute and add their own (" onclick="…).

All interpolation now goes through new html_text() / html_attr() / attrs_to_str() helpers. attrs_to_str() also filters attribute names, so a crafted key cannot introduce a new attribute.

Fixes — client-side validation

The generated validation script was either absent or broken:

  • generate_validation_code() returned "" for every format except plain "html", so no Bootstrap consumer ever had client-side validation. It is now generated for html, html_bootstrap4 and html_bootstrap5.
  • The script looked the form up by form.name, which is not what ends up in the id attribute. It now receives the exported id, and bails out quietly if the element is absent.
  • Per-field code was emitted as let {field.name} = … — a SyntaxError for any field name that is not a JS identifier (mi-campo) or is a reserved word (class). Rules are now emitted as JSON and evaluated by a generic runtime, so field names are just data.
  • Messages, labels and regex patterns are serialized with json.dumps. Previously a single apostrophe or backslash broke the script.
  • Values are read by a helper that handles checkbox/radio groups (where form.elements[name] yields a collection) and multiple selects, instead of assuming .value.
  • The handler attaches with addEventListener instead of assigning onsubmit, which clobbered any other handler on the form, and is guarded against double attachment.

Compatibility

  • validate_<form_name>(form) is still exposed when the form name can be a JS identifier, so the previous entry point keeps working. Validation is also reachable as window.codeformsValidate[formId]().
  • Consumers that relied on unescaped HTML in labels, help text or option labels will now see those tags rendered as text.
  • Bootstrap consumers start receiving a non-empty javascript_validation_code for the first time. It is inert until you inject it into the page.

42 new tests; 248 total.

v0.2.4 — Fix textarea and hidden field HTML export

Choose a tag to compare

@jpmanson jpmanson released this 27 Aug 16:12

Fixes

TextareaField was exported as <input type="textarea">. That input type does not exist in HTML, so browsers degrade it to type="text". The field rendered as a single-line input: it could not hold line breaks, and pressing Enter triggered the browser's implicit form submission instead of inserting a newline.

  • TextareaField now renders a real <textarea>, with the value as element content instead of a value attribute. The content is HTML-escaped, so a value containing </textarea> can no longer break the markup.
  • The rows, cols, minlength and maxlength attributes are now emitted — they were declared on the model but never reached the HTML.
  • readonly is now honoured on textareas and on regular inputs.
  • Hidden fields render as a bare <input type="hidden">, without the form-group wrapper and form-control class that reserved visible vertical space for every hidden field in a form.

Build

  • The PyPI publish workflow was pinned to a 2021 revision of pypa/gh-action-pypi-publish, whose bundled twine rejects the Metadata-Version: 2.5 that current hatchling emits. Pinned to v1.14.2.

Note

v0.2.3 carries the same library fixes but was never published to PyPI: its tag predates the workflow fix above, so its release failed at the upload step. Use 0.2.4.

Upgrading

No API changes. Any consumer styling the previous <input type="textarea"> by tag, or relying on the form-group wrapper around hidden fields, should check its CSS.

v0.2.3 — Fix textarea and hidden field HTML export

Choose a tag to compare

@jpmanson jpmanson released this 27 Aug 16:04

Fixes

TextareaField was exported as <input type="textarea">. That input type does not exist in HTML, so browsers degrade it to type="text". The field rendered as a single-line input: it could not hold line breaks, and pressing Enter triggered the browser's implicit form submission instead of inserting a newline.

  • TextareaField now renders a real <textarea>, with the value as element content instead of a value attribute. The content is HTML-escaped, so a value containing </textarea> can no longer break the markup.
  • The rows, cols, minlength and maxlength attributes are now emitted — they were declared on the model but never reached the HTML.
  • readonly is now honoured on textareas and on regular inputs.
  • Hidden fields render as a bare <input type="hidden">, without the form-group wrapper and form-control class that reserved visible vertical space for every hidden field in a form.

Upgrading

No API changes. Any consumer styling the previous <input type="textarea"> by tag or relying on the form-group wrapper around hidden fields should check its CSS.

0.2.2

Choose a tag to compare

@jpmanson jpmanson released this 23 Mar 22:49

Add ObjectListField support with validation and JSON Schema export

v0.2.1

Choose a tag to compare

@jpmanson jpmanson released this 23 Feb 02:29

Refactor code and improve test coverage

  • Reordered imports in registry.py for consistency.
  • Updated string formatting to use double quotes for consistency.
  • Enhanced _init_builtin_types function by organizing field imports and registration.
  • Improved readability of test cases by formatting data dictionaries and assertions.
  • Added comprehensive tests for JSON Schema export functionality.
  • Ensured backward compatibility in tests for form construction and validation.
  • Cleaned up unnecessary whitespace and comments across various test files.

v0.2.0 — Dynamic Form Logic

Choose a tag to compare

@jpmanson jpmanson released this 17 Feb 12:29

What's New

Conditional Field Visibility

  • visible_when attribute on any field with operators: equals, not_equals, in, not_in, gt, lt, is_empty, is_not_empty
  • evaluate_visibility() function for runtime evaluation
  • Form.get_visible_fields(data) helper

Dependent Field Options

  • DependentOptionsConfig model for parent-child option relationships
  • dependent_options attribute on SelectField/RadioField

Multi-Step Wizard Forms

  • FormStep model with title, description, validation_mode, skippable
  • Form.get_steps(), Form.validate_step(), Form.validate_all_steps()
  • HTML export renders steps as <section> with data-wizard attributes

Dynamic Validation

  • validate_form_data_dynamic() — opt-in validation respecting visibility rules
  • Legacy validate_form_data() unchanged (backward compatible)

Other

  • Duck-typing cleanup (isinstance checks)
  • Resolver priority ordering for type discrimination
  • i18n messages for wizard/visibility (EN + ES)
  • 151 tests passing

Full Changelog: v0.1.1...v0.2.0

v0.1.1

Choose a tag to compare

@jpmanson jpmanson released this 17 Feb 11:22
  • Refactor code structure for improved readability and maintainability
  • Support for Python 3.9+
  • Custom field type registry: Allow registering custom field types without modifying the hardcoded Union in Form.content. Provide a register_field_type() API.

v0.1.0

Choose a tag to compare

@jpmanson jpmanson released this 17 Feb 10:56

First realese to PyPi