Documentation: Reusable Advanced Selection System
This document explains how to use the generic selection system, which consists of a powerful LaravelAdminController superclass and a flexible Vue.js SelectAdvancedDialog component. This system is designed to rapidly create complex, searchable, and hierarchical selection dialogs.
Part 1: Backend - Laravel AdminController
The AdminController provides three main endpoints for fetching data for selection dialogs. To use them, your controller must extend AdminController and configure specific class properties in its __construct() method.
Method 1: postGetOption()
- Purpose: Provides a simple, paginated, flat list of options. Ideal for selecting users, products, etc., without any hierarchy.
- Endpoint:
POST {controller-base}/get-option - Configuration in Child Controller:
| Property | Type | Description | Example |
|---|---|---|---|
model | Model | Required. The Eloquent model class to query. | new User() |
option_search_fields | array | Required. Database columns to search against when a user types in the search box. | ['name', 'username', 'email'] |
option_text_fields | array | Required. Columns used to build the display text for each option. They will be joined by a separator. | ['name', 'email'] |
option_value_field | string | The column to use as the unique value/ID for the option. | 'id' (default) or 'slug' |
option_text_separator | string | The separator used to join the option_text_fields. | ' - ' (default) |
additionalOptionQuery() | method | An overridable method to add extra query constraints (e.g., ->where('status', 'active')). | return $query->where('isActive', true); |
- Example:
UserController.php
Method 2: postGetOptionTree()
- Purpose: Provides a hierarchical list of options from a single model that has a self-referencing parent-child relationship (e.g., categories with sub-categories). Supports both eager and lazy loading.
- Endpoint:
POST {controller-base}/get-option-tree - Configuration in Child Controller:
| Property | Type | Description | Example |
|---|---|---|---|
model, option_*_fields | mixed | All properties from postGetOption() are also used here. | (Same as above) |
option_tree_parent_field | string | Required. The database column that stores the ID of the parent record. | 'parent_id' |
option_tree_root_parent_value | mixed | The value in the parent field that identifies a root node. | null (default) or 0 |
option_tree_eager_load | bool | true: Loads the entire filtered tree at once. Best for small trees. false: (Recommended) Lazy loads children on demand. Essential for large trees. | false |
option_tree_type_field | string | (Optional) A column to source the _type property from, used for custom icons/styling on the frontend. | 'category_type' |
additionalOptionQuery() | method | This hook is also available to filter the tree query. | return $query->where('status', 'active'); |
- Example:
CategoryController.php
Method 3: postGetOptionCompoundTree()
- Purpose: Provides a complex hierarchical list built from multiple related models (e.g., Groups -> Sections -> Categories). This method is designed exclusively for lazy loading.
- Endpoint:
POST {controller-base}/get-option-compound-tree - Configuration in Child Controller: This method is configured using a single, detailed array property.
| Property | Type | Description |
|---|---|---|
option_compound_tree_config | array | Required. An associative array defining the entire hierarchy. See the example below for the structure. |
additionalOptionQuery() | method | This hook applies to every query made by this method, allowing for global filters across all models in the tree. |
-
Structure of
option_compound_tree_config: The array key (e.g.,'group') becomes the_typeof the node. Each entry is an array with these keys: -
model: The Eloquent model class. -
prefix: A unique string prefix for the node’s ID to prevent collisions (e.g.,'group'). -
parent_type: The_typeof the parent model, ornullif it’s a root node. -
foreign_key: The column on this model’s table that links to the parent’s primary key. -
primary_key: The primary key column of this model. -
text_fields: Array of columns for the display name. -
search_fields: Array of columns to search against. -
self_referencing_key: (Optional) If this model can have its own children (like categories and sub-categories), specify the parent ID column here. -
Example:
DocumentStructureController.php
Part 2: Frontend - Vue.js Components
The system uses one primary component,SelectAdvancedDialog.vue, which internally uses a recursive SelectItemNode.vue to render the list. You will only ever need to use SelectAdvancedDialog.vue in your pages.
Component: SelectAdvancedDialog.vue
Props
| Prop | Type | Default | Description |
|---|---|---|---|
value | String,Array | null | The selected value(s). Use with v-model. For single mode, it’s the ID. For multi mode, it’s an array of IDs. |
selectedItems | Array | [] | An array of the full selected item objects. Use with the .sync modifier (:selected-items.sync="...") to get the complete data of the selected nodes. |
mode | String | 'single' | Selection mode. Can be 'single' (radio buttons) or 'multi' (checkboxes). |
url | String | (req) | The full URL to the backend API endpoint (e.g., /api/user/get-option). |
lazyLoad | Boolean | false | Set to true to enable lazy loading for tree structures. The backend endpoint must support this (postGetOptionTree or postGetOptionCompoundTree). |
treeMode | String | 'simple' | Specifies the payload for lazy loading. 'simple' for postGetOptionTree (sends parentId). 'compound' for postGetOptionCompoundTree (sends parentId, parentType). |
Events
@input: Emitted when the selection is confirmed. Used byv-model.@update:selectedItems: Emitted when the selection is confirmed. Used by the.syncmodifier.
