Note: Special Districts, Corporation, Nonprofit, Higher Education tags do not work yet (not enough articles tagged with these). Contact Us if you need help finding an article!
/* ===== TS Fast Filter – self-contained styles ===== */
:root { --main-green:#2e6243; --main-green-dark:#3a7e47; --main-green-light:#a9ccb5; --accent-yellow:#f8de4c; --gray-light:#f8f9fa; --gray-mid:#e9ecef; --gray-dark:#555; --font-base:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif; }
.ts-fast-filter *{box-sizing:border-box}
.ts-fast-filter{font-family:var(--font-base);color:var(--gray-dark);background:#f0f2f5}
.ts-fast-filter .container{width:min(1640px,100%);margin:0 auto;padding:2rem 3rem;display:flex;gap:2rem;flex-wrap:nowrap}
.tsff-card{background:#fff;border-radius:1rem;padding:2rem;box-shadow:0 4px 16px rgba(0,0,0,.06)}
.tsff-sidebar{width:400px;flex-shrink:0}
.tsff-results{flex:1;overflow:hidden}
.tsff-h2{font-size:1.5rem;margin:0 0 1.25rem 0;font-weight:600;color:#2c3e50}
.tsff-grid{display:flex;flex-direction:column;gap:1rem;margin-bottom:1rem}
.tsff-label{display:block;font-size:.875rem;font-weight:500;text-transform:uppercase;letter-spacing:.5px;margin-bottom:.5rem;color:#2c3e50}
.tsff-input{width:100%;padding:.75rem 1rem;border:2px solid var(--gray-mid);border-radius:.5rem;font-size:1rem}
.tsff-help{color:#777;margin:.35rem 0 0;font-size:.85rem}
.tsff-checks{display:flex;flex-direction:column;gap:.5rem;margin-top:.25rem}
.tsff-check{display:flex;align-items:center;gap:.6rem;padding:.5rem .75rem;border:2px solid var(--gray-mid);background:var(--gray-light);border-radius:.5rem;cursor:pointer;transition:.15s}
.tsff-check:hover{background:#e3f2fd;border-color:var(--main-green-light);transform:translateX(3px)}
.tsff-check input{width:18px;height:18px;accent-color:var(--main-green-dark)}
.tsff-actions{display:flex;flex-direction:column;gap:1rem;margin-top:1rem}
.tsff-btn{padding:.75rem 1.5rem;border:none;border-radius:.5rem;font-size:.875rem;font-weight:600;text-transform:uppercase;letter-spacing:.5px;cursor:pointer}
.tsff-btn--primary{background:var(--main-green);color:#fff;border:2px solid var(--main-green)}
.tsff-btn--primary:hover{background:var(--main-green-dark)}
.tsff-btn--ghost{background:var(--main-green-light);color:#fff}
.tsff-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:2rem;padding-bottom:1rem;border-bottom:2px solid var(--gray-mid)}
.tsff-header h3{margin:0 0 .5rem 0;font-size:1.5rem;color:#2c3e50}
.tsff-count{font-size:.9rem;color:#555}
.tsff-sort{min-width:210px;padding:.6rem .9rem;border:2px solid var(--gray-mid);border-radius:.5rem}
.tsff-grid-results{display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));gap:1.5rem}
.tsff-item{background:#fff;border-radius:.75rem;overflow:hidden;box-shadow:0 4px 12px rgba(0,0,0,.1);transition:.25s;text-decoration:none;color:inherit;display:block}
.tsff-item:hover{transform:translateY(-5px);box-shadow:0 8px 25px rgba(0,0,0,.1);background:#fcfcfb}
.tsff-img{width:100%;height:200px;background:#e9ecef center/contain no-repeat}
.tsff-img--empty{display:flex;align-items:center;justify-content:center;color:#666;background:linear-gradient(135deg,var(--gray-light),var(--gray-mid))}
.tsff-body{padding:1.25rem}
.tsff-title{font-size:1.1rem;font-weight:700;color:#2c3e50;text-decoration:underline;text-underline-offset:.12em}
.tsff-meta{display:flex;flex-wrap:wrap;gap:.4rem;margin:.6rem 0 1rem}
.tsff-chip{background:var(--main-green-light);color:#fff;padding:.15rem .6rem;border-radius:1rem;font-size:.75rem;font-weight:600}
.tsff-badges{display:flex;flex-wrap:wrap;gap:.4rem}
.tsff-badge{background:var(--accent-yellow);color:#333;padding:.15rem .6rem;border-radius:1rem;font-size:.75rem;font-weight:600}
.tsff-loading,.tsff-empty{text-align:center;padding:2.5rem 1.5rem;color:#555}
.tsff-pager{display:flex;justify-content:center;margin-top:1.5rem}
.tsff-more{background:var(--main-green);color:#fff;border:none;padding:.75rem 2rem;border-radius:.5rem;font-size:1rem;font-weight:700;cursor:pointer}
.tsff-more[disabled]{opacity:.6;cursor:not-allowed}
.tsff-error{background:#fee;border:2px solid #fcc;color:#b33;border-radius:.5rem;padding:1rem;margin:1rem 0}
/* Tag buttons styles */
.tsff-tag-buttons{background:#fff;border-radius:1rem;padding:1.5rem;box-shadow:0 4px 16px rgba(0,0,0,.06);margin-bottom:2rem}
.tsff-tag-buttons h2{font-size:1.25rem;margin:0 0 1rem 0;font-weight:600;color:#2c3e50}
.tsff-tag-grid{display:flex;flex-wrap:wrap;gap:.75rem}
.tsff-tag-btn{background:var(--gray-light);color:var(--gray-dark);border:2px solid var(--gray-mid);padding:.5rem 1rem;border-radius:.5rem;font-size:.875rem;font-weight:500;cursor:pointer;transition:.2s;text-decoration:none;display:inline-block}
.tsff-tag-btn:hover{background:var(--main-green-light);color:#fff;border-color:var(--main-green);transform:translateY(-2px)}
.tsff-tag-btn.active{background:var(--main-green);color:#fff;border-color:var(--main-green-dark)}
.tsff-tag-clear{background:var(--accent-yellow);color:#333;border:2px solid #f0c808}
.tsff-tag-clear:hover{background:#f0c808;color:#222}
@media (max-width: 900px){
.ts-fast-filter .container{flex-direction:column;padding:1.25rem}
.tsff-sidebar{width:100%}
.tsff-grid-results{grid-template-columns:1fr}
.tsff-tag-grid{gap:.5rem}
.tsff-tag-btn{font-size:.8rem;padding:.4rem .8rem}
}
/* place buttons under search; row on desktop, stack on mobile */
.tsff-actions--inline{display:flex;gap:.75rem;margin-top:.75rem}
@media (max-width:900px){.tsff-actions--inline{flex-direction:column}}
Newest First
Oldest First
Name A–Z
Name Z–A
Relevance (when searching)
/* ===== TS Fast Filter – JS ===== */
const FALLBACK_IMG = 'https://tripepi2025.wpenginepowered.com/wp-content/uploads/2025/07/TS-Logo.png';
// Discover REST root reliably from WP's link tag
const REST_ROOT = (document.querySelector('link[rel="https://api.w.org/"]')?.href) || (window.location.origin + '/wp-json/');
const TS_ENDPOINT = new URL('ts/v1/search-posts', REST_ROOT).toString();
const WP_POSTS = new URL('wp/v2/posts', REST_ROOT).toString();
const PER_PAGE = 12;
const DEBOUNCE_MS = 350;
/* Content types with testimonials added */
const CONTENT_TYPES = ['insights','news','case-studies','ts-portfolio','client-logos','testimonials'];
/* Your requested filter sets */
const SERVICE_SLUGS = [
'ballot-measure-outreach','communications-support','community-choice-aggregation-programs',
'corporations','districting-outreach-services','graphic-design-and-branding','local-governments',
'media-intelligence','non-profit','organics-recycling-communication','photography',
'special-districts','videography-case-studies','web-design-and-support-services','technology' // Websites
];
const SECTOR_SLUGS = [
'community-choice-aggregation-cca','corporations-client-logos','higher-education-client-logos',
'local-governments-client-logos','nonprofits','special-districts-client-logos'
];
// Add the tag slugs
const TAG_SLUGS = [
'local-government','special-district','corporation','higher-education','nonprofit','cca',
'ballot-measure-outreach','communication-support','districting-outreach-services',
'graphic-design-and-branding','media-intelligence','photography-and-videography',
'web-design-and-support-services','organics-recycling-communication',
'recruitment-and-organizational-development','hr-news','conferences','sponsorships','associations'
];
let page = 1, hasMore = false, isLoading = false;
let postsAccum = [];
let activeTag = ''; // Track active tag filter
/* Utilities */
const $ = (s)=>document.querySelector(s);
const $$=(s)=>Array.from(document.querySelectorAll(s));
const debounce=(fn,ms)=>{let t;return(...a)=>{clearTimeout(t);t=setTimeout(()=>fn(...a),ms)}}
const stripHTML=(html)=>html?.replace(/]*>/g,'').trim() || '';
function labelize(slug){
const map = {
// content types
'insights':'Insights','news':'News','case-studies':'Case Study','ts-portfolio':'Portfolio','client-logos':'Client Logo','testimonials':'Testimonial',
// case study filters (services)
'ballot-measure-outreach':'Ballot Measure Outreach',
'communications-support':'Communications Support',
'community-choice-aggregation-programs':'Community Choice Aggregation Programs',
'corporations':'Corporations',
'districting-outreach-services':'Districting Outreach Services',
'graphic-design-and-branding':'Graphic Design & Branding',
'local-governments':'Local Governments',
'media-intelligence':'Media Intelligence',
'non-profit':'Non Profit',
'organics-recycling-communication':'Organics Recycling Communication',
'photography':'Photography',
'special-districts':'Special Districts',
'videography-case-studies':'Videography',
'web-design-and-support-services':'Web Design & Support Services',
'technology':'Websites',
// client logo filters (sectors)
'community-choice-aggregation-cca':'Community Choice Aggregation (CCA)',
'corporations-client-logos':'Corporations',
'higher-education-client-logos':'Higher Education',
'local-governments-client-logos':'Local Governments',
'nonprofits':'Nonprofits',
'special-districts-client-logos':'Special Districts',
// tag filters
'local-government':'Local Government',
'special-district':'Special District',
'corporation':'Corporation',
'higher-education':'Higher Education',
'nonprofit':'Nonprofit',
'cca':'CCA',
'communication-support':'Communication Support',
'photography-and-videography':'Photography and Videography',
'recruitment-and-organizational-development':'Recruitment and Organizational Development (TSTS)',
'hr-news':'HR News',
'conferences':'Conferences',
'sponsorships':'Sponsorships',
'associations':'Associations'
};
return map[slug] || slug.replace(/-/g,' ').replace(/\b\w/g,m=>m.toUpperCase());
}
/* API - Updated to include tags parameter */
async function tsSearch({q='',page=1,perPage=PER_PAGE,orderby='date',order='DESC',ct=[],svcs=[],secs=[],tags=[]}={}){
const u = new URL(TS_ENDPOINT);
if (q && q.length>=3) u.searchParams.set('q', q);
u.searchParams.set('page', page);
u.searchParams.set('per_page', perPage);
u.searchParams.set('orderby', orderby);
u.searchParams.set('order', order);
ct.forEach(v=>u.searchParams.append('content_types[]', v));
svcs.forEach(v=>u.searchParams.append('services[]', v));
secs.forEach(v=>u.searchParams.append('sectors[]', v));
tags.forEach(v=>u.searchParams.append('tags[]', v)); // Add tags parameter
const res = await fetch(u.toString());
if(!res.ok) throw new Error(`Search HTTP ${res.status}`);
return res.json();
}
async function hydrate(ids){
if(!ids.length) return [];
const u = new URL(WP_POSTS);
u.searchParams.set('_embed','1');
u.searchParams.set('include', ids.join(','));
u.searchParams.set('orderby','include');
u.searchParams.set('per_page', Math.min(100, ids.length));
const res = await fetch(u.toString());
if(!res.ok) throw new Error(`Hydrate HTTP ${res.status}`);
const rows = await res.json();
return rows.map(p=>{
const img = p._embedded?.['wp:featuredmedia']?.[0]?.source_url || FALLBACK_IMG;
const terms = p._embedded?.['wp:term']?.[0] || [];
const slugs = terms.map(t=>t.slug);
return {
id: p.id,
title: p.title?.rendered || 'Untitled',
permalink: p.link,
excerpt: stripHTML(p.excerpt?.rendered),
date: p.date,
img,
contentTypes: slugs.filter(s=>CONTENT_TYPES.includes(s)),
services: slugs.filter(s=>SERVICE_SLUGS.includes(s)),
sectors: slugs.filter(s=>SECTOR_SLUGS.includes(s)),
tags: slugs.filter(s=>TAG_SLUGS.includes(s)), // Add tags
};
});
}
/* Render */
function render(items,{append=false}={}){
const grid = $('#tsff-grid');
const empty = $('#tsff-empty');
if(!append){ grid.innerHTML=''; postsAccum=[]; }
if(!items.length && !append){ grid.style.display='none'; empty.style.display='block'; return; }
empty.style.display='none'; grid.style.display='grid';
postsAccum = append ? postsAccum.concat(items) : items;
const html = items.map(p=>{
const img = ``;
const chips = []
.concat(p.sectors.map(s=>`${labelize(s)}`))
.concat(p.services.map(s=>`${labelize(s)}`))
.concat(p.tags.map(s=>`${labelize(s)}`)) // Include tags in chips
.join('');
const badges = p.contentTypes.map(c=>`${labelize(c)}`).join('');
const excerpt = p.excerpt ? `
`;
}).join('');
grid.insertAdjacentHTML('beforeend', html);
$('#tsff-count').textContent = `Showing ${postsAccum.length}${hasMore?'+':''}`;
$('#tsff-pager').style.display = hasMore ? 'flex' : 'none';
}
/* Controller */
function getChecked(name){ return $$(`input[name="${name}"]:checked`).map(i=>i.value); }
function getSort(){
const v = $('#tsff-sort').value;
if (v==='date-asc') return {orderby:'date',order:'ASC'};
if (v==='date-desc') return {orderby:'date',order:'DESC'};
if (v==='title-asc') return {orderby:'title',order:'ASC'};
if (v==='title-desc')return {orderby:'title',order:'DESC'};
if (v==='relevance') return {orderby:'relevance',order:'DESC'};
return {orderby:'date',order:'DESC'};
}
async function run({append=false}={}){
if(isLoading) return;
isLoading = true;
$('#tsff-error').style.display='none';
$('#tsff-loading').style.display='block';
try{
const q = $('#tsff-search').value.trim();
const {orderby,order} = getSort();
const ct = getChecked('ct');
const svcs = getChecked('svc'); // Case Study filters
const secs = getChecked('sec'); // Client Logo filters
const tags = activeTag ? [activeTag] : []; // Use active tag if set
const payload = await tsSearch({ q, page, perPage: PER_PAGE, orderby, order, ct, svcs, secs, tags });
hasMore = !!payload.has_more;
const hydrated = await hydrate(payload.ids);
render(hydrated,{append});
}catch(e){
console.error(e);
const el = $('#tsff-error'); el.textContent = e.message || 'Search failed'; el.style.display='block';
}finally{
$('#tsff-loading').style.display='none';
isLoading = false;
}
}
/* Tag button handling */
function setActiveTag(tag){
activeTag = tag;
// Update button appearances
$$('.tsff-tag-btn').forEach(btn => {
btn.classList.toggle('active', btn.dataset.tag === tag);
});
// Reset page and run search
page = 1;
run();
}
/* Events */
const debounced = debounce(()=>{ page=1; run(); }, DEBOUNCE_MS);
document.addEventListener('DOMContentLoaded', ()=>{
// initial load (Insights + News checked by default)
page=1; run();
// Tag button events
$$('.tsff-tag-btn').forEach(btn => {
btn.addEventListener('click', () => {
setActiveTag(btn.dataset.tag);
});
});
$('#tsff-apply').addEventListener('click', ()=>{ page=1; run(); });
$('#tsff-clear').addEventListener('click', ()=>{
$('#tsff-search').value = '';
$$('input[name="ct"]').forEach(i=>i.checked=false);
$$('input[name="ct"][value="insights"], input[name="ct"][value="news"]').forEach(i=>i.checked=true);
$$('input[name="svc"], input[name="sec"]').forEach(i=>i.checked=false);
$('#tsff-sort').value = 'date-desc';
setActiveTag(''); // Clear active tag
page=1; run();
});
$('#tsff-more').addEventListener('click', ()=>{
if(!hasMore) return; page += 1; run({append:true});
});
$('#tsff-search').addEventListener('input', debounced);
['ct','svc','sec'].forEach(name=>{
$(`input[name="${name}"]`).forEach(cb=>cb.addEventListener('change', ()=>{ page=1; run(); }));
});
$('#tsff-sort').addEventListener('change', ()=>{ page=1; run(); });
});
Results
Loading…
${p.excerpt}
` : ''; return ` ${img}${p.title}
${excerpt}
${badges}


