VAT
Your cart

Your cart is empty.

The Addofy JavaScript API (window.adba)

Load your script with the dependency adba-core, then use window.adba. Full TypeScript types are in docs/adba.d.ts in the plugin.

adba.boot( 'myplugin', () => {
	adba.commands.register( { id: 'myplugin-report', label: 'Open report', run: () => location.assign( '/wp-admin/admin.php?page=myplugin' ) } );
	adba.shortcuts.register( { id: 'myplugin-report', keys: 'g r', label: 'Go to the report', handler: () => location.assign( '/wp-admin/admin.php?page=myplugin' ) } );
	adba.notices.add( { id: 'myplugin-sync', level: 'success', text: 'Sync done.', source: 'myplugin' } );
} );

adba.on( 'module:ready', ( { id } ) => console.log( 'started', id ) );

adba.boot() isolates errors: a failing entry is logged with its id. It fires module:ready when the entry started without errors.

Loading

Since 1.4.0 the admin loads one script for core and the modules that run on every screen (core/global.js). Parts that are only needed on interaction load on first use: the palette UI, the drawer, the notice panel, section tabs and the save bar, the Help rows and adba.api.document().

The API stays the same. adba.drawer.open() still answers right away, adba.sectionTabs.create() returns a controller and adba.savebar() returns an object whose bar arrives once loaded.

Notices

adba.notices.add( { id, text, level, source, dismissible } ) takes plain text, set with textContent: no HTML from an extension reaches the page. For a notice with links or markup, print a normal admin notice in PHP. The notice panel picks it up, and adba_notice_sources or data-adba-source assigns its group.

Events

Listen with adba.on( name, callback ).

EventPayloadWhen
readyadbaCore started.
module:ready{ id }A module entry started without errors.
prefs:change{ key, value, remote? }A preference changed (also from another tab).
prefs:errorerrorA preference could not be saved.
api:error{ error, request, silent }A REST call failed.
commands:changeA command was registered.
search:open, search:closeThe palette opened or closed.
search:select{ item, handled }A result or command was chosen. Set handled = true to take over.
search:scope{ scope }Multisite: the palette switched between this site (site) and all sites (network).
palette:run{ command, values }A palette command runs, with the values of its params. Since 2.11.0.
view:apply{ view }A saved view is opened from its pill or the views menu. Since 2.11.0.
view:save{ name, share }A view was saved; share is empty (only me), all or a role. Since 2.11.0.
drawer:open, drawer:close{ type, url }The side panel opened or closed.
drawer:saved{ url }A screen in the side panel saved.
notices:change{ count, level }The notice panel count or level changed.
pagebar:ready{ bar }The page bar is ready.
listtable:ready, listtable:updatedA list table is ready or reloaded.
listtable:appended{ rows }Load more (phones) added the rows of the next page. Since 2.8.0.
orders:ready, products:ready, settings:updated, wcsettings:updatedScreen specific.
guide:open{ id, type }A guide opened as a card (card) or a tour (tour). Since 2.9.0.
guide:done{ id, completed }A guide closed; completed when every tour step was seen. Since 2.9.0.
img:fallback{ element }A list picture that did not load got the placeholder (filter adba_image_placeholder). Since 2.12.2.

JS filters

Addofy uses the native WordPress hooks script. Add a filter with wp.hooks.addFilter(). A callback that throws is logged with the filter name, and the original value is used.

wp.hooks.addFilter( 'adba.search.results', 'myplugin', ( groups, { query } ) => [
	...groups,
	{ id: 'myplugin', label: 'Reports', items: [ { title: `Report for "${ query }"`, url: '/wp-admin/admin.php?page=myplugin' } ] },
] );
FilterValueExtra argument
adba.search.resultsResult groups [ { id, label, items: [ { title, url, subtitle, badge } ] } ] before they render.{ query, scope }
adba.commands.listCommands the palette shows.{ screen }
adba.paletteCommandsCommands right before the palette ranks them for the typed query (since 2.11.0).{ query, scope }
adba.notices.sourceThe plugin group { slug, name } of a notice, or null for Other.the notice element
adba.drawer.optionsOptions when the side panel opens (url must stay a string).
adba.orderQuickActionsSections of the order quick actions popup (since 1.2.0).the order data
adba.pagebar.actionsPage bar buttons from JS: [ { id, label, onClick, icon } ], icon a dashicons-* class.{ screen, bar }
adba.queueActionA background job before adba.queue runs it (since 2.5.0). Return the job, changed or not, or a falsy value to refuse it.

Background actions (adba.queue, since 2.5.0)

adba.queue.run( { key, label, element, apply, request, rollback, undo } ) changes the interface at once with apply(), marks element with aria-busy and the class adba-pending (a small pulsing dot), and runs request() in the background.

  • Use adba.api or fetch in request() so every server hook still runs.
  • On success a toast shows label, with Undo when undo() is given.
  • On a failure rollback() runs and the toast offers Try again.
  • Jobs with the same key run one after the other, others side by side (at most 4).
  • While jobs are pending, leaving the page asks for confirmation.
  • Load it with adba.load( 'queue' ); it then also sits on adba.queue.
  • Events: queue:start, queue:done and queue:fail, each with { key, label }.

The PHP filters adba_async_row_actions (status, trash and restore links) and adba_async_bulk_actions (bulk actions that run in batches of 20) decide which list actions use the queue.

Sortable lists (adba.sortable, since 2.36.0)

adba.sortable( container, options ) lets users reorder a list by dragging, with the same grip, chip, drop line and autoscroll as the term and menu sorting. Mouse and touch work; Escape cancels. The code loads on the first call; the call returns { refresh, destroy } right away.

const sorter = window.adba?.sortable?.( list, {
	items: 'li.myplugin-rule',
	label: ( item ) => item.dataset.name,
	disabled: () => busy,
	onSort: ( from, to, item ) => save( from, to ),
} );
  • items: selector for the items among the direct children of container. Default: all children.
  • handle: selector for your own grip inside an item (give it touch-action: none). Without it, Addofy adds a six-dot grip to each item.
  • label( item ): text in the chip. Default: the text of the item.
  • disabled: true, or a function that returns true, blocks dragging. Checked when a drag starts.
  • onSort( from, to, item ): called after the item moved in the DOM. The indexes count the items only.

One level, no nesting. Keyboard users keep your own up and down buttons. Calling it again on the same container replaces the earlier call, so you can redraw the list and call it again. New items get their grip by themselves. destroy() removes the grips and listeners. Feature-detect window.adba?.sortable and keep your own fallback when Addofy is not active.

Ready to connect your AI to real tools?

Start free trial