Last active
August 15, 2025 04:50
-
-
Save beata/9b015a272024a96004915c49f63edc7c to your computer and use it in GitHub Desktop.
Obsidian - filterable datacard list
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ```dataviewjs | |
| const pageTag = '#cosmetics' | |
| const brandProperty = 'brand' // for the primary dropdown | |
| const typeProperty = 'type' // for the secondary dropdown | |
| const imageProperty = 'cover' | |
| // End of Configurable Parameters | |
| const buildDropdown = (name, optionSet) => { | |
| const select = dv.el('select', '', { cls: `select--${name}` }) | |
| select.innerHTML = ['', ...([...optionSet].sort())].map((option, index) => `<option value="${option}">${index === 0 ? name : option}</option>`).join('') | |
| return select | |
| } | |
| const buildList = (selectedBrand, selectedType) => { | |
| const conds = ['!hidden']; | |
| if (selectedBrand) { | |
| conds.push(`${brandProperty} = "${selectedBrand}"`) | |
| } | |
| if (selectedType) { | |
| conds.push(`contains(${typeProperty}, "${selectedType}")`) | |
| } | |
| const condsString = conds.length ? ` WHERE ${conds.join(' AND ')}` : '' | |
| return dv.paragraph(` | |
| \`\`\`datacards | |
| TABLE cover FROM ${pageTag} ${condsString} SORT ${typeProperty}, name | |
| // Settings | |
| imageProperty: ${imageProperty} | |
| preset: portrait | |
| columns: 4 | |
| fontSize: small | |
| truncateText: true | |
| enableClickableCards: true | |
| mobilePreset: portrait | |
| mobileColumns: 1 | |
| mobileScrollableProperties: true | |
| \`\`\` | |
| `) | |
| } | |
| const brandSet = new Set() | |
| const typeSet = new Set() | |
| let selectedBrand = '' | |
| let selectedType = '' | |
| // Collect dropdown options from pages | |
| dv.pages(pageTag).where(p => !p.hidden).forEach(p => { | |
| brandSet.add(p.brand) | |
| if (p.type) { | |
| (Array.isArray(p.type) ? p.type : [p.type]) | |
| .forEach(type => typeSet.add(type)) | |
| } | |
| }) | |
| // Build DOM Elements | |
| const filterBox = dv.el('div', '') | |
| filterBox.style = 'display: flex; flex-direciton: row; justify-content: flex-end; gap: 8px' | |
| filterBox.append(buildDropdown('Brand', brandSet)) | |
| filterBox.append(buildDropdown('Type', typeSet)) | |
| const listBox = dv.el('div', '') | |
| listBox.append(buildList(selectedBrand, selectedType)) | |
| dv.container.append(filterBox) | |
| dv.container.append(listBox) | |
| // Add Event Listener | |
| filterBox.addEventListener('change', function(event) { | |
| if (event.srcElement.classList.contains('select--Brand')) { | |
| selectedBrand = event.target.value | |
| selectedType = ''; | |
| if (event.srcElement.nextSibling) { | |
| event.srcElement.nextSibling.value = selectedType; | |
| } | |
| } else if (event.srcElement.classList.contains('select--Type')) { | |
| selectedType = event.target.value | |
| } | |
| listBox.innerHTML = ''; | |
| listBox.append(buildList(selectedBrand, selectedType)) | |
| }); | |
| ``` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| --- | |
| tags: | |
| - cosmetics | |
| name: Makeup by Mario ETHEREAL EYES EYESHADOW PALETTE - MOONLIGHT | |
| cover: https://www.makeupbymario.com/cdn/shop/files/MBM_EE2_PACKSHOT_ALT_MBCOLOR_06_MBM.jpg?v=1727801911&width=2480 | |
| link: https://www.makeupbymario.com/products/ethereal-eyes-eyeshadow-palette-moonlight-copy?variant=41785633865793 | |
| brand: Makeup by Mario | |
| area: eye | |
| type: | |
| - eyeshadow palette | |
| --- | |
| `= ""` |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Requirements
Usage Instructions
index-dataviewjs
This is the DataviewJS snippet for displaying a card list.
Paste it into any page where you want the card list to appear.
page-meta-template
This is the template for individual card items.
Each page created with this template will serve as a card entry that the list can query.