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
| Field | Type | Notes |
|---|
name | text | required |
email | email | required |
phone | text | |
company | text | |
role | text | |
website | url | |
tags | multi_select | client / vendor / partner / internal |
notes | textarea | |
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;
}