djust 0.9.0rc2

Pre-releaseReleased

This is a pre-release. djust 0.9.0 has shipped since: read the djust 0.9.0 release notes.

Changed

  • WizardMixin.as_live_field auto-picks dom_event by widget class (closes #1156) — previously the view-level wizard_input_event attribute applied uniformly to every widget the wizard rendered. An author setting wizard_input_event = "dj-input" to capture unblurred text edits (per #1095) unintentionally also stamped dj-input on radios, selects, and checkboxes — which was semantically wrong (there's no keystroke stream to fire on) and pre- #1155 incurred a 300ms debounce stall on every click.

    as_live_field now inspects the field's widget class (walking the widget's MRO so any subclass of an enumerated builtin inherits the default automatically) and picks:

    • dj-change for click-fired widgets — RadioSelect, CheckboxInput, CheckboxSelectMultiple, Select, plus every Django Select subclass (SelectMultiple, NullBooleanSelect) and any app's RadioSelect/Select subclass matched via MRO. They commit exactly one value per user interaction, no stream to batch.
    • wizard_input_event for text-stream widgets (TextInput, Textarea, NumberInput, EmailInput, etc.) — preserves the #1095 contract for authors who need unblurred-text capture.
    • Caller-passed dom_event="..." still wins — the widget-aware default is a default, not a mandate.

    Apps that had implemented their own as_live_field override to do exactly this mapping can delete the override.

    New _CLICK_FIRED_WIDGET_CLASSES ClassVar (frozenset of widget class names) lets apps with custom commit-style widgets extend the dispatch without overriding as_live_field itself:

    class MyWizard(WizardMixin, LiveView):
        _CLICK_FIRED_WIDGET_CLASSES = frozenset({
            *WizardMixin._CLICK_FIRED_WIDGET_CLASSES,
            "MyColorPickerWidget",
        })
    

    Files: python/djust/wizard.py (new _default_dom_event_for helper + _CLICK_FIRED_WIDGET_CLASSES ClassVar, ~20 LoC; updated wizard_input_event docstring to clarify text-only scope). 15 new cases in TestAsLiveFieldWidgetAwareDomEvent in tests/unit/test_wizard_mixin.py cover text/textarea/integer/email tracking wizard_input_event, radio/select/checkbox/ CheckboxSelectMultiple locked to dj-change, caller-passed dom_event overrides, ClassVar extension for custom widgets, and MRO walk catching SelectMultiple / NullBooleanSelect / app-defined RadioSelect subclasses.

Fixed

  • dj-input on click-fired widgets no longer incurs a 300ms debounce (closes #1154)DEFAULT_RATE_LIMITS in python/djust/static/djust/src/08-event-parsing.js was missing entries for radio, checkbox, select-one, and select-multiple. The input handler's fallback ({ type: 'debounce', ms: 300 }) kicked in for these widget types, so WizardMixin.wizard_input_event = "dj-input" — the class-wide setting recommended by #1095 — silently inserted 300ms of dead air between a radio click and the WS event being sent.

    Fix adds a new passthrough rate-limit type for click-fired widgets (they commit exactly one value per user interaction, no stream to batch) plus a branch in the input handler in 09-event-binding.js that skips the rate-limit wrapper when rateLimit.type === 'passthrough'. Text/textarea fields retain their 300ms debounce unchanged. The defensive 300ms fallback for unknown widget types is intact.

    Real-world measurement from a wizard with a Yes/No radio and wizard_input_event = "dj-input":

    click → WS sendtotal click → DOM
    Before1104 ms~1150 ms
    After1 ms~75 ms

    dj-debounce/dj-throttle explicit overrides on a radio still work — passthrough is the default, not a mandate. Files: python/djust/static/djust/src/08-event-parsing.js (4-line DEFAULT_RATE_LIMITS extension), python/djust/static/djust/src/09-event-binding.js (7-line passthrough branch + a one-line Object.assign({}, …) clone of the default before the override branches mutate it — without the clone, dj-debounce/dj-throttle on one element permanently flips the shared DEFAULT_RATE_LIMITS entry and pollutes every subsequently- bound element of the same type). 9 new cases in tests/js/dj-input-click-widgets.test.js lock in synchronous firing for radio/checkbox/select-one/select-multiple, continued debounce for text/textarea, that dj-debounce overrides still apply, and that an override on one radio does not leak into a sibling radio's wrapper (regression for the shared-state mutation).

All releases · Atom feed