Backbone 'Reporting Filter' Shared State Example



// 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.eucera?.agent?.(agentKey);

const FiltersModel = Backbone.Model.extend({
  defaults: { location: "", account: "" }
});

const FiltersView = Backbone.View.extend({
  el: "#filters-root",
  className: "filters-panel",
  template: _.template(`
          <label>
            Location
            <select name="location">
              <option value="">Any</option>
              <option>NYC</option>
              <option>London</option>
              <option>Tel Aviv</option>
              <option>Remote</option>
            </select>
          </label>
          <label style="margin-left:12px">
            Account
            <select name="account">
              <option value="">Any</option>
              <option>Acme Inc</option>
              <option>Globex</option>
              <option>Initech</option>
              <option>Umbrella</option>
            </select>
          </label>
          <pre class="snapshot" style="margin-top:12px"></pre>
        `),

  events: {
    "change select[name=location]": "onChange",
    "change select[name=account]" : "onChange"
  },

  initialize() {
    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
  },

  render() {
    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.renderSnapshot();
    return this;
  },

  renderSnapshot() {
    this.$(".snapshot").text(JSON.stringify(this.model.toJSON()));
  },

  onChange(e) {
    const $t = this.$(e.currentTarget);
    const next = { ...this.model.toJSON(), [$t.attr("name")]: $t.val() };
    this.model.set(next);
    // UI -> Agent
    agent?.shareState(stateKey, next);
    this.renderSnapshot();
  },

  remove() {
    agent?.clearState(stateKey);
    Backbone.View.prototype.remove.call(this);
  }
});

// Mount after #filters-root exists
new FiltersView({ model: new FiltersModel() });