Skip to content

Server-Side Example

Loading Scheduler example…

Source code
import { applyControlPresentation } from '@revolist/ui';
import { CalendarEditorDialogPlugin } from '@revolist/revogrid-pro';
import { defineCustomElements } from '@revolist/revogrid/loader';
import { EventSchedulerPlugin } from '@revolist/scheduler';
import { currentTheme } from '../../composables/useRandomData';
import { createRemoteSchedulerDemo } from './demo';
import './styles.scss';
defineCustomElements();
export function load(parentSelector: string, _rows: any[] = []) {
const parent = document.querySelector(parentSelector);
if (!parent) return () => {};
const model = createRemoteSchedulerDemo();
const root = document.createElement('section');
root.className = 'scheduler-remote-demo';
root.innerHTML = `<div class="scheduler-remote-demo__controls">
<button class="rv-btn" data-action="rename">Rename booking</button>
<button class="rv-btn" data-action="refresh">Refresh from server</button>
<button class="rv-btn" data-action="calendars">Working calendars</button>
<label><input type="checkbox" data-action="reject" /> Reject next save</label>
<label title="Changes appear immediately and revert if the server rejects the save."><input type="checkbox" data-action="optimistic" checked /> Update immediately</label>
</div>`;
const rename = root.querySelector<HTMLButtonElement>('[data-action="rename"]')!;
const refresh = root.querySelector<HTMLButtonElement>('[data-action="refresh"]')!;
const calendars = root.querySelector<HTMLButtonElement>('[data-action="calendars"]')!;
calendars.onclick = () => model.openCalendars();
const reject = root.querySelector<HTMLInputElement>('[data-action="reject"]')!;
const optimistic = root.querySelector<HTMLInputElement>('[data-action="optimistic"]')!;
rename.onclick = () => model.rename(); refresh.onclick = () => { void model.refresh(); };
reject.onchange = () => model.rejectNext(reject.checked);
optimistic.onchange = () => model.optimistic(optimistic.checked);
applyControlPresentation(root);
const grid = document.createElement('revo-grid');
grid.className = 'scheduler-remote-demo__grid'; grid.hideAttribution = true;
grid.theme = currentTheme().isDark() ? 'darkMaterial' : 'material';
grid.plugins = [EventSchedulerPlugin, CalendarEditorDialogPlugin]; grid.columns = []; grid.eventScheduler = model.state.config;
const render = (state: typeof model.state) => {
rename.disabled = refresh.disabled = calendars.disabled = !state.ready || state.busy;
reject.disabled = optimistic.disabled = state.busy;
reject.checked = state.rejectNext;
optimistic.checked = state.config.remote?.optimistic !== false;
};
const feedback = document.createElement('div');
feedback.className = 'scheduler-remote-demo__activity';
const connect = () => { void model.connect(grid, render, feedback); };
grid.addEventListener('aftergridinit', connect);
root.append(grid, feedback); parent.append(root); grid.source = [];
render(model.state);
return () => { grid.removeEventListener('aftergridinit', connect); model.disconnect(); grid.remove(); root.remove(); };
}

This demo uses native fetch() with an isolated browser backend. Saved events stay outside the grid, and a short delay makes pending saves visible. No Node server is needed; reloading resets the data.

  1. Rename the booking to save a change and receive the server’s accepted event.
  2. Enable Reject next save, then rename again to see the edit roll back.
  3. Turn off Optimistic updates, then rename again. The saved title stays visible until the server accepts the change.
  4. Open Working calendars to edit working days, hours and exceptions. Choose Save to apply or Cancel to discard.
  5. Choose Refresh from server to reload saved data without resubmitting a save.

Expand the source panel above to compare all four frameworks and inspect the HTTP client and backend. To connect your own API, replace the demo’s loadEvents, loadResources and commitMutation callbacks.

Open the full Scheduler demo.

See Remote Data for query policy and Mutations and App-Owned Saving for rollback and receipts. This demo covers accepted and rejected saves; durable receipt recovery and backend deployment are outside its scope.