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: