Displaying Multiselect Values as Chips in List Pages
Creating a visually appealing display for multiselect values can greatly enhance the usability of your application. Here's a guide on how to transform comma-separated multiselect values into colored chips in your list page.
Step 1: Store Multiselect Values in a Text Field
First, you need to create a text field in your data model to store the multiselect values as a comma-separated string. For example:
"Home,Grant,Actual,Business,Home Delivery"
This text field will serve as the data source for your chips display.
Step 2: Implement the View Model Handler
Add the following code to your handler to transform the text values into visual chips:
View Model Handler Code
{ request: "crt.HandleViewModelAttributeChangeRequest", handler: async (request, next, context) => { //console.log("Data changed"); const columnId = "d83d0646-68df-e743-f996-e007039be534"; const injectChipStyles = () => { const style = document.createElement("style"); style.innerHTML = ` .custom-chip { display: inline-block; padding: 1px 5px; margin: 3px 5px 3px 0px; border-radius: 20px; font-size: 12px; font-weight: 500; color: white; position: relative; padding-right: 5px; background-color: #666; } .custom-chip::after { font-weight: bold; position: absolute; right: 5px; top: 50%; transform: translateY(-50%); cursor: default; } `; document.head.appendChild(style); }; const stringToColor = (str) => { let hash = 0; for (let i = 0; i < str.length; i++) { hash = str.charCodeAt(i) + ((hash << 5) - hash); } let color = '#'; for (let i = 0; i < 3; i++) { const value = (hash >> (i * 8)) & 0xFF; color += (`00${value.toString(16)}`).slice(-2); } return color; }; const renderChips = () => { const cells = document.querySelectorAll( `td[crt-data-table-column-id="${columnId}"] .crt-data-table-cell-value` ); if (cells.length === 0) return; cells.forEach(cell => { const title = cell.getAttribute("title"); if (title && cell.children.length === 0) { cell.innerHTML = ""; title.split(",").forEach(value => { const trimmed = value.trim(); const chip = document.createElement("span"); chip.className = "custom-chip"; chip.innerText = trimmed; chip.style.backgroundColor = stringToColor(trimmed); cell.appendChild(chip); }); } }); clearInterval(timer); }; injectChipStyles(); const timer = setInterval(renderChips, 500); await next?.handle(request); } } { request: "crt.HandleViewModelAttributeChangeRequest", handler: async (request, next, context) => { //console.log("Data changed"); const columnId = "d83d0646-68df-e743-f996-e007039be534"; const injectChipStyles = () => { const style = document.createElement("style"); style.innerHTML = ` .custom-chip { display: inline-block; padding: 1px 5px; margin: 3px 5px 3px 0px; border-radius: 20px; font-size: 12px; font-weight: 500; color: white; position: relative; padding-right: 5px; background-color: #666; } .custom-chip::after { font-weight: bold; position: absolute; right: 5px; top: 50%; transform: translateY(-50%); cursor: default; } `; document.head.appendChild(style); }; const stringToColor = (str) => { let hash = 0; for (let i = 0; i < str.length; i++) { hash = str.charCodeAt(i) + ((hash << 5) - hash); } let color = '#'; for (let i = 0; i < 3; i++) { const value = (hash >> (i * 8)) & 0xFF; color += (`00${value.toString(16)}`).slice(-2); } return color; }; const renderChips = () => { const cells = document.querySelectorAll( `td[crt-data-table-column-id="${columnId}"] .crt-data-table-cell-value` ); if (cells.length === 0) return; cells.forEach(cell => { const title = cell.getAttribute("title"); if (title && cell.children.length === 0) { cell.innerHTML = ""; title.split(",").forEach(value => { const trimmed = value.trim(); const chip = document.createElement("span"); chip.className = "custom-chip"; chip.innerText = trimmed; chip.style.backgroundColor = stringToColor(trimmed); cell.appendChild(chip); }); } }); clearInterval(timer); }; injectChipStyles(); const timer = setInterval(renderChips, 500); await next?.handle(request); } }
How This Code Works
- Column Identification: Replace the
columnId
with your specific column ID where the multiselect values are stored. - Style Injection: The
injectChipStyles
function adds custom CSS to your page that defines how chips will look. - Color Generation: The
stringToColor
function creates a unique color for each value based on its string content, ensuring visual distinction between different values. - Chip Rendering: The
renderChips
function:- Identifies all cells in the specified column
- Splits the comma-separated values
- Creates a chip element for each value
- Applies the generated color
- Adds the chips to the cell
- Timing: The code uses a timer to ensure cells are found and processed even if they load asynchronously.
Implementation Steps
- Locate your list page configuration
- Add the handler code to your view model handlers
- Make sure to update the
columnId
with your specific column ID - Test the implementation by viewing the list page
Result
Your multiselect values will appear as color-coded chips instead of a comma-separated string:
- Instead of: "Home,Grant,Actual,Business,Home Delivery"
- You'll see: [Home] [Grant] [Actual] [Business] [Home Delivery] (where each value has its own colored background)
This approach not only makes the information more visually appealing but also improves readability and user experience.
images
After: