1.0.1 • Published 10 months ago

vue-dynamic-cascading-select v1.0.1

Weekly downloads
-
License
MIT
Repository
github
Last release
10 months ago

Vue 3 component for selecting addresses through multi-level dropdowns.

Props

The component accepts the following props:

  • initialId (number | null) - the initial identifier used to load initial data when the component is mounted.

  • mode (create |'view | edit) - determines the mode of the component. In 'view' mode, data modification is not allowed. In 'edit' and 'create' modes, data can be modified.

  • fetchOptions ((parentId: number | null, query?: string) => Promise<Address[]>) - function to load options for the select. It takes parentId (identifier of the parent item) and query (a string for filtering options).

  • fetchAncestry ((id: number) => Promise<Address[]>) - function to load the entire chain of ancestors for a given id. Used to initialize the component in edit and view modes.

  • showAddButton (boolean) - determines whether the button to create a new item should be displayed.

Events

The component emits the following events:

  • update:selectedId (id: number | null) - event that is emitted when the selected item changes. The id of the selected item or null is passed if the selection is cleared.

  • addNew (index: number | null) - event that is emitted when the button to create a new item is clicked. The index of the current level or null is passed.

Example

# Yarn
yarn add vue-dynamic-cascading-select

# NPM
npm install vue-dynamic-cascading-select --save
import { DynamicCascadingSelect } from 'vue-dynamic-cascading-select'
import 'vue-dynamic-cascading-select/dist/style.css'

const baseUrl = 'https://66be58a374dfc195586f3a53.mockapi.io/api/v1'

const fetchOptions = async (parentId: number | null, query?: string) => {
  try {
    const url = new URL(`${baseUrl}/address`)
    if (parentId != null) {
      url.searchParams.set('parentId', parentId)
    }
    if (query != undefined) {
      url.searchParams.set('query', query)
    }
    const res = await fetch(url)
    if (!res.ok) {
      throw new Error('Network error')
    }
    const data = await res.json()
    return data
  } catch (error) {
    console.error(error)
    return []
  }
}

const fetchAncestry = async (id: number) => {
  const ancestry = []
  let currentId = id
  while (currentId !== null) {
    try {
      const res = await fetch(`${baseUrl}/address/${currentId}`)
      if (!res.ok) {
        throw new Error('Network error')
      }
      const data = await res.json()
      ancestry.unshift(data)
      currentId = data.parentId
    } catch (error) {
      console.error(error)
      break
    }
  }
  return ancestry
}

const handleSelectedId = (id: number | null): void => {
  console.log(id)
}

const handleAddNew = (id: number | null): void => {
  alert(id ?? 'parent')
}
<el-row :gutter="20">
  <el-col :span="8">
    <el-text>View</el-text>
    <dynamic-cascading-select
      mode="view"
      :initial-id="3"
      :fetch-options="fetchOptions"
      :fetch-ancestry="fetchAncestry"
    />
  </el-col>
  <el-col :span="8">
    <el-text>Edit</el-text>
    <dynamic-cascading-select
      mode="edit"
      :initial-id="6"
      :fetch-options="fetchOptions"
      :fetch-ancestry="fetchAncestry"
      @update:selectedId="handleSelectedId"
      @add-new="handleAddNew"
      show-add-button
    />
  </el-col>
  <el-col :span="8">
    <el-text>Create</el-text>
    <dynamic-cascading-select
      mode="create"
      :fetch-options="fetchOptions"
      :fetch-ancestry="fetchAncestry"
      @update:selected-id="handleSelectedId"
      @add-new="handleAddNew"
    />
  </el-col>
</el-row>
1.0.1

10 months ago

1.0.0

10 months ago