Build dynamic filter UIs with the V2 JSON Layout API
The default pills style provides a clean, modern appearance for status filters and category selectors.
RSL.JSONLayout.renderLayout('#container', {
version: 2,
layoutId: "filter-pills-demo",
wrapper: { renderMode: 'direct' },
items: [{
content: {
type: "filter",
key: "status",
style: "pills",
defaultValue: "all",
label: "Filter by status",
options: [
{ value: "all", label: "All" },
{ value: "active", label: "Active" },
{ value: "pending", label: "Pending" },
{ value: "completed", label: "Completed" }
]
}
}]
});
// Subscribe to filter changes
RSL.FilterBus.subscribe('my-demo', function(state) {
console.log('Status filter:', state.status);
}, { keys: ['status'] });
Connected button group style with FontAwesome icons - perfect for view mode selectors.
RSL.JSONLayout.renderLayout('#container', {
version: 2,
layoutId: "filter-buttons-demo",
wrapper: { renderMode: 'direct' },
items: [{
content: {
type: "filter",
key: "viewMode",
style: "buttons",
defaultValue: "grid",
label: "Select view mode",
options: [
{ value: "grid", label: "Grid", icon: "fas fa-th" },
{ value: "list", label: "List", icon: "fas fa-list" },
{ value: "compact", label: "Compact", icon: "fas fa-bars" }
]
}
}]
});
Allow users to select multiple values simultaneously. Great for tag-based filtering.
RSL.JSONLayout.renderLayout('#container', {
version: 2,
layoutId: "filter-chips-demo",
wrapper: { renderMode: 'direct' },
items: [{
content: {
type: "filter",
key: "tags",
style: "chips",
multi: true, // Enable multi-select
color: "success", // Green color theme
label: "Select categories",
options: [
{ value: "design", label: "Design" },
{ value: "development", label: "Development" },
{ value: "marketing", label: "Marketing" },
{ value: "analytics", label: "Analytics" }
]
}
}]
});
// Multi-select returns an array
RSL.FilterBus.subscribe('tags-demo', function(state) {
var tags = state.tags || [];
console.log('Selected tags:', tags.join(', '));
}, { keys: ['tags'] });
A dropdown select for when you have many options or limited horizontal space.
RSL.JSONLayout.renderLayout('#container', {
version: 2,
layoutId: "filter-dropdown-demo",
wrapper: { renderMode: 'direct' },
items: [{
content: {
type: "filter",
key: "region",
style: "dropdown",
placeholder: "Select a region...",
label: "Filter by region",
options: [
{ value: "north-america", label: "North America" },
{ value: "europe", label: "Europe" },
{ value: "asia-pacific", label: "Asia Pacific" },
{ value: "latin-america", label: "Latin America" },
{ value: "middle-east", label: "Middle East" }
]
}
}]
});
Customize filter appearance with different colors and sizes to match your design system.
// Size variants: sm, md (default), lg
RSL.JSONLayout.renderLayout('#container', {
version: 2,
layoutId: "size-demo",
breakpoints: { xs: 1 },
gap: "1.5rem",
items: [
{
content: {
type: "filter",
key: "small",
style: "pills",
size: "sm", // Small size
options: [{ value: "a", label: "Small A" }, { value: "b", label: "Small B" }]
}
},
{
content: {
type: "filter",
key: "large",
style: "pills",
size: "lg", // Large size
options: [{ value: "a", label: "Large A" }, { value: "b", label: "Large B" }]
}
}
]
});
// Color variants: primary, success, warning, danger, info
{
type: "filter",
color: "success", // Green theme
// ...
}
Handle filter changes directly in your JSON configuration with the onChange callback.
RSL.JSONLayout.renderLayout('#container', {
version: 2,
layoutId: "filter-callback-demo",
wrapper: { renderMode: 'direct' },
items: [{
content: {
type: "filter",
key: "priority",
style: "pills",
color: "warning",
label: "Filter by priority",
options: [
{ value: "high", label: "High", icon: "fas fa-exclamation-circle" },
{ value: "medium", label: "Medium", icon: "fas fa-minus-circle" },
{ value: "low", label: "Low", icon: "fas fa-check-circle" }
],
// Direct callback - no need to subscribe separately
onChange: function(value, state, meta) {
console.log('Priority changed to:', value);
console.log('Full state:', state);
// Update your UI directly here
updatePriorityDisplay(value);
}
}
}]
});
A real-world example showing a Filter controlling which cards are displayed via FilterBus pub/sub.
// Sample data
var projects = [
{ id: 1, name: 'Website Redesign', category: 'design', status: 'Active' },
{ id: 2, name: 'Mobile App', category: 'development', status: 'Active' },
{ id: 3, name: 'Brand Guidelines', category: 'design', status: 'Completed' },
{ id: 4, name: 'API Integration', category: 'development', status: 'Pending' },
{ id: 5, name: 'Social Campaign', category: 'marketing', status: 'Active' },
{ id: 6, name: 'SEO Audit', category: 'marketing', status: 'Completed' }
];
// Render Filter
RSL.JSONLayout.renderLayout('#filter-container', {
version: 2,
layoutId: "category-filter",
wrapper: { renderMode: 'direct' },
items: [{
content: {
type: "filter",
key: "category",
style: "pills",
defaultValue: "all",
options: [
{ value: "all", label: "All Projects" },
{ value: "design", label: "Design" },
{ value: "development", label: "Development" },
{ value: "marketing", label: "Marketing" }
]
}
}]
});
// Render Cards
function renderCards(filterValue) {
var filtered = filterValue === 'all'
? projects
: projects.filter(p => p.category === filterValue);
RSL.JSONLayout.renderLayout('#cards-container', {
version: 2,
layoutId: "project-cards",
breakpoints: { xs: 1, sm: 2, lg: 3 },
gap: "1.5rem",
items: filtered.map(project => ({
content: {
type: "card",
title: project.name,
text: 'Category: ' + project.category,
footer: 'Status: ' + project.status
}
}))
});
}
// Subscribe to filter changes
RSL.FilterBus.subscribe('cards-updater', function(state) {
renderCards(state.category || 'all');
}, { keys: ['category'] });
// Initial render
renderCards('all');
All V2 Filter components automatically publish to the RSL FilterBus. Other components like Smart Tables, Accordions, and custom components can subscribe to filter changes using:
RSL.FilterBus.subscribe('my-subscriber', function(state) {
// React to filter changes
var filterValue = state['my-filter-key'];
}, { keys: ['my-filter-key'] });