BUTTON: the simplest JustZix action — fire-and-forget with per-button customization
One action type is so basic it gets skipped in posts. BUTTON — click → run code → done. No state, no memory, no options list to choose from. It's a "stateless function" in the action bar. But that simplicity is precisely what makes it the strongest: BUTTON is 80% of all actions in a typical JustZix setup, because most things you want to do are "click = X".
When BUTTON, when something else?
| Need | Action type | Memory? |
|---|---|---|
| "Click = run X" | BUTTON | No |
| "Pick one of N options" | SELECT | Yes |
| "Type text and run" | INPUT | Yes |
| "Keep a draft / notes" | TEXTAREA | Yes |
| "Control range 0-100" | SLIDER | Yes |
| "3 known states (Dev/Stg/Prod)" | TOGGLE3 | Yes |
Only BUTTON is stateless. All other types hold a value per action.id (sessionStorage + chrome.storage.local backup). BUTTON = pure function: input (click) → output (effect on the page).
First BUTTON action
In the JustZix editor → rule → action bar → "+ BUTTON". Config:
label: "🚀 Fill demo" // button text + icon
code: |
// value, $el, $action automatically injected as extras
document.querySelector('[name=email]').value = 'demo@test.com';
document.querySelector('[name=name]').value = 'Demo User';
document.querySelectorAll('input, textarea').forEach(el =>
el.dispatchEvent(new Event('input', { bubbles: true }))
);
JUSTZIX.log('Demo data filled.');
Click "🚀 Fill demo" → form fields filled, the page's framework (React/Vue/Angular) sees the input event → state updated.
Two colours + customStyles
BUTTON has 2 basic colours:
color → button background
colorText → label text colour (and icon if emoji)
Plus an optional customStyles object — granular CSS override:
customStyles: {
padding: '8px 16px', // default 6px 12px
fontSize: '14px', // default 12px
borderRadius: '4px', // default 6px
fontFamily: 'Fira Code, monospace',
fontWeight: '600',
letterSpacing: '0.5px',
}
Render: each customStyles property goes through el.style.setProperty(key, value, 'important') — wins over JustZix default rules. This lets you match buttons to the brand style of the site you're modifying (e.g. Bootstrap blue, Material Design ripple, per-domain customization).
What's available inside the code field
BUTTON code runs in MAIN world (chrome.scripting.executeScript world:'MAIN') via background.js. Automatically available:
window.JZ— action helpers (JZ.click, JZ.value, JZ.setValue, etc.) when not collisionedwindow.JUSTZIX— logger (since v2.13.76, brand name, always available)$el— reference to the button (HTMLElement) — useful if you want to modify the button itself after click$action— object{id, label, type, el}— meta-info about the action- Full page context — all window globals of the page (jQuery, React internals, etc.)
- async/await OK — the wrapper is an async IIFE
Use case 1 — Quick chains
Frequently-repeated action sequences can be automated by a single button:
// Action "🔥 Test flow"
JZ.click('Login'); // clicks the BUTTON action labelled "Login"
await new Promise(r => setTimeout(r, 500));
JZ.click('Add to cart');
await new Promise(r => setTimeout(r, 500));
JZ.click('Checkout');
JUSTZIX.log('Test flow complete.');
Chain of 3 buttons in 1 → clicking "Test flow" fires them sequentially. Each of the 3 sub-buttons can still be reused individually.
Use case 2 — Conditional execution
BUTTON is "execute on demand", so it's perfect for destructive scripts with a URL guard:
// Action "🗑️ Clear staging cart"
if (!location.hostname.includes('staging')) {
JUSTZIX.error('Only on staging! Aborting.');
alert('This button only works on staging.');
return;
}
const items = document.querySelectorAll('.cart-item .remove-btn');
items.forEach(btn => btn.click());
JUSTZIX.log(`Cleared ${items.length} items.`);
No auto-run risk (like JS pane), no text field to fill manually — just a click when you want, where you want.
Use case 3 — Visual feedback after click
Old classic: a button that changes label on success:
// Action "💾 Save state"
const oldLabel = $el.textContent;
$el.textContent = '⏳ Saving...';
$el.style.opacity = '0.6';
try {
await fetch('/api/state', {
method: 'POST',
body: JSON.stringify(getState()),
});
$el.textContent = '✓ Saved';
setTimeout(() => {
$el.textContent = oldLabel;
$el.style.opacity = '';
}, 2000);
} catch (e) {
$el.textContent = '✗ Error';
JUSTZIX.error('Save failed', e);
}
$el is the button's DOM reference — modify it directly. Visual feedback without external state.
Use case 4 — Multiple buttons, one flow
Instead of one "Full QA flow" button, 5 separate ones in a visual cluster:
// Action "1️⃣"
JUSTZIX.log('Step 1: login');
JZ.click('Login as test user');
// Action "2️⃣"
JUSTZIX.log('Step 2: navigate');
location.href = '/admin/orders';
// Action "3️⃣"
JUSTZIX.log('Step 3: filter');
document.querySelector('select.status').value = 'pending';
document.querySelector('select.status').dispatchEvent(new Event('change'));
Each step as a separate button → user sees visually where they are in the flow. Plus they can repeat any step without restarting.
Pitfalls
- BUTTON code MUST have a label. The
isActionRenderablecheck requires both (label + code). An action without code will never render. - customStyles via setProperty(..., 'important') wins over most page CSS, but some site styles use specific pseudo-elements (::before with content) — customStyles can't help there. Workaround: add a CSS rule in the same rule's CSS section (cascading !important still wins).
- Code runs in MAIN world. Meaning: page scripts (React, Vue, jQuery) see the events you dispatch. But also: page scripts can interfere with your code (e.g. override fetch, console). The Output Console fix via chrome.scripting.executeScript helps (CSP-immune), but the general principle: page and your code share scope.
- Async errors in code won't show in Output Console automatically. Wrap try/catch around await statements + JUSTZIX.error explicit. Or: use window.addEventListener('error') globally in a JS rule.
- No built-in throttle/debounce. click-click-click = 3 independent code invocations. If the code is expensive (fetch, DOM rewrite), guard it yourself:
let busy = false;+ guard.
What's next
BUTTON is the backbone of all JustZix toolbars. Check also other action types:
- SELECT static vs js — pick from a list of options
- INPUT — single-line text + Enter→run
- TEXTAREA — multi-line scratch pad
- SLIDER — native range controller
- TOGGLE3 — 3-state segmented controls
- window.JZ + JUSTZIX helpers — programmatic API
Install JustZix — completely free, no account, no server.
Rate this post
No ratings yet — be the first.