Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,81 @@ The default modern color palette includes:
- **Warning**: Amber (#f59e0b)
- **Danger**: Modern red (#ef4444)

## Autocomplete + Create Field (Bootstrap 5)

This package includes reusable backend traits and a Bootstrap 5 field partial for "search and create if missing" flows.

### 1) Controller traits

Use one or both traits from:

- `ByTIC\AdminBase\Library\Controllers\Traits\HasAutocompleteSearchTrait`
- `ByTIC\AdminBase\Library\Controllers\Traits\HasAutocompleteCreateTrait`

You must implement:

- `autocompleteSearchFetchRecords(string $query, int $limit): iterable`
- `autocompleteCreatePersistRecord(string $name): mixed`

Optional extension points:

- duplicate lookup: `autocompleteCreateFindDuplicateRecord(string $name): mixed`
- request parameter names (`q`, `limit`, `name`)
- limits, error messages, and record formatting

### 2) Response contract

Search success:

```json
{
"success": true,
"data": [{"id": 1, "label": "Example"}],
"meta": {"query": "exa", "limit": 10, "count": 1}
}
```

Create success:

```json
{
"success": true,
"data": {"id": 1, "label": "Example"},
"meta": {"created": true}
}
```

Error:

```json
{
"success": false,
"error": {"code": "duplicate", "message": "...", "details": {}}
}
```

### 3) View partial

Use field partial:

- `/abstract/modules/item-form/fields/autocomplete_create`

Expected variables:

- required: `field`, `searchUrl`
- optional: `createUrl`, `selectedId`, `selectedLabel`, `label`, `placeholder`, `minChars`, `limit`, `required`, `readonly`

### 4) Frontend behavior

The Bootstrap 5 admin bundle now includes an autocomplete component that:

- debounces search requests
- renders results dropdown
- supports keyboard navigation and selection
- shows inline "create new" when no results
- creates and selects new record via AJAX
- handles Turbo navigation lifecycle cleanup

#### UI INSPIRATION
https://coreui.io/
https://github.com/coreui/coreui-free-bootstrap-admin-template
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
.btc-autocomplete-create-field {
.btc-autocomplete-create-menu {
max-height: 260px;
overflow-y: auto;
margin-top: .125rem;
border: 1px solid var(--bs-border-color);
box-shadow: 0 .5rem 1rem rgba(0, 0, 0, .12);
}

.btc-autocomplete-create-option.active,
.btc-autocomplete-create-option:active {
background-color: var(--bs-primary);
color: var(--bs-white);
}

.btc-autocomplete-create-new {
border-top: 1px solid var(--bs-border-color-translucent);
font-weight: 500;
}

.btc-autocomplete-create-feedback {
margin-top: .35rem;
}

.btc-autocomplete-create-reset {
min-width: 2.5rem;
}

&.is-loading {
.btc-autocomplete-create-input {
background-image: linear-gradient(90deg, rgba(255, 255, 255, 0) 0%, color-mix(in srgb, var(--bs-primary) 10%, transparent) 50%, rgba(255, 255, 255, 0) 100%);
background-size: 200% 100%;
animation: btc-autocomplete-loading 1s linear infinite;
}
}
}

@keyframes btc-autocomplete-loading {
from {
background-position: 200% 0;
}
to {
background-position: -200% 0;
}
}
2 changes: 1 addition & 1 deletion resources/themes/bootstrap5/assets/sass/ui/core.scss
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
@import "cards";
@import "autocomplete-create";
@import "content";
@import "content-header";
@import "header";
@import "sidebar";
@import "modern-enhancements";

2 changes: 2 additions & 0 deletions resources/themes/bootstrap5/assets/scripts/admin/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { TopMenuComponent } from './components/top-menu';
import { PanelComponent } from './components/panel';
import { ThemeComponent } from './components/theme';
import { AjaxComponent, applyPageOption } from './components/ajax';
import { AutocompleteCreateComponent } from './components/AutocompleteCreate';

/**
* ByticAdminApp
Expand Down Expand Up @@ -34,6 +35,7 @@ class ByticAdminApp {
.register(new TopMenuComponent())
.register(new PanelComponent())
.register(new ThemeComponent())
.register(new AutocompleteCreateComponent())
.register(new AjaxComponent());
}

Expand Down
Loading