Skip to content

Data binding

Display data from your registered queries directly in the DOM.

Single record

gg-data runs a query and populates [gg-field] descendants from the returned object:

html
<div gg-data="post_by_id">
  <h1 gg-field="title">Loading...</h1>
  <p gg-field="body"></p>
</div>

gg-field supports dot-paths for nested data (e.g. author.name).

Form pre-fill

gg-data-form runs a query and sets value / checked on inputs by their name attribute:

html
<form gg-data-form="post_by_id">
  <input name="title" />
  <textarea name="body"></textarea>
</form>

Lists

gg-data-list runs a query that returns an array, and clones a [gg-list-template] element for each record:

html
<ul gg-data-list="posts_list">
  <li gg-list-template>
    <h3 gg-field="title"></h3>
    <span gg-field="author.name"></span>
  </li>
</ul>

Passing data to web components / React

Elements that manage their own DOM (custom elements wrapping React, Lit, etc.) read from the container's __ggRecord property. Every gg-data, gg-data-form, and cloned gg-data-list row stamps the record there after the query resolves, and the engine fires a gg-data-ready CustomEvent on the same element with detail.record.

html
<form gg-data-form="post_form">
  <input name="title" />
  <my-select name="school_id"></my-select>
</form>
js
// Inside <my-select> — wait for the parent record, then hydrate.
const form = host.closest("form");
form.addEventListener("gg-data-ready", (e) => {
  hydrate(e.detail.record);
});
if (form.__ggRecord) hydrate(form.__ggRecord); // already populated

The event bubbles, so listeners on one form/container never fire for another. From inside a shadow root, the host element's parent chain is unreachable via closest() directly — walk out with getRootNode().host first.

TIP

If the component re-runs its own search query against the library, it can call any registered query imperatively via app.queries[id](app.context, params). The library exposes the App as window.ggApp automatically (and dispatches a gg-app-ready event on document with detail.app), so custom-code components can reach it without any plumbing. Pass expose: false to init() to opt out.

Re-running on URL changes

Add gg-data-on to re-run a query when specific URL params change:

html
<div gg-data="post_by_id" gg-data-on="id">
  <h1 gg-field="title"></h1>
</div>

Combine with gg-query-bind (see URL params) to drive live search:

html
<input gg-query-bind="q" gg-query-debounce="300" />

<ul gg-data-list="search_posts" gg-data-on="q">
  <li gg-list-template><span gg-field="title"></span></li>
</ul>

Released under the MIT License.