Matt Luo
Matt Luo6mo ago

How does the search bar in https://www.convex.dev/can-do work?

In https://www.convex.dev/can-do, I see that the search bar can find results from the title, headline, and body. Is this search bar using Convex full text search, duplicating the data into a separate table for the purpose of full text search, and concatenating the three properties into one string field? I'm considering building similar functionality. It's not necessary to actually specify how the can-do search bar works, but any general commentary on how to do this would be helpful.
No description
5 Replies
Matt Luo
Matt LuoOP6mo ago
What I'm really trying to understand is how does the information of multiple columns get consolidated into one searchField? Is it a delimited concatenation of some sort? That's what I'm inferring since searchField must be of type string Looking further into Discord, seems like this can-do page is designed a combination of Convex CMS (not yet released) and Sanity.io CMS. So perhaps for this specific webpage, Sanity's GROQ query language is used under the hood
v
v6mo ago
i think the search is done in the browser
function d(e) {
let {features: t} = e
, [n,a] = (0,
o.useState)("")
, i = t.filter(e=>{
if (!n)
return !0;
{
var t;
let r = n.toLowerCase();
return e.title.toLowerCase().includes(r) || (null === (t = e.subtitle) || void 0 === t ? void 0 : t.toLowerCase().includes(r)) || e.summary.toLowerCase().includes(r) || e.description.toLowerCase().includes(r)
}
}
);
return (0,
r.jsxs)("div", {
children: [(0,
r.jsxs)("div", {
className: "mb-8 flex max-w-lg flex-col gap-2 lg:max-w-2xl lg:flex-row lg:items-center lg:gap-4",
children: [(0,
r.jsx)("span", {
className: "whitespace-nowrap font-bold",
children: "What do you want to build?"
}), (0,
r.jsx)(l.Z, {
type: "search",
label: "Filter features",
id: "search",
onChange: e=>a(e.target.value)
})]
}), (0,
r.jsx)("div", {
className: "grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3 lg:gap-6",
children: null == i ? void 0 : i.map(e=>(0,
r.jsx)(c, {
feature: e
}, e.slug))
})]
})
}
},
function d(e) {
let {features: t} = e
, [n,a] = (0,
o.useState)("")
, i = t.filter(e=>{
if (!n)
return !0;
{
var t;
let r = n.toLowerCase();
return e.title.toLowerCase().includes(r) || (null === (t = e.subtitle) || void 0 === t ? void 0 : t.toLowerCase().includes(r)) || e.summary.toLowerCase().includes(r) || e.description.toLowerCase().includes(r)
}
}
);
return (0,
r.jsxs)("div", {
children: [(0,
r.jsxs)("div", {
className: "mb-8 flex max-w-lg flex-col gap-2 lg:max-w-2xl lg:flex-row lg:items-center lg:gap-4",
children: [(0,
r.jsx)("span", {
className: "whitespace-nowrap font-bold",
children: "What do you want to build?"
}), (0,
r.jsx)(l.Z, {
type: "search",
label: "Filter features",
id: "search",
onChange: e=>a(e.target.value)
})]
}), (0,
r.jsx)("div", {
className: "grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3 lg:gap-6",
children: null == i ? void 0 : i.map(e=>(0,
r.jsx)(c, {
feature: e
}, e.slug))
})]
})
}
},
also https://discord.com/channels/1019350475847499849/1220856317095444653/1221885518212497448
Matt Luo
Matt LuoOP6mo ago
Thanks V, good to see you again!
v
v6mo ago
How are ya bro
ian
ian6mo ago
yes we load all features and do client side filtering