Create Santaโs Workshop Dashboard with Custom Widget Builder
Since Christmas is coming, letโs learn how to use the Custom Widget Builder while enjoying a hot chocolate! Follow these steps to create Santaโs gift order dashboard.
Create your data table
- Create a new Grist document
- Rename your table to โSanta_Ordersโ
- Create these fields:
order_id (Numeric)
child_name (Text)
gift_type (Choice)
status (Choice)
received_date (Date)
last_update (Date)
delivery_zone (Choice)
deadline (Text)
transport (Choice)
workshop (Text)
head_elf (Text)
assistant_elf (Text)
reindeer_assigned (Choice)
materials_cost (Numeric)
labor_cost (Numeric)
total_cost (Formula: materials_cost + labor_cost)
budget_notes (Text)
budget_alert (Text)
nice_level (Choice)
bonus_points (Numeric)
priority_level (Choice)
For each Choice field, copy these options:
gift_type:
๐ Simple Gift
๐ฎ Electronic Toy
๐ Book/Culture
๐งธ Plush/Cuddle
๐ฒ Outdoor Game
๐จ Creative Activity
status:
๐ Letter Received
๐ Under Review
๐ญ In Production
โจ Quality Check
๐ Ready to Wrap
๐ท Ready for Delivery
๐ Delivered
nice_level:
๐ Very Nice
๐ Nice
๐ Some Mischief
๐
To Watch
delivery_zone:
๐๏ธ North Pole
๐ Europe
๐ Americas
๐ Asia-Pacific
transport:
๐ท Standard Sleigh
โ๏ธ Supersonic Sleigh
๐ Mini-Sleigh
๐ฆ Solo Reindeer
priority_level:
โญ Ultra Priority
๐ High Priority
โจ Normal Priority
๐ซ Low Priority
reindeer_assigned:
Yes
No
Widget Configuration
- Click โAdd Newโ
- Add a Custom view
- Link the widget to โSanta_Ordersโ table
- Select custom widget builder
- Click โEdit Codeโ
- In the HTML tab, remove existing code and paste the following:
`
<!-- Line 2: Reference + Type + Status -->
<div class="flex items-center gap-4 text-left mb-3">
<div>
<span class="text-yellow-200">๐
</span>
<span id="order_id" class="text-yellow-200 font-bold"></span>
</div>
<div>
<span class="text-yellow-200"></span>
<span id="gift_type" class="px-3 py-1 rounded-md text-sm font-medium"></span>
</div>
<div>
<span class="text-yellow-200"></span>
<span id="status" class="px-3 py-1 rounded-md text-sm font-medium"></span>
</div>
</div>
<!-- Line 3: Workshop + Zone + Deadline -->
<div class="mt-2 pt-2 border-t border-yellow-300">
<div class="grid grid-cols-3 gap-4 mb-3">
<div>
<span class="text-yellow-200">๐ญ Workshop</span>
<div id="workshop" class="font-medium"></div>
</div>
<div>
<span class="text-yellow-200">๐ Delivery Zone</span>
<div id="delivery_zone" class="font-medium"></div>
</div>
<div class="text-right">
<span class="text-yellow-200">๐
Deadline</span>
<div id="deadline" class="font-medium"></div>
</div>
</div>
<!-- Dates bottom right -->
<div class="flex justify-end text-xs text-yellow-200/80">
<div class="text-right">
<div>Letter received on <span id="received_date"></span></div>
<div>Last update on <span id="last_update"></span></div>
</div>
</div>
</div>
</div>
<!-- Budget Section -->
<div class="bg-[#F9F9F9] rounded-lg shadow p-4 mt-4 text-[#1B4D3E] border-2 border-[#B8860B]">
<h2 class="text-lg font-semibold mb-4">โจ Production Budget</h2>
<div class="grid grid-cols-2 gap-6">
<div class="space-y-2">
<div class="flex justify-between p-2 bg-green-50 rounded">
<span>Materials</span>
<span id="materials_cost" class="font-extralight"></span>
</div>
<div class="flex justify-between p-2 bg-green-50 rounded">
<span>Elf Labor</span>
<span id="labor_cost" class="font-extralight"></span>
</div>
</div>
<div class="space-y-3">
<div class="p-2 bg-green-50 rounded">
<div class="text-gray-600 mb-1">Special Notes:</div>
<div id="budget_notes" class="font-medium"></div>
</div>
</div>
</div>
<!-- Total production -->
<div class="mt-2 pt-2 border-t border-[#1B4D3E]">
<div class="grid grid-cols-12 gap-4 items-center px-2">
<div class="col-span-3">
<span class="text-xl font-semibold">Total Budget</span>
</div>
<div class="col-span-3 text-left">
<span id="total_cost" class="text-xl font-bold"></span>
</div>
<div class="col-span-6">
<span id="budget_alert" class="text-sm text-red-500"></span>
</div>
</div>
</div>
</div>
<!-- Delivery Priorities -->
<div class="bg-[#F9F9F9] rounded-lg shadow p-4 mt-4 text-[#1B4D3E] border-2 border-[#B8860B]">
<h2 class="text-lg font-semibold mb-4 flex items-center gap-2">
๐ Delivery Priorities
</h2>
<div class="space-y-2">
<div class="p-2 bg-green-50 rounded">
<div class="text-sm text-gray-600 mb-1">Priority Level</div>
<div id="priority_level" class="font-medium"></div>
</div>
<div class="p-2 bg-green-50 rounded">
<div class="text-sm text-gray-600 mb-1">Transport Type</div>
<div id="transport" class="font-medium"></div>
</div>
</div>
</div>
<!-- Nice Level Evaluation -->
<div class="bg-[#F9F9F9] rounded-lg shadow p-4 mt-4 text-[#1B4D3E] border-2 border-[#B8860B]">
<h2 class="text-lg font-semibold mb-4 flex items-center gap-2">
๐ Nice Level Assessment
</h2>
<div class="grid grid-cols-2 gap-6">
<div>
<div class="flex justify-between p-2 bg-green-50 rounded">
<span>Nice Level</span>
<span id="nice_level" class="font-medium"></span>
</div>
</div>
<div>
<div class="flex justify-between p-2 bg-green-50 rounded">
<span>Bonus Points</span>
<span id="bonus_points" class="font-medium"></span>
</div>
</div>
</div>
</div>
<!-- Elf Team -->
<div class="bg-[#F9F9F9] rounded-lg shadow p-4 mt-4 text-[#1B4D3E] border-2 border-[#B8860B]">
<h2 class="text-lg font-semibold mb-4 flex items-center gap-2">
๐งโโ๏ธ Assigned Team
</h2>
<div class="grid grid-cols-2 gap-6">
<div class="space-y-3">
<div class="p-3 bg-green-50 rounded-lg">
<div class="flex items-center gap-2">
๐
<span class="text-gray-600">Head Elf:</span>
<span id="head_elf" class="font-medium"></span>
</div>
</div>
<div class="p-3 bg-green-50 rounded-lg">
<div class="flex items-center gap-2">
๐งโโ๏ธ <span class="text-gray-600">Assistant Elf:</span>
<span id="assistant_elf" class="font-medium"></span>
</div>
</div>
</div>
<div>
<div class="p-4 bg-red-50 rounded-lg">
<div class="flex items-center justify-between">
<span class="font-medium">Reindeer Status</span>
<span id="reindeer_assigned" class="font-medium"></span>
</div>
</div>
</div>
</div>
</div>
<!-- Documents -->
<div class="bg-[#F9F9F9] rounded-lg shadow p-4 mt-4 text-[#1B4D3E] border-2 border-[#B8860B]">
<h2 class="text-lg font-semibold mb-4 flex items-center gap-2">
๐ Documents
</h2>
<div class="grid grid-cols-2 gap-6">
<div class="space-y-3">
<div class="flex items-center gap-2 p-3 bg-green-50 rounded">
<span class="text-[#8B0000]">โ๏ธ</span>
<span>Santa's Letter</span>
<span id="santa_letter" class="ml-2 px-2 py-1 text-xs rounded-full"></span>
</div>
<div class="flex items-center gap-2 p-3 bg-green-50 rounded">
<span class="text-[#8B0000]">๐จ</span>
<span>Drawing</span>
<span id="child_drawing" class="ml-2 px-2 py-1 text-xs rounded-full"></span>
</div>
<div class="flex items-center gap-2 p-3 bg-green-50 rounded">
<span class="text-[#8B0000]">๐</span>
<span>Detailed List</span>
<span id="gift_list" class="ml-2 px-2 py-1 text-xs rounded-full"></span>
</div>
</div>
<div class="space-y-3">
<div class="flex items-center gap-2 p-3 bg-green-50 rounded">
<span class="text-[#8B0000]">๐</span>
<span>Elf Notes</span>
<span id="elf_notes" class="ml-2 px-2 py-1 text-xs rounded-full"></span>
</div>
<div class="flex items-center gap-2 p-3 bg-green-50 rounded">
<span class="text-[#8B0000]">โญ</span>
<span>Nice Certificate</span>
<span id="nice_certificate" class="ml-2 px-2 py-1 text-xs rounded-full"></span>
</div>
<div class="mt-6">
<a id="file_link" href="#" target="_blank"
class="inline-flex items-center gap-2 px-4 py-2 bg-red-50 hover:bg-red-100 rounded transition-colors text-[#8B0000]">
๐ <span class="underline">View Complete File</span>
</a>
</div>
</div>
</div>
</div>
- In the JavaScript tab, remove existing code and paste:
function formatDate(date) {
if (!date) return '';
return new Date(date).toLocaleDateString('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric'
});
}
function formatMoney(amount) {
if (!amount) return '0 ๐';
return new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
minimumFractionDigits: 0
}).format(amount).replace('$', '๐');
}
function getStateColor(state) {
const stateColors = {
'Letter Received': 'bg-[#FFD700]',
'Under Review': 'bg-[#1B4D3E]',
'In Production': 'bg-[#8B0000]',
'Quality Check': 'bg-[#B8860B]',
'Ready to Wrap': 'bg-[#228B22]',
'Ready for Delivery': 'bg-[#4169E1]',
'Delivered': 'bg-[#9B0000]'
};
return stateColors[state] || 'bg-[#FFD700]';
}
function getTypeColor(type) {
const typeColors = {
'Simple Gift': 'bg-[#228B22]',
'Electronic Toy': 'bg-[#4169E1]',
'Book/Culture': 'bg-[#8B4513]',
'Plush/Cuddle': 'bg-[#FF69B4]',
'Outdoor Game': 'bg-[#32CD32]',
'Creative Activity': 'bg-[#FF8C00]'
};
return typeColors[type] || 'bg-[#FFD700]';
}
grist.ready({
requiredTables: ['Santa_Orders']
});
grist.onRecord(function(record) {
if (!record) return;
// Order status
const statusElement = document.getElementById('status');
statusElement.textContent = record.status || '';
statusElement.className = 'px-3 py-1 rounded-full text-sm font-medium text-white ' + getStateColor(record.status);
// Gift type
const typeElement = document.getElementById('gift_type');
typeElement.textContent = record.gift_type || '';
typeElement.className = 'px-3 py-1 rounded-full text-sm font-medium text-white ' + getTypeColor(record.gift_type);
// Header
document.getElementById('order_id').textContent = record.order_id || '';
document.getElementById('child_name').textContent = record.child_name || '';
document.getElementById('workshop').textContent = record.workshop || '';
document.getElementById('delivery_zone').textContent = record.delivery_zone || '';
document.getElementById('deadline').textContent = record.deadline || '';
document.getElementById('received_date').textContent = formatDate(record.received_date);
document.getElementById('last_update').textContent = formatDate(record.last_update);
// Priorities
document.getElementById('priority_level').textContent = record.priority_level || '';
document.getElementById('transport').textContent = record.transport || '';
// Budget
document.getElementById('materials_cost').textContent = formatMoney(record.materials_cost);
document.getElementById('labor_cost').textContent = formatMoney(record.labor_cost);
document.getElementById('budget_notes').textContent = record.budget_notes || 'No notes';
document.getElementById('total_cost').textContent = formatMoney(record.total_cost);
document.getElementById('budget_alert').textContent = record.budget_alert || '';
// Nice level assessment
document.getElementById('nice_level').textContent = record.nice_level || '';
document.getElementById('bonus_points').textContent = record.bonus_points || '';
// Team
const reindeerElement = document.getElementById('reindeer_assigned');
const reindeerValue = record.reindeer_assigned;
if (reindeerValue === 'Yes') {
reindeerElement.textContent = 'โ
Assigned';
reindeerElement.className = 'font-medium text-green-600';
} else {
reindeerElement.textContent = 'โ Not Assigned';
reindeerElement.className = 'font-medium text-red-600';
}
document.getElementById('head_elf').textContent = record.head_elf || '';
document.getElementById('assistant_elf').textContent = record.assistant_elf || '';
// Documents
['santa_letter', 'child_drawing', 'gift_list', 'elf_notes', 'nice_certificate'].forEach(id => {
const element = document.getElementById(id);
if (element) {
if (record[id]) {
element.textContent = 'Document Present';
element.className = 'ml-2 px-2 py-1 text-xs rounded-full bg-green-100 text-green-800';
} else {
element.textContent = 'Missing';
element.className = 'ml-2 px-2 py-1 text-xs rounded-full bg-red-100 text-red-800';
}
}
});
// File link
const linkElement = document.getElementById('file_link');
if (record.file_link) {
linkElement.href = record.file_link || '#';
linkElement.target = '_blank';
}
});
- Click โPreviewโ and save
Test with Sample Data
Copy these 10 rows into your table:
1 Emma Smith ๐ฎ Electronic Toy ๐ Letter Received 2023-12-01 2023-12-02 ๐ Europe Urgent ๐ท Standard Sleigh Tech Workshop Pixel Micro Yes 250 150 400 Standard Budget None ๐ Very Nice 5 โญ Ultra Priority
2 Lucas Johnson ๐ Book/Culture ๐ญ In Production 2023-12-02 2023-12-03 ๐ Americas Normal โ๏ธ Supersonic Sleigh Culture Workshop Story Read No 120 80 200 Reduced Budget None ๐ Nice 3 ๐ซ Low Priority
3 Sofia Lee ๐ฒ Outdoor Game โจ Quality Check 2023-12-01 2023-12-04 ๐ Asia-Pacific Urgent ๐ Mini-Sleigh Wood Workshop Sport Active No 290 160 450 Special Materials Deadline Alert ๐ Some Mischief 2 โจ Normal Priority
4 Amir Khan ๐จ Creative Activity ๐ท Ready for Delivery 2023-12-02 2023-12-05 ๐ Europe Normal ๐ฆ Solo Reindeer Creative Workshop Create Make Yes 180 120 300 N/A None ๐ Very Nice 4 ๐ High Priority
5 Lea Chen ๐ฎ Electronic Toy ๐ Under Review 2023-12-03 2023-12-04 ๐ Asia-Pacific Urgent โ๏ธ Supersonic Sleigh Tech Workshop Tech Code No 200 150 350 Extra Budget None ๐ Nice 3 โญ Ultra Priority
6 Mohamed Taylor ๐งธ Plush/Cuddle ๐ญ In Production 2023-12-01 2023-12-05 ๐ Europe Normal ๐ท Standard Sleigh Plush Workshop Soft Cuddle Yes 300 200 500 Rare Materials Budget Alert ๐ Some Mischief 2 โจ Normal Priority
7 Julie Nguyen ๐ Book/Culture ๐ Letter Received 2023-12-02 2023-12-03 ๐ Africa Urgent ๐ Mini-Sleigh Culture Workshop Book Write No 280 180 460 N/A None ๐ Very Nice 5 ๐ High Priority
8 Thomas Lee ๐ฒ Outdoor Game โจ Quality Check 2023-12-03 2023-12-05 ๐ Asia-Pacific Normal ๐ฆ Solo Reindeer Wood Workshop Build Craft Yes 150 100 250 Standard Budget None ๐ Nice 3 ๐ซ Low Priority
9 Maria Garcia ๐จ Creative Activity ๐ท Ready for Delivery 2023-12-01 2023-12-04 ๐ Americas Urgent โ๏ธ Supersonic Sleigh Creative Workshop Art Paint No 110 70 180 N/A None ๐ Very Nice 4 โญ Ultra Priority
10 Yuki Tanaka ๐ฎ Electronic Toy ๐ Under Review 2023-12-02 2023-12-03 ๐ Asia-Pacific Normal ๐ท Standard Sleigh Tech Workshop Robot Circuit Yes 160 110 270 Reduced Budget None ๐ Some Mischief 2 โจ Normal Priority
If everything is configured correctly, you should see your Christmas dashboard appear! Of course, this example is just a starting point - you can adapt this display format to your needs.
Widget Customization Guide
Colors
Main Background
<body class="bg-[#C41E3A] min-h-screen">
Replace #C41E3A
with any color code
Header Gradient
<div class="bg-gradient-to-r from-[#7BBF6A] to-[#016936] rounded-lg">
Modify #7BBF6A
and #016936
for different gradient colors
Sections
<div class="bg-[#F9F9F9] rounded-lg shadow p-4 mt-4 text-[#1B4D3E] border-2 border-[#B8860B]">
#F9F9F9
: section background#1B4D3E
: text color#B8860B
: border color
Adding Sections
Template
<div class="bg-[#F9F9F9] rounded-lg shadow p-4 mt-4 text-[#1B4D3E] border-2 border-[#B8860B]">
<h2 class="text-lg font-semibold mb-4 flex items-center gap-2">
๐ Section Title
</h2>
<div class="grid grid-cols-2 gap-6">
<div class="p-2 bg-green-50 rounded">
<span>Label</span>
<span id="field_name" class="font-medium"></span>
</div>
</div>
</div>
Add to JavaScript
document.getElementById('field_name').textContent = record.field_name || '';
Layouts & Styling
Grid Layouts
<div class="grid grid-cols-2 gap-6">
grid-cols-2
: columns (1-12)gap-6
: spacing (1-12)
Cards
<div class="p-4 bg-green-50 rounded-lg">
p-4
: paddingrounded-lg
: corner radiusbg-green-50
: color intensity
Typography
<span class="text-lg font-semibold text-gray-600">
- Sizes:
text-sm
,text-lg
,text-xl
,text-2xl
- Weights:
font-light
,font-medium
,font-bold
Effects
<div class="shadow hover:shadow-lg transition-all">
- Shadows:
shadow-sm
toshadow-xl
- Transitions:
duration-300
- Hover effects:
hover:scale-105
Status Colors
function getStateColor(state) {
const stateColors = {
'Status 1': 'bg-[#COLOR]',
};
}
Responsive Design
<div class="md:grid-cols-2 lg:grid-cols-3">
sm:
: >640pxmd:
: >768pxlg:
: >1024pxxl:
: >1280px
Animation Examples
<div class="transition-all duration-300 hover:scale-105 hover:rotate-3">
scale-105
: zoomrotate-3
: rotationtranslate-y-1
: movement