Template Examples
User Select with Avatars
Display user avatars alongside names in the dropdown:
<select
data-dot-select
data-searchable="true"
data-ajax-url="/api/users?q={@term}"
data-render-option-content-as-html="true"
data-render-item-content-as-html="true"
data-template-option="
<div style='display:flex;align-items:center;gap:10px'>
<img src='{@avatar}' style='width:36px;height:36px;border-radius:50%' />
<div>
<div style='font-weight:600'>{@text}</div>
<div style='font-size:12px;color:#6b7280'>{@email}</div>
</div>
</div>"
data-template-item="
<span style='display:inline-flex;align-items:center;gap:4px'>
<img src='{@avatar}' style='width:20px;height:20px;border-radius:50%' />
{@text}
</span>"
data-placeholder="Search users..."
data-allow-clear="true"
>
</select>import { DotSelect } from 'dot-select'
const ds = new DotSelect('select[data-dot-select]')
// API
ds.getValue()
ds.setValue(['value'])
ds.clear()
ds.destroy()import { useEffect, useRef } from 'react'
import { DotSelect } from 'dot-select'
import 'dot-select/css'
export default function Select() {
const ref = useRef(null)
useEffect(() => {
const ds = new DotSelect(ref.current)
return () => ds.destroy()
}, [])
return (
<select
data-dot-select
data-searchable="true"
data-ajax-url="/api/users?q={@term}"
data-render-option-content-as-html="true"
data-render-item-content-as-html="true"
data-template-option="
<div style='display:flex;align-items:center;gap:10px'>
<img src='{@avatar}' style='width:36px;height:36px;border-radius:50%' />
<div>
<div style='font-weight:600'>{@text}</div>
<div style='font-size:12px;color:#6b7280'>{@email}</div>
</div>
</div>"
data-template-item="
<span style='display:inline-flex;align-items:center;gap:4px'>
<img src='{@avatar}' style='width:20px;height:20px;border-radius:50%' />
{@text}
</span>"
data-placeholder="Search users..."
data-allow-clear="true"
>
</select>
)
}<template>
<select
data-dot-select
data-searchable="true"
data-ajax-url="/api/users?q={@term}"
data-render-option-content-as-html="true"
data-render-item-content-as-html="true"
data-template-option="
<div style='display:flex;align-items:center;gap:10px'>
<img src='{@avatar}' style='width:36px;height:36px;border-radius:50%' />
<div>
<div style='font-weight:600'>{@text}</div>
<div style='font-size:12px;color:#6b7280'>{@email}</div>
</div>
</div>"
data-template-item="
<span style='display:inline-flex;align-items:center;gap:4px'>
<img src='{@avatar}' style='width:20px;height:20px;border-radius:50%' />
{@text}
</span>"
data-placeholder="Search users..."
data-allow-clear="true"
>
</select>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue'
import { DotSelect } from 'dot-select'
import 'dot-select/css'
const selectRef = ref(null)
let ds = null
onMounted(() => {
ds = new DotSelect(selectRef.value)
})
onBeforeUnmount(() => {
ds?.destroy()
})
</script>Country Select with Flags
Show country flag emojis in options:
<select
data-dot-select
data-searchable="true"
data-render-option-content-as-html="true"
data-render-item-content-as-html="true"
data-template-option="<span>{@flag} {@text}</span>"
data-template-item="<span>{@flag} {@text}</span>"
data-placeholder="Select a country..."
>
<option value="us" data-flag="🇺🇸">United States</option>
<option value="ca" data-flag="🇨🇦">Canada</option>
<option value="uk" data-flag="🇬🇧">United Kingdom</option>
<option value="de" data-flag="🇩🇪">Germany</option>
<option value="fr" data-flag="🇫🇷">France</option>
<option value="jp" data-flag="🇯🇵">Japan</option>
<option value="br" data-flag="🇧🇷">Brazil</option>
<option value="au" data-flag="🇦🇺">Australia</option>
</select>import { DotSelect } from 'dot-select'
const ds = new DotSelect('select[data-dot-select]')
// API
ds.getValue()
ds.setValue(['value'])
ds.clear()
ds.destroy()import { useEffect, useRef } from 'react'
import { DotSelect } from 'dot-select'
import 'dot-select/css'
export default function Select() {
const ref = useRef(null)
useEffect(() => {
const ds = new DotSelect(ref.current)
return () => ds.destroy()
}, [])
return (
<select
data-dot-select
data-searchable="true"
data-render-option-content-as-html="true"
data-render-item-content-as-html="true"
data-template-option="<span>{@flag} {@text}</span>"
data-template-item="<span>{@flag} {@text}</span>"
data-placeholder="Select a country..."
>
<option value="us" data-flag="🇺🇸">United States</option>
<option value="ca" data-flag="🇨🇦">Canada</option>
<option value="uk" data-flag="🇬🇧">United Kingdom</option>
<option value="de" data-flag="🇩🇪">Germany</option>
<option value="fr" data-flag="🇫🇷">France</option>
<option value="jp" data-flag="🇯🇵">Japan</option>
<option value="br" data-flag="🇧🇷">Brazil</option>
<option value="au" data-flag="🇦🇺">Australia</option>
</select>
)
}<template>
<select
data-dot-select
data-searchable="true"
data-render-option-content-as-html="true"
data-render-item-content-as-html="true"
data-template-option="<span>{@flag} {@text}</span>"
data-template-item="<span>{@flag} {@text}</span>"
data-placeholder="Select a country..."
>
<option value="us" data-flag="🇺🇸">United States</option>
<option value="ca" data-flag="🇨🇦">Canada</option>
<option value="uk" data-flag="🇬🇧">United Kingdom</option>
<option value="de" data-flag="🇩🇪">Germany</option>
<option value="fr" data-flag="🇫🇷">France</option>
<option value="jp" data-flag="🇯🇵">Japan</option>
<option value="br" data-flag="🇧🇷">Brazil</option>
<option value="au" data-flag="🇦🇺">Australia</option>
</select>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue'
import { DotSelect } from 'dot-select'
import 'dot-select/css'
const selectRef = ref(null)
let ds = null
onMounted(() => {
ds = new DotSelect(selectRef.value)
})
onBeforeUnmount(() => {
ds?.destroy()
})
</script>Product Select with Prices
Show product details including price and stock status:
<select
data-dot-select
data-searchable="true"
data-ajax-url="/api/products?q={@term}"
data-render-option-content-as-html="true"
data-template-option="
<div style='display:flex;justify-content:space-between;align-items:center'>
<div>
<div style='font-weight:500'>{@text}</div>
<div style='font-size:12px;color:#6b7280'>{@sku}</div>
</div>
<div style='text-align:right'>
<div style='font-weight:600;color:#059669'>${@price}</div>
<div style='font-size:11px;color:#9ca3af'>{@stock} in stock</div>
</div>
</div>"
data-placeholder="Search products..."
data-allow-clear="true"
>
</select>import { DotSelect } from 'dot-select'
const ds = new DotSelect('select[data-dot-select]')
// API
ds.getValue()
ds.setValue(['value'])
ds.clear()
ds.destroy()import { useEffect, useRef } from 'react'
import { DotSelect } from 'dot-select'
import 'dot-select/css'
export default function Select() {
const ref = useRef(null)
useEffect(() => {
const ds = new DotSelect(ref.current)
return () => ds.destroy()
}, [])
return (
<select
data-dot-select
data-searchable="true"
data-ajax-url="/api/products?q={@term}"
data-render-option-content-as-html="true"
data-template-option="
<div style='display:flex;justify-content:space-between;align-items:center'>
<div>
<div style='font-weight:500'>{@text}</div>
<div style='font-size:12px;color:#6b7280'>{@sku}</div>
</div>
<div style='text-align:right'>
<div style='font-weight:600;color:#059669'>${@price}</div>
<div style='font-size:11px;color:#9ca3af'>{@stock} in stock</div>
</div>
</div>"
data-placeholder="Search products..."
data-allow-clear="true"
>
</select>
)
}<template>
<select
data-dot-select
data-searchable="true"
data-ajax-url="/api/products?q={@term}"
data-render-option-content-as-html="true"
data-template-option="
<div style='display:flex;justify-content:space-between;align-items:center'>
<div>
<div style='font-weight:500'>{@text}</div>
<div style='font-size:12px;color:#6b7280'>{@sku}</div>
</div>
<div style='text-align:right'>
<div style='font-weight:600;color:#059669'>${@price}</div>
<div style='font-size:11px;color:#9ca3af'>{@stock} in stock</div>
</div>
</div>"
data-placeholder="Search products..."
data-allow-clear="true"
>
</select>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue'
import { DotSelect } from 'dot-select'
import 'dot-select/css'
const selectRef = ref(null)
let ds = null
onMounted(() => {
ds = new DotSelect(selectRef.value)
})
onBeforeUnmount(() => {
ds?.destroy()
})
</script>Status Badge Template
Render colored status indicators:
<select
data-dot-select
data-render-option-content-as-html="true"
data-render-item-content-as-html="true"
data-template-option="
<span style='display:inline-flex;align-items:center;gap:8px'>
<span style='width:8px;height:8px;border-radius:50%;background:{@color};display:inline-block'></span>
{@text}
</span>"
data-template-item="
<span style='display:inline-flex;align-items:center;gap:4px'>
<span style='width:6px;height:6px;border-radius:50%;background:{@color};display:inline-block'></span>
{@text}
</span>"
data-placeholder="Set status..."
>
<option value="active" data-color="#22c55e">Active</option>
<option value="pending" data-color="#f59e0b">Pending</option>
<option value="inactive" data-color="#ef4444">Inactive</option>
<option value="archived" data-color="#6b7280">Archived</option>
</select>import { DotSelect } from 'dot-select'
const ds = new DotSelect('select[data-dot-select]')
// API
ds.getValue()
ds.setValue(['value'])
ds.clear()
ds.destroy()import { useEffect, useRef } from 'react'
import { DotSelect } from 'dot-select'
import 'dot-select/css'
export default function Select() {
const ref = useRef(null)
useEffect(() => {
const ds = new DotSelect(ref.current)
return () => ds.destroy()
}, [])
return (
<select
data-dot-select
data-render-option-content-as-html="true"
data-render-item-content-as-html="true"
data-template-option="
<span style='display:inline-flex;align-items:center;gap:8px'>
<span style='width:8px;height:8px;border-radius:50%;background:{@color};display:inline-block'></span>
{@text}
</span>"
data-template-item="
<span style='display:inline-flex;align-items:center;gap:4px'>
<span style='width:6px;height:6px;border-radius:50%;background:{@color};display:inline-block'></span>
{@text}
</span>"
data-placeholder="Set status..."
>
<option value="active" data-color="#22c55e">Active</option>
<option value="pending" data-color="#f59e0b">Pending</option>
<option value="inactive" data-color="#ef4444">Inactive</option>
<option value="archived" data-color="#6b7280">Archived</option>
</select>
)
}<template>
<select
data-dot-select
data-render-option-content-as-html="true"
data-render-item-content-as-html="true"
data-template-option="
<span style='display:inline-flex;align-items:center;gap:8px'>
<span style='width:8px;height:8px;border-radius:50%;background:{@color};display:inline-block'></span>
{@text}
</span>"
data-template-item="
<span style='display:inline-flex;align-items:center;gap:4px'>
<span style='width:6px;height:6px;border-radius:50%;background:{@color};display:inline-block'></span>
{@text}
</span>"
data-placeholder="Set status..."
>
<option value="active" data-color="#22c55e">Active</option>
<option value="pending" data-color="#f59e0b">Pending</option>
<option value="inactive" data-color="#ef4444">Inactive</option>
<option value="archived" data-color="#6b7280">Archived</option>
</select>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue'
import { DotSelect } from 'dot-select'
import 'dot-select/css'
const selectRef = ref(null)
let ds = null
onMounted(() => {
ds = new DotSelect(selectRef.value)
})
onBeforeUnmount(() => {
ds?.destroy()
})
</script>Custom No Results Template
Customize the message shown when no options match:
<select
data-dot-select
data-searchable="true"
data-render-option-content-as-html="true"
data-template-no-results="
<div style='text-align:center;padding:20px;color:#9ca3af'>
<div style='font-size:24px;margin-bottom:8px'>🔍</div>
<div>No results found</div>
<div style='font-size:12px'>Try a different search term</div>
</div>"
data-placeholder="Search..."
>
<option value="1">Alpha</option>
<option value="2">Beta</option>
<option value="3">Gamma</option>
</select>import { DotSelect } from 'dot-select'
const ds = new DotSelect('select[data-dot-select]')
// API
ds.getValue()
ds.setValue(['value'])
ds.clear()
ds.destroy()import { useEffect, useRef } from 'react'
import { DotSelect } from 'dot-select'
import 'dot-select/css'
export default function Select() {
const ref = useRef(null)
useEffect(() => {
const ds = new DotSelect(ref.current)
return () => ds.destroy()
}, [])
return (
<select
data-dot-select
data-searchable="true"
data-render-option-content-as-html="true"
data-template-no-results="
<div style='text-align:center;padding:20px;color:#9ca3af'>
<div style='font-size:24px;margin-bottom:8px'>🔍</div>
<div>No results found</div>
<div style='font-size:12px'>Try a different search term</div>
</div>"
data-placeholder="Search..."
>
<option value="1">Alpha</option>
<option value="2">Beta</option>
<option value="3">Gamma</option>
</select>
)
}<template>
<select
data-dot-select
data-searchable="true"
data-render-option-content-as-html="true"
data-template-no-results="
<div style='text-align:center;padding:20px;color:#9ca3af'>
<div style='font-size:24px;margin-bottom:8px'>🔍</div>
<div>No results found</div>
<div style='font-size:12px'>Try a different search term</div>
</div>"
data-placeholder="Search..."
>
<option value="1">Alpha</option>
<option value="2">Beta</option>
<option value="3">Gamma</option>
</select>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue'
import { DotSelect } from 'dot-select'
import 'dot-select/css'
const selectRef = ref(null)
let ds = null
onMounted(() => {
ds = new DotSelect(selectRef.value)
})
onBeforeUnmount(() => {
ds?.destroy()
})
</script>Custom Loading Template
Customize the loading indicator for AJAX selects:
<select
data-dot-select
data-searchable="true"
data-ajax-url="/api/users?q={@term}"
data-render-option-content-as-html="true"
data-template-loading="
<div style='text-align:center;padding:16px;color:#6b7280'>
<div style='display:inline-block;width:20px;height:20px;border:2px solid #e5e7eb;border-top-color:#3b82f6;border-radius:50%;animation:spin 0.6s linear infinite'></div>
<div style='margin-top:8px;font-size:13px'>Searching...</div>
</div>"
data-placeholder="Search users..."
>
</select>import { DotSelect } from 'dot-select'
const ds = new DotSelect('select[data-dot-select]')
// API
ds.getValue()
ds.setValue(['value'])
ds.clear()
ds.destroy()import { useEffect, useRef } from 'react'
import { DotSelect } from 'dot-select'
import 'dot-select/css'
export default function Select() {
const ref = useRef(null)
useEffect(() => {
const ds = new DotSelect(ref.current)
return () => ds.destroy()
}, [])
return (
<select
data-dot-select
data-searchable="true"
data-ajax-url="/api/users?q={@term}"
data-render-option-content-as-html="true"
data-template-loading="
<div style='text-align:center;padding:16px;color:#6b7280'>
<div style='display:inline-block;width:20px;height:20px;border:2px solid #e5e7eb;border-top-color:#3b82f6;border-radius:50%;animation:spin 0.6s linear infinite'></div>
<div style='margin-top:8px;font-size:13px'>Searching...</div>
</div>"
data-placeholder="Search users..."
>
</select>
)
}<template>
<select
data-dot-select
data-searchable="true"
data-ajax-url="/api/users?q={@term}"
data-render-option-content-as-html="true"
data-template-loading="
<div style='text-align:center;padding:16px;color:#6b7280'>
<div style='display:inline-block;width:20px;height:20px;border:2px solid #e5e7eb;border-top-color:#3b82f6;border-radius:50%;animation:spin 0.6s linear infinite'></div>
<div style='margin-top:8px;font-size:13px'>Searching...</div>
</div>"
data-placeholder="Search users..."
>
</select>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue'
import { DotSelect } from 'dot-select'
import 'dot-select/css'
const selectRef = ref(null)
let ds = null
onMounted(() => {
ds = new DotSelect(selectRef.value)
})
onBeforeUnmount(() => {
ds?.destroy()
})
</script>Multiple Select with Rich Items
Display badges with images in a multi-select:
<select
data-dot-select
data-searchable="true"
data-plugins="remove-button"
data-ajax-url="/api/team?q={@term}"
data-render-option-content-as-html="true"
data-render-item-content-as-html="true"
data-template-option="
<div style='display:flex;align-items:center;gap:10px'>
<img src='{@photo}' style='width:32px;height:32px;border-radius:50%' />
<div>
<div>{@text}</div>
<div style='font-size:11px;color:#94a3b8'>{@role}</div>
</div>
</div>"
data-template-item="
<span style='display:inline-flex;align-items:center;gap:4px'>
<img src='{@photo}' style='width:16px;height:16px;border-radius:50%' />
{@text}
</span>"
data-placeholder="Add team members..."
multiple
>
</select>import { DotSelect } from 'dot-select'
const ds = new DotSelect('select[data-dot-select]')
// API
ds.getValue()
ds.setValue(['value'])
ds.clear()
ds.destroy()import { useEffect, useRef } from 'react'
import { DotSelect } from 'dot-select'
import 'dot-select/css'
export default function Select() {
const ref = useRef(null)
useEffect(() => {
const ds = new DotSelect(ref.current)
return () => ds.destroy()
}, [])
return (
<select
data-dot-select
data-searchable="true"
data-plugins="remove-button"
data-ajax-url="/api/team?q={@term}"
data-render-option-content-as-html="true"
data-render-item-content-as-html="true"
data-template-option="
<div style='display:flex;align-items:center;gap:10px'>
<img src='{@photo}' style='width:32px;height:32px;border-radius:50%' />
<div>
<div>{@text}</div>
<div style='font-size:11px;color:#94a3b8'>{@role}</div>
</div>
</div>"
data-template-item="
<span style='display:inline-flex;align-items:center;gap:4px'>
<img src='{@photo}' style='width:16px;height:16px;border-radius:50%' />
{@text}
</span>"
data-placeholder="Add team members..."
multiple
>
</select>
)
}<template>
<select
data-dot-select
data-searchable="true"
data-plugins="remove-button"
data-ajax-url="/api/team?q={@term}"
data-render-option-content-as-html="true"
data-render-item-content-as-html="true"
data-template-option="
<div style='display:flex;align-items:center;gap:10px'>
<img src='{@photo}' style='width:32px;height:32px;border-radius:50%' />
<div>
<div>{@text}</div>
<div style='font-size:11px;color:#94a3b8'>{@role}</div>
</div>
</div>"
data-template-item="
<span style='display:inline-flex;align-items:center;gap:4px'>
<img src='{@photo}' style='width:16px;height:16px;border-radius:50%' />
{@text}
</span>"
data-placeholder="Add team members..."
multiple
>
</select>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue'
import { DotSelect } from 'dot-select'
import 'dot-select/css'
const selectRef = ref(null)
let ds = null
onMounted(() => {
ds = new DotSelect(selectRef.value)
})
onBeforeUnmount(() => {
ds?.destroy()
})
</script>WARNING
When using data-render-option-content-as-html="true" or data-render-item-content-as-html="true", ensure that the data source is trusted. User-generated content in templates can lead to XSS vulnerabilities.