← Playground index

AjaxSlim — element reference

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).

Element kinds: Widget a form-input UI element · Update a refreshable region / its triggers · Activity busy & polling · Server no UI of its own. A marks a required binding.

Core update mechanism

Input widgets

Containers, activity & polling

Two update-container elements, on purpose. 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.

Migrating from the Ajax framework

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.

Core update mechanism

The load-bearing spine: partial-page updates and Ajax form submission, all reconciled into the live DOM via Idiomorph.

AjaxUpdateContainer Update

A 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.

BindingTypeDescription
idStringThe DOM id of the container (defaults to a safe generated element id). This is the id other elements target.
elementNameStringThe HTML tag to render. Defaults to div.
morphBooleanWhen 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.
onRefreshCompleteString (JS)JavaScript to run after the container has been refreshed/morphed.
optionalBooleanSet 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 Update

An 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-*, …).

BindingTypeDescription
frequencyNumber (s)The frequency, in seconds, of a periodic self-refresh.
stoppedBooleanWhether a periodic container loads stopped (so it can be started later by refreshing it).
observeFieldIDStringThe DOM id of a field whose changes trigger a self-refresh of this container.
fullSubmitBooleanWhen observing a field, whether to submit the whole form (true) or just the field (false).
actionactionThe action to invoke when this container refreshes itself.
<wo:AjaxSelfUpdatingContainer id="clock" frequency="5" action="$tick">
  Server time: <wo:str value="$now"/>
</wo:AjaxSelfUpdatingContainer>

A 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.

BindingTypeDescription
actionactionThe action to call when the link executes.
directActionNameStringThe direct action to call when the link executes (requires replaceID).
updateContainerIDStringThe id of the AjaxUpdateContainer to morph after the action. May be a ;-separated list to update several at once.
replaceIDStringThe id of the element whose contents are replaced with the action's result.
stringStringString prepended to the contained elements (the link text).
onClickString (JS)JavaScript to run on the client before the request is sent.
onClickBeforeString (JS)If this expression is false, the click is ignored (e.g. confirm(...)).
onClickServerString (JS)JS returned from the server after the action when there is no update.
onSuccessString (JS)JavaScript to run after a successful update/morph (before onComplete).
onCompleteString (JS)JavaScript to run after the update/morph completes.
ignoreActionResponseBooleanIf true, the action's response is thrown away.
functionString (JS)A custom JS function to call, passed the action url.
functionNameStringIf set, the link becomes a named JavaScript function instead of an element.
elementNameStringThe element name to use. Defaults to a.
buttonBooleanIf true, renders an <input type="button">.
disabledBooleanIf true, the link tag is not rendered.
id / class / style / title / accesskeyStringStandard 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 Update

Like 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.

BindingTypeDescription
actionactionThe action to execute when the button is pressed.
updateContainerIDStringThe id of the container to morph after submitting. May be a ;-separated list.
replaceIDStringThe id of the region to replace (mutually exclusive with updateContainerID).
valueStringThe button text.
nameStringThe HTML name of the button.
buttonBooleanRender as a link rather than a button.
useButtonTagBooleanRender a <button> instead of <input type="button">.
formNameStringThe name of the form to submit (defaults to the containing form).
functionNameStringIf set, exposes the submit as a named JS function (the UI then defaults to hidden).
showUIBooleanWhen functionName is set (which hides the UI by default), set true to render the button anyway.
onClick / onClickBefore / onClickServerString (JS)Client hook after the request / gate before it / server-returned JS.
onSuccess / onCompleteString (JS)Post-update hooks (run after the morph).
disabledBooleanRenders the disabled attribute.
id / class / style / title / tabindex / accesskey / elementNameStringStandard HTML attributes on the rendered element.
<wo:AjaxSubmitButton action="$save" updateContainerID="result" value="Save"/>

AjaxDefaultSubmitButton Update

An 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).

BindingTypeDescription
actionactionThe action to execute on Enter.
updateContainerIDStringThe id of the container to morph after the action.
formNameStringThe name of the form to submit (defaults to the containing form).
formSerializerAccepted for compatibility; the runtime always serializes the form itself.
name / valueStringHTML name/value of the hidden button (optional).
onClick / onClickBefore / onClickServerString (JS)Client hook after the request / gate before it / server-returned JS.
onSuccess / onCompleteString (JS)Post-update hooks.
id / class / accesskeyStringStandard attributes.
<wo:form>
  <wo:AjaxDefaultSubmitButton action="$search" updateContainerID="results"/>
  ...fields...
</wo:form>

AjaxObserveField Update

Performs 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).

BindingTypeDescription
observeFieldIDStringThe id of the field to observe. Omit to observe all descendant fields of this element (descendant mode).
updateContainerIDStringThe id of the container to morph on change. Use "_parent" for the nearest enclosing one. May be a ;-separated list.
actionactionThe action to call when the observer fires.
fullSubmitBooleanWhen false (default), only the changed field is submitted (partial); when true, the whole form is submitted.
observeDelayNumber (s)The debounce, in seconds, before the submit fires.
observeFieldFrequencyNumber (s)Legacy poll interval, in seconds; now treated as a debounce.
onBeforeSubmitString (JS)JS called before submitting; return false to deny the submit.
onSuccess / onCompleteString (JS)Post-update hooks.
nameStringThe HTML name used as the ajax submit-button name (defaults to the element id).
id / elementName / class / styleStringThe 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 Server

A 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.

BindingTypeDescription
updateContainerIDStringA single update container id to refresh.
updateContainerIDsArray<String>An array of update container ids to refresh.
resetAfterUpdateBooleanIf true, the array of ids is cleared after appendToResponse.
<!-- inside a region that, when re-rendered, should refresh others: -->
<wo:AjaxUpdateTrigger updateContainerID="summaryPanel"/>

Input widgets

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 Widget

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.

BindingTypeDescription
list ListThe list of objects to choose from.
itemObjectThe repetition item (current object) during rendering.
selectionObjectThe currently selected object (settable).
displayStringStringThe text shown for each option (defaults to the item's toString).
noSelectionStringStringPlaceholder option text shown when nothing is selected.
value / selectedValueObjectValue-based selection (as on WOPopUpButton).
disabled / escapeHTMLBooleanStandard WOPopUpButton behaviour.
id / name / class / styleStringStandard 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 Widget

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.

BindingTypeDescription
list ListThe list of objects to choose from.
itemObjectThe repetition item during rendering.
selectionsArrayThe currently selected objects (settable).
selectedValuesArrayValue-based multi-selection (as on WOBrowser).
multipleBooleanWhether the browser is multi-select (bind multiple="$true" for tags).
displayStringStringThe text shown for each option.
noSelectionStringStringMapped to a data-placeholder attribute (a multi-select has no no-selection option) for the widget's placeholder.
disabled / escapeHTMLBooleanStandard WOBrowser behaviour.
id / name / class / styleStringStandard HTML attributes.
<wo:AjaxBrowser list="$items" item="$item" selections="$selected"
  multiple="$true" displayString="$item.name" noSelectionString="Add some…"/>

Containers, activity & polling

AjaxModalContainer Update

Renders 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).

BindingTypeDescription
labelStringThe text on the trigger button.
titleStringOptional title shown at the top of the dialog (and as the button's title).
closeLabelStringThe text on the dialog's close button. Defaults to "Close".
openBooleanIf true, the dialog is open on initial render.
id / class / styleStringAttributes for the trigger button.
<wo:AjaxModalContainer label="Details" title="Order details" id="box">
  ...dialog content (may contain its own update container)...
</wo:AjaxModalContainer>

AjaxBusySpinner Activity

Shows 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.)

BindingTypeDescription
idStringOptional id for the spinner element.
classStringOptional extra CSS class(es) on the spinner.
styleStringOptional inline style on the spinner.
<wo:AjaxBusySpinner/>

AjaxPing Activity

Refreshes 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.

BindingTypeDescription
targetContainerIDStringThe id of the update container to refresh when the key changes.
cacheKeyObjectA value that represents the state of the target container.
frequencyNumber (ms)The frequency of the ping, in milliseconds. Defaults to 3000.
onBeforeUpdateString (JS)A JS function to call before updating; return true to allow the update.
stopBooleanIf true, the ping stops; if false it runs (refresh the ping's container to restart it).
idStringOptional id of the ping container.
<wo:AjaxPing targetContainerID="bigPanel" cacheKey="$panelVersion" frequency="5000"/>

AjaxPingUpdate Server

Refreshes 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.

BindingTypeDescription
targetContainerIDStringThe id of the update container to refresh when the key changes.
cacheKeyObjectA value that represents the state of the target container.
onBeforeUpdateString (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.