87 lines
9.1 KiB
JSON
87 lines
9.1 KiB
JSON
{
|
|
"$schema": "../schemas/code-crispies-module-schema.json",
|
|
"id": "html-datalist",
|
|
"title": "Datalist",
|
|
"description": "Provide suggestions for text inputs without JavaScript",
|
|
"mode": "html",
|
|
"difficulty": "beginner",
|
|
"lessons": [
|
|
{
|
|
"id": "datalist-basic",
|
|
"title": "Input with Suggestions",
|
|
"description": "The <kbd><datalist></kbd> element provides autocomplete suggestions for inputs. Connect it using the <kbd>list</kbd> attribute on the input matching the datalist's <kbd>id</kbd>.<br><br>Users can still type freely - suggestions are just helpers!",
|
|
"task": "Create a browser selector:<br>1. Add a <kbd><label></kbd> saying <code>Browser:</code><br>2. Add an <kbd><input></kbd> with <kbd>list=\"browsers\"</kbd><br>3. Add a <kbd><datalist id=\"browsers\"></kbd> with options for Chrome, Firefox, and Safari",
|
|
"previewHTML": "",
|
|
"previewBaseCSS": "body { font-family: system-ui; padding: 20px; } label { display: block; margin-bottom: 8px; font-weight: 500; } input { width: 100%; padding: 10px; border: 1px solid #ccc; border-radius: 6px; font-size: 16px; } input:focus { outline: 2px solid #1976d2; border-color: transparent; }",
|
|
"sandboxCSS": "",
|
|
"initialCode": "",
|
|
"solution": "<label for=\"browser\">Browser:</label>\n<input type=\"text\" id=\"browser\" list=\"browsers\">\n<datalist id=\"browsers\">\n <option value=\"Chrome\">\n <option value=\"Firefox\">\n <option value=\"Safari\">\n</datalist>",
|
|
"previewContainer": "preview-area",
|
|
"concept": {
|
|
"explanation": "Datalist provides native autocomplete without requiring JavaScript—the browser handles all the filtering, dropdown rendering, and selection logic. When users type, the browser automatically shows matching options using substring matching (typing \"fir\" shows \"Firefox\"). Unlike a select element that restricts users to predefined choices, datalist is advisory-only: users can ignore all suggestions and enter custom text, making it perfect for \"common values but allow anything\" scenarios. The dropdown styling is platform-native and keyboard-accessible (arrow keys to navigate, Enter to select), with full screen reader support announcing \"combobox with X suggestions\".",
|
|
"diagram": "Datalist vs Select\n\nDatalist (Flexible):\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n<input list=\"browsers\">\n<datalist id=\"browsers\">\n <option value=\"Chrome\">\n <option value=\"Firefox\">\n</datalist>\n\n┌─────────────────────────────┐\n│ Fir_ │ ← User types\n├─────────────────────────────┤\n│ ▾ Suggestions: │\n│ Firefox │ ← Filtered\n└─────────────────────────────┘\n✓ Can type \"Brave\" (not listed)\n✓ Suggestions are optional\n\nSelect (Restricted):\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n<select>\n <option>Chrome</option>\n <option>Firefox</option>\n</select>\n\n┌─────────────────────────────┐\n│ Chrome ▾ │\n├─────────────────────────────┤\n│ Chrome │\n│ Firefox │\n└─────────────────────────────┘\n✗ Can't type custom value\n✗ Must pick from list\n\nBrowser Handles:\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n✓ Substring filtering\n✓ Dropdown rendering\n✓ Keyboard navigation\n✓ Screen reader announcements"
|
|
},
|
|
"validations": [
|
|
{
|
|
"type": "element_exists",
|
|
"value": "datalist",
|
|
"message": "Add a <kbd><datalist></kbd> element"
|
|
},
|
|
{
|
|
"type": "attribute_value",
|
|
"value": { "selector": "input", "attr": "list", "value": "browsers" },
|
|
"message": "Connect the input to datalist using <kbd>list=</kbd>\"browsers\""
|
|
},
|
|
{
|
|
"type": "element_count",
|
|
"value": { "selector": "option", "min": 3 },
|
|
"message": "Add at least 3 <kbd><option></kbd> elements inside <kbd><datalist></kbd>"
|
|
},
|
|
{
|
|
"type": "element_exists",
|
|
"value": "label",
|
|
"message": "Add a <kbd><label></kbd> for the input"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "datalist-countries",
|
|
"title": "Country Selector",
|
|
"description": "Datalists work great for long lists like countries. Users can type to filter suggestions instantly.<br><br>The <kbd>value</kbd> attribute is what gets entered, and you can add display text after it.",
|
|
"task": "Create a country input:<br>1. Add a <kbd><label></kbd> saying <code>Country:</code><br>2. Add an <kbd><input></kbd> with <kbd>list=\"countries\"</kbd><br>3. Add a <kbd><datalist id=\"countries\"></kbd> with at least 4 country options",
|
|
"previewHTML": "",
|
|
"previewBaseCSS": "body { font-family: system-ui; padding: 30px; background: linear-gradient(135deg, #e0f7fa 0%, #b2ebf2 100%); min-height: 100vh; margin: 0; box-sizing: border-box; } label { display: block; margin-bottom: 10px; font-weight: 600; color: #00695c; } input { width: 100%; padding: 12px 15px; border: 2px solid #26a69a; border-radius: 8px; font-size: 16px; background: white; } input:focus { outline: none; border-color: #00695c; box-shadow: 0 0 0 3px rgba(38,166,154,0.2); }",
|
|
"sandboxCSS": "",
|
|
"initialCode": "",
|
|
"solution": "<label for=\"country\">Country:</label>\n<input type=\"text\" id=\"country\" list=\"countries\" placeholder=\"Start typing...\">\n<datalist id=\"countries\">\n <option value=\"Germany\">\n <option value=\"France\">\n <option value=\"Spain\">\n <option value=\"Italy\">\n</datalist>",
|
|
"previewContainer": "preview-area",
|
|
"concept": {
|
|
"explanation": "Datalists scale exceptionally well for long lists because filtering happens client-side without network requests—the browser holds all options in memory and filters instantly as the user types. This makes it ideal for common datasets like countries, states, or product names where you have hundreds of options but don't want to overwhelm users with a massive dropdown. Unlike select elements that require scrolling through all options, datalist progressively narrows results: typing \"ger\" in a 200-country list instantly shows only \"Germany\", \"Algeria\", and \"Niger\". This progressive disclosure pattern improves usability while maintaining full keyboard and screen reader accessibility.",
|
|
"diagram": "Progressive Filtering\n\nInitial State:\n┌─────────────────────────────┐\n│ Country: _ │\n└─────────────────────────────┘\n(No dropdown shown)\n\nUser types \"G\":\n┌─────────────────────────────┐\n│ Country: G_ │\n├─────────────────────────────┤\n│ ▾ Suggestions: │\n│ Germany │\n│ Georgia │\n│ Ghana │\n│ Greece │\n└─────────────────────────────┘\n\nUser types \"Ge\":\n┌─────────────────────────────┐\n│ Country: Ge_ │\n├─────────────────────────────┤\n│ ▾ Suggestions: │\n│ Germany │ ← Narrowed to 2\n│ Georgia │\n└─────────────────────────────┘\n\nUser types \"Ger\":\n┌─────────────────────────────┐\n│ Country: Ger_ │\n├─────────────────────────────┤\n│ ▾ Suggestions: │\n│ Germany │ ← Only 1 match\n└─────────────────────────────┘\n\nPerformance:\n✓ No network requests\n✓ Instant client-side filtering\n✓ Scales to hundreds of options\n✓ No JavaScript required"
|
|
},
|
|
"validations": [
|
|
{
|
|
"type": "element_exists",
|
|
"value": "datalist",
|
|
"message": "Add a <kbd><datalist></kbd> element"
|
|
},
|
|
{
|
|
"type": "attribute_value",
|
|
"value": { "selector": "datalist", "attr": "id", "value": "countries" },
|
|
"message": "Set <kbd>id=</kbd>\"countries\" on the datalist"
|
|
},
|
|
{
|
|
"type": "attribute_value",
|
|
"value": { "selector": "input", "attr": "list", "value": "countries" },
|
|
"message": "Connect the input using <kbd>list=</kbd>\"countries\""
|
|
},
|
|
{
|
|
"type": "element_count",
|
|
"value": { "selector": "option", "min": 4 },
|
|
"message": "Add at least 4 country options"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|