The canonical reference for every element in the AjaxSlim library: what it does and its full set of bindings. AjaxSlim is the morph-native, fetch-based rebuild of the classic Ajax framework — zero Prototype, zero Scriptaculous. Elements live in package er.ajax as a drop-in replacement; the client runtime is the dependency-free ajaxslim.js (fetch + Idiomorph).
AjaxUpdateContainer is passive — a named region that other elements refresh. AjaxSelfUpdatingContainer refreshes itself (on a timer or when a field changes) and may run its own action. The old single element conflated the two: an action on a plain container only fired on self-refresh, which read backwards. Splitting them makes the intent explicit.AjaxSlim is a drop-in replacement (same er.ajax package), so most templates need no change. The things that actually break a port — almost all client-side, because the Prototype/Scriptaculous runtime is gone:
| <id>Update() | AjaxSlim.AUC.update('<id>') | The per-container global function the old framework generated (via eval) no longer exists. Call the public API to refresh a container from your own JS. |
| AjaxUpdateContainer frequency / action / observeFieldID |
AjaxSelfUpdatingContainer | The container element was split. A container that refreshes itself (on a timer, on a field change, or running its own action) is now AjaxSelfUpdatingContainer; plain AjaxUpdateContainer is passive and only refreshes when something else targets it. An old self-updating container ported as-is will stop refreshing. |
| AUC. / AUL. / ASB. | AjaxSlim.AUC. / AUL. / ASB. | The client globals are namespaced now. Any custom JS calling the bare globals needs the AjaxSlim. prefix. |
| effect / insertion *Duration / *EffectID |
— (dropped) | All Scriptaculous effect & insertion bindings are gone (no effects.js). Use CSS transitions instead. onComplete/onSuccess are kept, repurposed as post-morph JS hooks. |
| onLoading / onFailure asynchronous / evalScripts |
— (dropped) | The Prototype Ajax.Request transport options are gone — the transport that consumed them (Prototype) was replaced by fetch. |
Also worth knowing: updates now morph the DOM (Idiomorph) by default instead of replacing innerHTML — focus, scroll and selection survive a refresh; bind morph="$false" for the old replace-everything behaviour. And ~40 rarely-used legacy elements (Accordion, Tree, Slider, DatePicker, drag/drop, in-place editors, the Scriptaculous effects, …) were not ported — AjaxSlim is the actually-used core; reach for a platform/native equivalent for those.
The load-bearing spine: partial-page updates and Ajax form submission, all reconciled into the live DOM via Idiomorph.
AjaxUpdateContainer UpdateA region of the page that can be refreshed independently via an Ajax request, morphing the freshly-rendered HTML into the live DOM (preserving focus, scroll, selection and unchanged subtrees) instead of replacing its innerHTML. Passive: it is refreshed by other elements that name it in updateContainerID; it has no action and no self-refresh of its own.
| Binding | Type | Description |
|---|---|---|
| id | String | The DOM id of the container (defaults to a safe generated element id). This is the id other elements target. |
| elementName | String | The HTML tag to render. Defaults to div. |
| morph | Boolean | When true (the default), content updates reconcile the existing DOM via Idiomorph — preserving focus/scroll/selection and unchanged subtrees. Bind morph="$false" to force classic innerHTML replacement. |
| onRefreshComplete | String (JS) | JavaScript to run after the container has been refreshed/morphed. |
| optional | Boolean | Set true to skip rendering the container tags when this element is already inside another update container (renders only its children). |
Any other attribute you set — class, style, data-*, role, aria-*, title, … — is passed through verbatim onto the rendered tag.
<wo:AjaxUpdateContainer id="detail"> ...content... </wo:AjaxUpdateContainer> <!-- refresh it from elsewhere: --> <wo:AjaxUpdateLink action="$reload" updateContainerID="detail">Reload</wo:AjaxUpdateLink>
AjaxSelfUpdatingContainer UpdateAn update container that refreshes itself — on a timer (frequency) and/or when a field changes (observeFieldID) — and may invoke its own action when it does. The counterpart to the passive AjaxUpdateContainer; it also inherits all of that element's bindings (id, elementName, morph, onRefreshComplete, optional) and the same attribute passthrough (class, style, data-*, …).
| Binding | Type | Description |
|---|---|---|
| frequency | Number (s) | The frequency, in seconds, of a periodic self-refresh. |
| stopped | Boolean | Whether a periodic container loads stopped (so it can be started later by refreshing it). |
| observeFieldID | String | The DOM id of a field whose changes trigger a self-refresh of this container. |
| fullSubmit | Boolean | When observing a field, whether to submit the whole form (true) or just the field (false). |
| action | action | The action to invoke when this container refreshes itself. |
<wo:AjaxSelfUpdatingContainer id="clock" frequency="5" action="$tick"> Server time: <wo:str value="$now"/> </wo:AjaxSelfUpdatingContainer>
AjaxUpdateLink UpdateA link (or button, or named JS function) that fires a server action and morphs the result into a target container (updateContainerID) or replaces a region (replaceID). The standard "click to update part of the page". A updateContainerID may name several containers separated by ; to refresh them all in one round-trip.
| Binding | Type | Description |
|---|---|---|
| action | action | The action to call when the link executes. |
| directActionName | String | The direct action to call when the link executes (requires replaceID). |
| updateContainerID | String | The id of the AjaxUpdateContainer to morph after the action. May be a ;-separated list to update several at once. |
| replaceID | String | The id of the element whose contents are replaced with the action's result. |
| string | String | String prepended to the contained elements (the link text). |
| onClick | String (JS) | JavaScript to run on the client before the request is sent. |
| onClickBefore | String (JS) | If this expression is false, the click is ignored (e.g. confirm(...)). |
| onClickServer | String (JS) | JS returned from the server after the action when there is no update. |
| onSuccess | String (JS) | JavaScript to run after a successful update/morph (before onComplete). |
| onComplete | String (JS) | JavaScript to run after the update/morph completes. |
| ignoreActionResponse | Boolean | If true, the action's response is thrown away. |
| function | String (JS) | A custom JS function to call, passed the action url. |
| functionName | String | If set, the link becomes a named JavaScript function instead of an element. |
| elementName | String | The element name to use. Defaults to a. |
| button | Boolean | If true, renders an <input type="button">. |
| disabled | Boolean | If true, the link tag is not rendered. |
| id / class / style / title / accesskey | String | Standard HTML attributes on the rendered element. |
<wo:AjaxUpdateLink action="$edit" updateContainerID="detail" string="Edit"/> <wo:AjaxUpdateLink action="$bumpAll" updateContainerID="boxA;boxB;boxC">Bump all</wo:AjaxUpdateLink>
AjaxSubmitButton UpdateLike a WOSubmitButton, but submits its form in the background via Ajax and morphs the result into a target container (updateContainerID) or replaces a region (replaceID). Honours the AJAX_SUBMIT_BUTTON_NAME partial-submit contract, so it works correctly in multiple-submit forms.
| Binding | Type | Description |
|---|---|---|
| action | action | The action to execute when the button is pressed. |
| updateContainerID | String | The id of the container to morph after submitting. May be a ;-separated list. |
| replaceID | String | The id of the region to replace (mutually exclusive with updateContainerID). |
| value | String | The button text. |
| name | String | The HTML name of the button. |
| button | Boolean | Render as a link rather than a button. |
| useButtonTag | Boolean | Render a <button> instead of <input type="button">. |
| formName | String | The name of the form to submit (defaults to the containing form). |
| functionName | String | If set, exposes the submit as a named JS function (the UI then defaults to hidden). |
| showUI | Boolean | When functionName is set (which hides the UI by default), set true to render the button anyway. |
| onClick / onClickBefore / onClickServer | String (JS) | Client hook after the request / gate before it / server-returned JS. |
| onSuccess / onComplete | String (JS) | Post-update hooks (run after the morph). |
| disabled | Boolean | Renders the disabled attribute. |
| id / class / style / title / tabindex / accesskey / elementName | String | Standard HTML attributes on the rendered element. |
<wo:AjaxSubmitButton action="$save" updateContainerID="result" value="Save"/>
AjaxDefaultSubmitButton UpdateAn invisible submit button placed first in a form so that pressing Enter performs its action (the form's "default" action) via the background Ajax submit. A subclass of AjaxSubmitButton; renders an off-screen type="submit" input. Modern browsers fire its click on Enter natively (the legacy IE<9 keypress shim is dropped).
| Binding | Type | Description |
|---|---|---|
| action | action | The action to execute on Enter. |
| updateContainerID | String | The id of the container to morph after the action. |
| formName | String | The name of the form to submit (defaults to the containing form). |
| formSerializer | — | Accepted for compatibility; the runtime always serializes the form itself. |
| name / value | String | HTML name/value of the hidden button (optional). |
| onClick / onClickBefore / onClickServer | String (JS) | Client hook after the request / gate before it / server-returned JS. |
| onSuccess / onComplete | String (JS) | Post-update hooks. |
| id / class / accesskey | String | Standard attributes. |
<wo:form> <wo:AjaxDefaultSubmitButton action="$search" updateContainerID="results"/> ...fields... </wo:form>
AjaxObserveField UpdatePerforms an Ajax submit (and optional container morph) when a form field changes. Two modes: give it an observeFieldID to watch a single field; or omit observeFieldID to watch every descendant form field inside it (it then renders a wrapper element). Binds native change/input listeners with a debounce. fullSubmit="false" (the default) sends only the changed field (partial submit).
| Binding | Type | Description |
|---|---|---|
| observeFieldID | String | The id of the field to observe. Omit to observe all descendant fields of this element (descendant mode). |
| updateContainerID | String | The id of the container to morph on change. Use "_parent" for the nearest enclosing one. May be a ;-separated list. |
| action | action | The action to call when the observer fires. |
| fullSubmit | Boolean | When false (default), only the changed field is submitted (partial); when true, the whole form is submitted. |
| observeDelay | Number (s) | The debounce, in seconds, before the submit fires. |
| observeFieldFrequency | Number (s) | Legacy poll interval, in seconds; now treated as a debounce. |
| onBeforeSubmit | String (JS) | JS called before submitting; return false to deny the submit. |
| onSuccess / onComplete | String (JS) | Post-update hooks. |
| name | String | The HTML name used as the ajax submit-button name (defaults to the element id). |
| id / elementName / class / style | String | The wrapper element (only used in descendant mode). elementName defaults to div. |
<!-- single field --> <wo:textfield value="$q" id="q"/> <wo:AjaxObserveField observeFieldID="q" updateContainerID="results" action="$search"/> <!-- descendant mode: watch every field inside the wrapper --> <wo:AjaxObserveField updateContainerID="results" action="$refresh"> <wo:popUpButton .../> <wo:textfield .../> </wo:AjaxObserveField>
AjaxUpdateTrigger ServerA server-side-only element with no UI of its own: when it is rendered into a response, it forces named AjaxUpdateContainers elsewhere on the page to refresh. Useful when a central area controls several others — e.g. an edit view that, on opening, tells all the sibling read-only views to re-render. A missing target is silently skipped.
| Binding | Type | Description |
|---|---|---|
| updateContainerID | String | A single update container id to refresh. |
| updateContainerIDs | Array<String> | An array of update container ids to refresh. |
| resetAfterUpdate | Boolean | If true, the array of ids is cleared after appendToResponse. |
<!-- inside a region that, when re-rendered, should refresh others: --> <wo:AjaxUpdateTrigger updateContainerID="summaryPanel"/>
Searchable, type-to-filter replacements for the standard <select> elements (the dependency-free wonder-select custom element). Both are thin WO subclasses: they add the marker class ajax-popup-button and ensure wonder-select.js/.css are loaded — so a plain WOPopUpButton/WOBrowser with class="ajax-popup-button" is equivalent.
AjaxPopUpButton A drop-in WOPopUpButton that renders a searchable single-select instead of a bare <select>. Reach for it when a long option list needs type-to-filter. The widget auto-enhances any matching <select> on the page, so it needs no per-page init.
| Binding | Type | Description |
|---|---|---|
| list • | List | The list of objects to choose from. |
| item | Object | The repetition item (current object) during rendering. |
| selection | Object | The currently selected object (settable). |
| displayString | String | The text shown for each option (defaults to the item's toString). |
| noSelectionString | String | Placeholder option text shown when nothing is selected. |
| value / selectedValue | Object | Value-based selection (as on WOPopUpButton). |
| disabled / escapeHTML | Boolean | Standard WOPopUpButton behaviour. |
| id / name / class / style | String | Standard HTML attributes. (The marker class ajax-popup-button is merged in automatically.) |
<wo:AjaxPopUpButton list="$items" item="$item" selection="$sel" displayString="$item.name" noSelectionString="Pick one…"/>
AjaxBrowser The multi-select companion to AjaxPopUpButton: a drop-in WOBrowser that renders the same searchable wonder-select widget with removable tags instead of a bare multi-select. The shared wonder-select.js reads the <select>'s multiple attribute to switch between single value and removable tags.
| Binding | Type | Description |
|---|---|---|
| list • | List | The list of objects to choose from. |
| item | Object | The repetition item during rendering. |
| selections | Array | The currently selected objects (settable). |
| selectedValues | Array | Value-based multi-selection (as on WOBrowser). |
| multiple | Boolean | Whether the browser is multi-select (bind multiple="$true" for tags). |
| displayString | String | The text shown for each option. |
| noSelectionString | String | Mapped to a data-placeholder attribute (a multi-select has no no-selection option) for the widget's placeholder. |
| disabled / escapeHTML | Boolean | Standard WOBrowser behaviour. |
| id / name / class / style | String | Standard HTML attributes. |
<wo:AjaxBrowser list="$items" item="$item" selections="$selected" multiple="$true" displayString="$item.name" noSelectionString="Add some…"/>
AjaxModalContainer UpdateRenders a trigger button that opens its inline content in a modal dialog, built on the platform's native <dialog> (free backdrop, focus trapping and Esc-to-close). The content stays in place in the DOM, so forms/links inside the dialog — including update containers — work exactly as anywhere else. Only the inline-content use is supported (iframe / direct-action / skin / locked modes are dropped).
| Binding | Type | Description |
|---|---|---|
| label | String | The text on the trigger button. |
| title | String | Optional title shown at the top of the dialog (and as the button's title). |
| closeLabel | String | The text on the dialog's close button. Defaults to "Close". |
| open | Boolean | If true, the dialog is open on initial render. |
| id / class / style | String | Attributes for the trigger button. |
<wo:AjaxModalContainer label="Details" title="Order details" id="box"> ...dialog content (may contain its own update container)... </wo:AjaxModalContainer>
AjaxBusySpinner ActivityShows a busy indicator while AjaxSlim has one or more Ajax requests in flight, and hides it when idle. A pure-CSS spinner driven by the runtime's activity broker — ajaxslim.js sets data-ajaxslim-busy on the document element while any request is in flight. No configuration: a busy indicator is the same everywhere. (Apps wanting a bespoke one can style .ajaxslim-busy-spinner or react to the ajaxslim:busy/ajaxslim:idle events on document.)
| Binding | Type | Description |
|---|---|---|
| id | String | Optional id for the spinner element. |
| class | String | Optional extra CSS class(es) on the spinner. |
| style | String | Optional inline style on the spinner. |
<wo:AjaxBusySpinner/>
AjaxPing ActivityRefreshes a large content area based on periodic refreshes of a very small one. A tiny self-refreshing container whose content depends only on cacheKey: while the key is unchanged the periodic ping is cheap; when it changes, the embedded AjaxPingUpdate refreshes the (potentially large) targetContainerID. So the expensive container is rebuilt only when something actually changed.
| Binding | Type | Description |
|---|---|---|
| targetContainerID | String | The id of the update container to refresh when the key changes. |
| cacheKey | Object | A value that represents the state of the target container. |
| frequency | Number (ms) | The frequency of the ping, in milliseconds. Defaults to 3000. |
| onBeforeUpdate | String (JS) | A JS function to call before updating; return true to allow the update. |
| stop | Boolean | If true, the ping stops; if false it runs (refresh the ping's container to restart it). |
| id | String | Optional id of the ping container. |
<wo:AjaxPing targetContainerID="bigPanel" cacheKey="$panelVersion" frequency="5000"/>
AjaxPingUpdate ServerRefreshes a target AjaxUpdateContainer when its cache key changes. Used inside an AjaxPing — place several in one ping to drive multiple targets from a single periodic refresh. It tracks cacheKey across requests and emits a refresh script for its target only when the key differs from the last seen value.
| Binding | Type | Description |
|---|---|---|
| targetContainerID | String | The id of the update container to refresh when the key changes. |
| cacheKey | Object | A value that represents the state of the target container. |
| onBeforeUpdate | String (JS) | A JS function to call before updating; return true to allow the update. |
<wo:AjaxPing frequency="5000" cacheKey="$tick"> <wo:AjaxPingUpdate targetContainerID="panelA" cacheKey="$versionA"/> <wo:AjaxPingUpdate targetContainerID="panelB" cacheKey="$versionB"/> </wo:AjaxPing>
Every element above is exercised together in the invoice editor integration page.