← All posts

Action types

SELECT static vs js: two dropdown variants in the action bar — which one when

BUTTON is "one action". TOGGLE3 is "three states". SELECT is "pick one of N" — where N can be 2, 5, 50, or dynamic. But SELECT has two variants that look the same and work differently: static (options in storage, editable via UI) and js (options generated by user code, reading from page DOM / fetched from an API). The choice depends on whether your option list is fixed or contextual.

Two variants — the key difference

TraitSELECT staticSELECT js
Source of optionsFrom storage (action.options[])From user JS code (at render time)
Editing optionsManually in options.htmlCode field
Best forFixed presets, language, themeDOM categories, fetch API, dynamic list
Re-renderOnly on storage changeCan refresh options programmatically
Requires code?Yes — what to do after pickYes — generate options + handle pick
Selected value memorydataset.jzValuenative <select>.value

SELECT static — first action

Use case: language switcher for an app with its own i18n.

type: 'select'                  // no 'variant' = static
label: '🌐 Language'
options: [
  { id: 'pl', label: 'Polski',   value: 'pl' },
  { id: 'en', label: 'English',  value: 'en' },
  { id: 'de', label: 'Deutsch',  value: 'de' },
  { id: 'fr', label: 'Français', value: 'fr' },
]
code: |
  // `value` is the selected option's value (or label when no value)
  document.cookie = `lang=${value}; path=/`;
  location.reload();
  JUSTZIX.log(`Language switched to ${value}`);

UI: "🌐 Language" button shows the current value (e.g. "Polski") as its label. Click → dropdown of 4 options → click "English" → cookie + reload. Memory: next visit to the domain → button shows "English" (preserved).

SELECT js — first action

Use case: jumps to anchors in a long article. Dropdown of the page's H2 headings.

type: 'select'
variant: 'js'
label: '📑 Sections'
code: |
  // Code runs at bar render. Return an array of {value, label} (or {value} only).
  return Array.from(document.querySelectorAll('h2')).map(h => ({
    value: h.id || h.textContent.trim().slice(0, 40),
    label: h.textContent.trim().slice(0, 40),
  }));
codeOnSelect: |
  // A second code field — runs after option pick. `value` is the chosen option's value.
  const target = document.getElementById(value)
    || Array.from(document.querySelectorAll('h2')).find(h => h.textContent.includes(value));
  if (target) target.scrollIntoView({ behavior: 'smooth', block: 'start' });

UI: "📑 Sections" button → dropdown of the page's current H2s → click → scroll to that H2. The list regenerates on page load — always up-to-date.

4 colours + dropdown customization

SELECT has 4 colours + 2 for the dropdown (static):

color              → button background (like BUTTON)
colorText          → label text colour (current value)
colorDropdownBg    → background of the opened dropdown
colorOption        → option text colour inside the dropdown
colorSelected      → background of the currently-selected option
colorHover         → option background on hover

All applied via CSS variables (--jz-dropdown-bg, --jz-option-color, etc.) — granular visual control. By default we use a dark dropdown on a light page (contrast).

SELECT js uses a native <select> element — dropdown colours are limited to what the system allows (varies per OS and browser). It's a trade-off: js variant has dynamically generated options but less styling, static variant has full visual control but requires manual editing.

Use case 1 — Environment switcher (static)

Classic: dropdown with 3-5 environments, click → redirects URL.

options: [
  { id: 'dev',  label: '🟢 DEV',   value: 'dev.app.com' },
  { id: 'stg',  label: '🟡 STG',   value: 'staging.app.com' },
  { id: 'prod', label: '🔴 PROD',  value: 'app.com' },
]
code: |
  const path = location.pathname + location.search;
  location.href = `https://${value}${path}`;

For 3 states better use TOGGLE3 (each state visible). For 4+ → SELECT static is cleanest.

Use case 2 — Per-domain bookmarks (js)

List of "favourite" URLs per domain, in localStorage:

variant: 'js'
label: '⭐ Bookmarks'
code: |
  const stored = JSON.parse(localStorage.getItem('jz_bookmarks') || '[]');
  return stored.map(b => ({ value: b.url, label: b.label }));
codeOnSelect: |
  window.location.href = value;

A second BUTTON "+ Bookmark" adds the current URL to the list:

// BUTTON action
const stored = JSON.parse(localStorage.getItem('jz_bookmarks') || '[]');
const label = prompt('Label?') || document.title.slice(0, 30);
stored.push({ url: location.href, label });
localStorage.setItem('jz_bookmarks', JSON.stringify(stored));
JUSTZIX.log(`Bookmark added: ${label}`);
// SELECT js auto-rerenders on reload, so F5 or:
JZ.action('Bookmarks')?.click(); // optional refresh
location.reload();

Use case 3 — Files from an FTP gist (js + fetch)

List of snippets you want to paste into a page's text field, fetched from a private gist:

variant: 'js'
label: '📋 Snippets'
code: |
  const r = await fetch('https://gist.githubusercontent.com/.../snippets.json');
  if (!r.ok) return [];
  const snippets = await r.json();
  return snippets.map(s => ({ value: s.content, label: s.name }));
codeOnSelect: |
  navigator.clipboard.writeText(value);
  JUSTZIX.log(`Copied snippet (${value.length} chars)`);

NOTE: async/await works in code, but render waits for resolve — high latency (>500ms) makes the button flicker. Cache in localStorage with fallback.

Use case 4 — Pick an action to run (static)

Mega-button: dropdown with the 10 most common flows:

options: [
  { id: 'login',    label: '🔑 Login as test',  value: 'login' },
  { id: 'addCart',  label: '🛒 Add 3 items',    value: 'addCart' },
  { id: 'checkout', label: '✅ Quick checkout', value: 'checkout' },
  ...
]
code: |
  // Classic switch — each value maps to a flow
  switch (value) {
    case 'login':
      JZ.click('Login');
      break;
    case 'addCart':
      ['p1','p2','p3'].forEach(id =>
        document.querySelector(`[data-product=${id}] .add`)?.click()
      );
      break;
    case 'checkout':
      JZ.click('Checkout');
      break;
  }
  JUSTZIX.log(`Ran flow: ${value}`);

1 dropdown instead of 10 separate buttons — more compact bar. Trade-off: 1 extra click (open → pick vs. single click).

Pitfalls

What's next

SELECT (static or js) is "pick one of many" — most flexible after BUTTON. Check also the other action types and the API:

Install JustZix — completely free, no account, no server.

Rate this post

No ratings yet — be the first.

Try it yourself

Install JustZix and paste any snippet from this article. Two minutes from zero to a working rule across all your devices.

Get JustZix

Features · How it works · Examples · Use cases