jsf-frontend-events
Handle the JetSmartFilters frontend AJAX lifecycle and reinitialize behavior after provider DOM replacement. Use when JavaScript must react when filtering starts, rendered content updates, loading ends, or JSF initializes; when integrating sliders, galleries, analytics, accessibi
Install
npx skills add https://github.com/Lonsdale201/wp-agent-skills/tree/main/jetsmartfilter/jsf-frontend-events
claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install lonsdale201-wp-agent-skills@llmmart
git clone https://github.com/Lonsdale201/wp-agent-skills.git
The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole lonsdale201/wp-agent-skills collection as a plugin from our marketplace. Git is the plain clone.
Skill manifest
JetSmartFilters frontend events
Subscribe to the JSF event bus and scope every callback. For a listing, the three essential lifecycle channels are:
| Channel | Callback arguments | Meaning |
|---|---|---|
ajaxFilters/start-loading |
provider, queryId |
A real AJAX request started; preloader is active |
ajaxFilters/updated |
provider, queryId, response, requestOptions |
Response was processed and provider DOM/fragments were updated |
ajaxFilters/end-loading |
provider, queryId |
Loading teardown ran and the preloader was hidden |
Use updated to read or initialize the new DOM. Use end-loading for a
global “cycle finished” UI state. They are not aliases.
Load a companion script after JSF
JSF enqueues its public script in wp_footer only on pages where filters were
rendered. Queue the bridge after JSF has enqueued itself and before footer
scripts print:
add_action( 'wp_footer', static function (): void {
if ( ! wp_script_is( 'jet-smart-filters', 'enqueued' ) ) {
return;
}
wp_enqueue_script(
'acme-jsf-bridge',
plugins_url( 'assets/js/jsf-bridge.js', __FILE__ ),
array( 'jet-smart-filters' ),
'1.0.0',
true
);
}, 16 );
Subscribe with provider/query scoping
(() => {
const targetProvider = 'jsf-listing';
const targetQueryId = 'catalog-listing';
const isTarget = (provider, queryId) =>
provider === targetProvider && queryId === targetQueryId;
const bind = () => {
const bus = window.JetSmartFilters?.events;
if (!bus?.subscribe) {
return;
}
bus.subscribe('ajaxFilters/start-loading', (provider, queryId) => {
if (!isTarget(provider, queryId)) return;
document.querySelector('.catalog-shell')?.setAttribute('aria-busy', 'true');
});
bus.subscribe(
'ajaxFilters/updated',
(provider, queryId, response, requestOptions) => {
if (!isTarget(provider, queryId)) return;
initCatalogWidgets(document.querySelector('#catalog-listing'));
}
);
bus.subscribe('ajaxFilters/end-loading', (provider, queryId) => {
if (!isTarget(provider, queryId)) return;
document.querySelector('.catalog-shell')?.setAttribute('aria-busy', 'false');
});
};
if (window.JetSmartFilters?.events) {
bind();
} else {
document.addEventListener('jet-smart-filters/before-init', bind, { once: true });
}
})();
Make initCatalogWidgets() idempotent: destroy or detect an existing widget
before recreating it.
Other useful events
- DOM
jet-smart-filters/before-init: JSF global exists; filter discovery has not run. - DOM
jet-smart-filters/inited: initial filter groups are available. - Bus
provider/content-rendered: callback receivesprovider, $providerafter provider HTML and builder integrations render. It has no query ID, so it is insufficient alone when several instances share a provider. - Legacy jQuery
jet-filter-content-rendered: document event withevent, $provider, filterGroup, provider, queryId. Prefer the event bus in new code; keep this only for a legacy integration contract. - A provider element may receive
jet-filter-data-updatedfor providers that return data rather than HTML.
Failure and concurrency rules
- A “start” event is not proof that content changed.
- In 3.8.3.1 a newer request aborts the previous XHR, and the abort path can
skip
end-loading. Do not maintain an unbounded global counter that assumes perfect start/end pairs. - Key UI state by provider/query ID and make repeated cleanup harmless.
updatedfires on successful processing. Use application-level monitoring if failed AJAX requests must also be reported.- Prefer delegated click/input handlers for elements inside the replaced wrapper.
References
Verified against JetSmartFilters 3.8.3.1 source:
includes/filters/manager.php:22-112assets/js/public.jschannelsajaxFilters/start-loading,ajaxFilters/updated,ajaxFilters/end-loading,provider/content-renderedassets/lib/jet-plugins/jet-plugins.js
Files (wp-agent-skills)
-
agents
-
openai.yaml 245 B
interface: display_name: "JSF Frontend Events" short_description: "Handle JSF AJAX lifecycle and DOM refresh." default_prompt: "Use $jsf-frontend-events to run JavaScript at JetSmartFilters AJAX start, DOM update, and loading completion."
-
-
SKILL.md 4.8 KB
--- name: jsf-frontend-events description: >- Handle the JetSmartFilters frontend AJAX lifecycle and reinitialize behavior after provider DOM replacement. Use when JavaScript must react when filtering starts, rendered content updates, loading ends, or JSF initializes; when integrating sliders, galleries, analytics, accessibility, or other widgets; or when code references JetSmartFilters.events, ajaxFilters/start-loading, ajaxFilters/updated, ajaxFilters/end-loading, provider/content-rendered, or jet-filter-content-rendered. metadata: wp-skills-author: "Soczó Kristóf" wp-skills-contact: "mailto:lonsdale201@hotmail.com" wp-skills-plugin: "jet-smart-filters" wp-skills-plugin-version-tested: "3.8.3.1" wp-skills-php-min: "7.4" wp-skills-last-updated: "2026-07-21" --- # JetSmartFilters frontend events Subscribe to the JSF event bus and scope every callback. For a listing, the three essential lifecycle channels are: | Channel | Callback arguments | Meaning | |---|---|---| | `ajaxFilters/start-loading` | `provider, queryId` | A real AJAX request started; preloader is active | | `ajaxFilters/updated` | `provider, queryId, response, requestOptions` | Response was processed and provider DOM/fragments were updated | | `ajaxFilters/end-loading` | `provider, queryId` | Loading teardown ran and the preloader was hidden | Use `updated` to read or initialize the new DOM. Use `end-loading` for a global “cycle finished” UI state. They are not aliases. ## Load a companion script after JSF JSF enqueues its public script in `wp_footer` only on pages where filters were rendered. Queue the bridge after JSF has enqueued itself and before footer scripts print: ```php add_action( 'wp_footer', static function (): void { if ( ! wp_script_is( 'jet-smart-filters', 'enqueued' ) ) { return; } wp_enqueue_script( 'acme-jsf-bridge', plugins_url( 'assets/js/jsf-bridge.js', __FILE__ ), array( 'jet-smart-filters' ), '1.0.0', true ); }, 16 ); ``` ## Subscribe with provider/query scoping ```js (() => { const targetProvider = 'jsf-listing'; const targetQueryId = 'catalog-listing'; const isTarget = (provider, queryId) => provider === targetProvider && queryId === targetQueryId; const bind = () => { const bus = window.JetSmartFilters?.events; if (!bus?.subscribe) { return; } bus.subscribe('ajaxFilters/start-loading', (provider, queryId) => { if (!isTarget(provider, queryId)) return; document.querySelector('.catalog-shell')?.setAttribute('aria-busy', 'true'); }); bus.subscribe( 'ajaxFilters/updated', (provider, queryId, response, requestOptions) => { if (!isTarget(provider, queryId)) return; initCatalogWidgets(document.querySelector('#catalog-listing')); } ); bus.subscribe('ajaxFilters/end-loading', (provider, queryId) => { if (!isTarget(provider, queryId)) return; document.querySelector('.catalog-shell')?.setAttribute('aria-busy', 'false'); }); }; if (window.JetSmartFilters?.events) { bind(); } else { document.addEventListener('jet-smart-filters/before-init', bind, { once: true }); } })(); ``` Make `initCatalogWidgets()` idempotent: destroy or detect an existing widget before recreating it. ## Other useful events - DOM `jet-smart-filters/before-init`: JSF global exists; filter discovery has not run. - DOM `jet-smart-filters/inited`: initial filter groups are available. - Bus `provider/content-rendered`: callback receives `provider, $provider` after provider HTML and builder integrations render. It has no query ID, so it is insufficient alone when several instances share a provider. - Legacy jQuery `jet-filter-content-rendered`: document event with `event, $provider, filterGroup, provider, queryId`. Prefer the event bus in new code; keep this only for a legacy integration contract. - A provider element may receive `jet-filter-data-updated` for providers that return data rather than HTML. ## Failure and concurrency rules - A “start” event is not proof that content changed. - In 3.8.3.1 a newer request aborts the previous XHR, and the abort path can skip `end-loading`. Do not maintain an unbounded global counter that assumes perfect start/end pairs. - Key UI state by provider/query ID and make repeated cleanup harmless. - `updated` fires on successful processing. Use application-level monitoring if failed AJAX requests must also be reported. - Prefer delegated click/input handlers for elements inside the replaced wrapper. ## References Verified against JetSmartFilters 3.8.3.1 source: - `includes/filters/manager.php:22-112` - `assets/js/public.js` channels `ajaxFilters/start-loading`, `ajaxFilters/updated`, `ajaxFilters/end-loading`, `provider/content-rendered` - `assets/lib/jet-plugins/jet-plugins.js`
Comments (0)
Sign in to join the conversation.
Reviews (0)
No reviews yet.
No comments yet.