Pagination Examples
Basic Pagination
Enable infinite-scroll pagination for AJAX results:
<select
data-dot-select
data-searchable="true"
data-ajax-url="/api/users?q={@term}&page={@page}&limit={@pagination_limit}"
data-pagination="true"
data-pagination-limit="20"
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}&page={@page}&limit={@pagination_limit}"
data-pagination="true"
data-pagination-limit="20"
data-placeholder="Search users..."
>
</select>
)
}<template>
<select
data-dot-select
data-searchable="true"
data-ajax-url="/api/users?q={@term}&page={@page}&limit={@pagination_limit}"
data-pagination="true"
data-pagination-limit="20"
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>When the user scrolls to the bottom of the dropdown, DotSelect automatically loads the next page.
Expected API Response
{
"data": [
{ "id": 1, "text": "Alice" },
{ "id": 2, "text": "Bob" },
{ "id": 3, "text": "Carol" }
],
"pagination": {
"more": true
}
}When pagination.more is false, DotSelect stops loading more pages.
Custom Page Size
Load more results per page to reduce the number of requests:
<select
data-dot-select
data-searchable="true"
data-ajax-url="/api/products?search={@term}&page={@page}&per_page={@pagination_limit}"
data-pagination="true"
data-pagination-limit="50"
data-placeholder="Search products..."
>
</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?search={@term}&page={@page}&per_page={@pagination_limit}"
data-pagination="true"
data-pagination-limit="50"
data-placeholder="Search products..."
>
</select>
)
}<template>
<select
data-dot-select
data-searchable="true"
data-ajax-url="/api/products?search={@term}&page={@page}&per_page={@pagination_limit}"
data-pagination="true"
data-pagination-limit="50"
data-placeholder="Search products..."
>
</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 "Has More" Key
If your API uses a different key for the "has more pages" flag:
<select
data-dot-select
data-searchable="true"
data-ajax-url="/api/items?q={@term}&page={@page}"
data-pagination="true"
data-pagination-more-key="meta.has_next_page"
data-placeholder="Search items..."
>
</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/items?q={@term}&page={@page}"
data-pagination="true"
data-pagination-more-key="meta.has_next_page"
data-placeholder="Search items..."
>
</select>
)
}<template>
<select
data-dot-select
data-searchable="true"
data-ajax-url="/api/items?q={@term}&page={@page}"
data-pagination="true"
data-pagination-more-key="meta.has_next_page"
data-placeholder="Search items..."
>
</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>Expected response:
{
"data": [
{ "id": 1, "text": "Item 1" },
{ "id": 2, "text": "Item 2" }
],
"meta": {
"has_next_page": true,
"current_page": 1,
"total_pages": 5
}
}Pagination with Templates
Combine pagination with custom templates:
<select
data-dot-select
data-searchable="true"
data-ajax-url="/api/employees?q={@term}&page={@page}&limit={@pagination_limit}"
data-pagination="true"
data-pagination-limit="15"
data-render-option-content-as-html="true"
data-template-option="<div style='display:flex;justify-content:space-between'><span>{@text}</span><small style='color:#9ca3af'>{@department}</small></div>"
data-placeholder="Search employees..."
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/employees?q={@term}&page={@page}&limit={@pagination_limit}"
data-pagination="true"
data-pagination-limit="15"
data-render-option-content-as-html="true"
data-template-option="<div style='display:flex;justify-content:space-between'><span>{@text}</span><small style='color:#9ca3af'>{@department}</small></div>"
data-placeholder="Search employees..."
data-allow-clear="true"
>
</select>
)
}<template>
<select
data-dot-select
data-searchable="true"
data-ajax-url="/api/employees?q={@term}&page={@page}&limit={@pagination_limit}"
data-pagination="true"
data-pagination-limit="15"
data-render-option-content-as-html="true"
data-template-option="<div style='display:flex;justify-content:space-between'><span>{@text}</span><small style='color:#9ca3af'>{@department}</small></div>"
data-placeholder="Search employees..."
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>Pagination with Multiple Select
Paginated results with multi-select and exclusion of selected items:
<select
data-dot-select
data-searchable="true"
data-plugins="remove-button"
data-ajax-url="/api/users?q={@term}&page={@page}&limit={@pagination_limit}&exclude={@selected}"
data-pagination="true"
data-pagination-limit="25"
data-placeholder="Search and select users..."
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/users?q={@term}&page={@page}&limit={@pagination_limit}&exclude={@selected}"
data-pagination="true"
data-pagination-limit="25"
data-placeholder="Search and select users..."
multiple
>
</select>
)
}<template>
<select
data-dot-select
data-searchable="true"
data-plugins="remove-button"
data-ajax-url="/api/users?q={@term}&page={@page}&limit={@pagination_limit}&exclude={@selected}"
data-pagination="true"
data-pagination-limit="25"
data-placeholder="Search and select users..."
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>Pagination with Virtual Scroll
For the best performance with large paginated datasets, combine with the virtual-scroll plugin:
<select
data-dot-select
data-searchable="true"
data-plugins="virtual-scroll"
data-ajax-url="/api/records?q={@term}&page={@page}&limit={@pagination_limit}"
data-pagination="true"
data-pagination-limit="100"
data-placeholder="Search records..."
>
</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="virtual-scroll"
data-ajax-url="/api/records?q={@term}&page={@page}&limit={@pagination_limit}"
data-pagination="true"
data-pagination-limit="100"
data-placeholder="Search records..."
>
</select>
)
}<template>
<select
data-dot-select
data-searchable="true"
data-plugins="virtual-scroll"
data-ajax-url="/api/records?q={@term}&page={@page}&limit={@pagination_limit}"
data-pagination="true"
data-pagination-limit="100"
data-placeholder="Search records..."
>
</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>TIP
When using virtual scroll with pagination, consider using a larger data-pagination-limit (e.g., 100) to reduce the number of network requests, since virtual scroll handles the rendering performance.
Custom Load More Text
Override the "Load more" text at the bottom of the dropdown:
<select
data-dot-select
data-searchable="true"
data-ajax-url="/api/items?q={@term}&page={@page}"
data-pagination="true"
data-load-more-text="Scroll for more results..."
data-placeholder="Search..."
>
</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/items?q={@term}&page={@page}"
data-pagination="true"
data-load-more-text="Scroll for more results..."
data-placeholder="Search..."
>
</select>
)
}<template>
<select
data-dot-select
data-searchable="true"
data-ajax-url="/api/items?q={@term}&page={@page}"
data-pagination="true"
data-load-more-text="Scroll for more results..."
data-placeholder="Search..."
>
</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>