// Bind Backbone to jQuery (defensive)
if (!Backbone.$ && window.jQuery) Backbone.$ = window.jQuery;
// --- Share-state Backbone example (filters) ---
const stateKey = "bb_filters";
const agentKey = "YOUR_AGENT_KEY";
const agent = window.foldspace?.agent?.(agentKey);
const FiltersModel = Backbone.Model.extend({
defaults: { location: "", account: "" }
const FiltersView = Backbone.View.extend({
className: "filters-panel",
<option value="">Any</option>
<option>Tel Aviv</option>
<label style="margin-left:12px">
<option value="">Any</option>
<option>Acme Inc</option>
<option>Umbrella</option>
<pre class="snapshot" style="margin-top:12px"></pre>
"change select[name=location]": "onChange",
"change select[name=account]" : "onChange"
this.listenTo(this.model, "change", this.renderSnapshot);
// Agent -> UI: subscribe for shared state updates
this._handler = (key, nextState) => {
if (key === stateKey) this.model.set(nextState);
agent?.shareState(stateKey, this.model.toJSON(), this._handler);
this.render(); // ensure element exists & template rendered
this.$el.html(this.template());
// Sync current values into selects
this.$("select[name=location]").val(this.model.get("location"));
this.$("select[name=account]").val(this.model.get("account"));
this.$(".snapshot").text(JSON.stringify(this.model.toJSON()));
const $t = this.$(e.currentTarget);
const next = { ...this.model.toJSON(), [$t.attr("name")]: $t.val() };
agent?.shareState(stateKey, next);
agent?.clearState(stateKey);
Backbone.View.prototype.remove.call(this);
// Mount after #filters-root exists
new FiltersView({ model: new FiltersModel() });