Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.usehasp.com/llms.txt

Use this file to discover all available pages before exploring further.

A searchable contact directory demonstrating text search with contains, multi_select tag filtering, and email/url field types.

Schema

Entity: Contacts — key: contacts
FieldTypeNotes
nametextrequired
emailemailrequired
phonetext
companytext
roletext
websiteurl
tagsmulti_selectclient / vendor / partner / internal
notestextarea

Key Patterns

Text Search with Debounce

let searchTimer;
document.getElementById('search').addEventListener('input', () => {
  clearTimeout(searchTimer);
  searchTimer = setTimeout(loadContacts, 300);
});
Debouncing prevents a request on every keystroke. 300 ms is a good default.

Filter by Tag

const result = await sdk.listRecords('contacts', {
  filter: { tags: { contains: 'vendor' } },
  sort: 'name:asc',
});
contains on a multi_select field matches any record where the array includes the given value.

Combined Search + Tag Filter

const filter = {};
if (query) filter.name = { contains: query };
if (tag) filter.tags = { contains: tag };

const result = await sdk.listRecords('contacts', {
  filter: Object.keys(filter).length ? filter : undefined,
  sort: 'name:asc',
});
Multiple filter conditions use AND logic — both must match.

Reading multi_select Values

// c.tags is an array of strings, or null/undefined if empty
const selectedTags = Array.isArray(c.tags) ? c.tags : [];

Restoring Checkboxes on Edit

document.querySelectorAll('input[name="tags"]').forEach(cb => {
  cb.checked = selectedTags.includes(cb.value);
});

Null-Safe HTML Escaping

Always guard escapeHtml against null/undefined values — optional fields may be absent on older records:
function escapeHtml(str) {
  if (str == null) return '';
  const div = document.createElement('div');
  div.textContent = String(str);
  return div.innerHTML;
}