Changelog¶
Changelog¶
[0.0.5] - 2026-03-29¶
Fixed¶
Scripts now run synchronously instead of on
DOMContentLoaded—admin.jsandcore.jspreviously registeredDOMContentLoadedlisteners, but Alpine v3 callsAlpine.start()immediately when its script executes (it checksdocument.readyState, which is already"interactive"fordeferscripts). This meant Alpine initialized the DOM before our listeners fired, causing “Undefined variable” Alpine errors on every directive we applied. Both scripts now run their initialization synchronously. Sincedeferguarantees document-order execution (admin.js→core.js→alpine.js), Alpine always sees the fully prepared DOM.
[0.0.4] - 2026-03-27¶
Added¶
Dynamic inline rows supported —
core.jsnow listens for theformset:addedevent that Django Admin dispatches when a new inline row is added. The new row’s inputs are processed automatically (directives applied,x-modelset, Alpine state updated), andAlpine.initTreeis called on the row so bindings take effect immediately without a page reload.
Fixed¶
Empty form template rows skipped — elements whose
nameoridcontains Django’s__prefix__placeholder are now ignored bycore.js. Previously these template inputs were processed, producing phantom state keys and Alpine expression errors.
[0.0.3] - 2026-03-27¶
Added¶
tdDjango Admin preset resolver — targets the closest<td>, useful for applying directives to individual cells in tabular formsets (x-td-<directive>).selfbuilt-in resolver — always available regardless of which mixin or custom resolvers are configured. Usex-self-<directive>to apply Alpine directives directly to the input element itself, which is especially useful in formsets where no surrounding container is needed.
Changed¶
__row_prefix__sanitizes hyphens to underscores for Alpine.js compatibility. The row prefix (from the container ID or elementname) is now sanitized so hyphens become underscores, producing valid JavaScript identifiers (e.g.items_0_myFieldinstead ofitems-0-myField). Hyphens in Alpine expressions cause a parse error because JavaScript treats them as subtraction operators.
[0.0.2] - 2026-03-26¶
Added¶
README.mdset as the PyPI long description viapyproject.toml(readme = { file = "README.md", content-type = "text/markdown" }).
[0.0.1] - 2026-03-26¶
First release of django-form-alpine.
Added¶
FormAlpineMixin— base mixin that loadscore.jsand Alpine.js via Django’s media framework. Use it in any Django form together with custom resolvers.AdminAlpineMixin— extendsFormAlpineMixinand also loadsadmin.js, which registers built-in resolvers for all standard Django Admin containers.x-add-model-dataattribute — declare it on a widget to automatically register the field’s initial value in the closestform[x-data]and bind it withx-model.Prefixed directives — apply Alpine.js directives to surrounding containers directly from widget
attrsusingx-<resolver>-<directive>or@<resolver>-<directive>patterns.__row_prefix__placeholder — namespace Alpine state keys per inline row; resolved from the container ID or the elementnameattribute using Django’s<prefix>-<number>-<field>convention.Custom resolvers — define
window.DjangoFormAlpine.resolversbefore the scripts load to target any container. SetuseAdminResolvers: trueto merge custom resolvers with the built-in admin ones.Django Admin preset resolvers:
form-row,form-multiline,form,fieldset,field-box,field-container,label,errorlist,help,inline-container,nonfield-errorlist,option-label.Configurable Alpine.js path — override the bundled Alpine.js with
django_form_alpine_JS_PATHinsettings.py.Playwright end-to-end tests for Django Admin integration.
Vitest unit tests with 100% statement, branch, function, and line coverage for
core.jsandadmin.js.