The SearchController provides HTMX-powered search functionality for categories and icons, returning partial views for dynamic UI updates.
Class Overview
namespace App\Http\Controllers;
use App\Models\Category;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Config;
class SearchController extends Controller
Routes
| Method | Route | Action | Middleware |
|---|
| POST | /search/icons | searchIcons | auth, verified |
| POST | /search/categories/{type} | searchCategories | auth, verified |
Methods
searchCategories()
Search user’s categories by name and type.
public function searchCategories(Request $request, $type)
The HTTP request containing search query
Category type filter: income, expense, correction, or transfer
Request Parameters:
Search query to filter categories by name (case-insensitive partial match)
Returns: View - Partial view categories.partials.results with filtered categories
Response Data:
Filtered categories matching search criteria, ordered by latest first, with eager-loaded transactions
Query Logic:
- Filter by current user
- Filter by category type
- Filter by name (partial match)
- Order by latest created
- Eager load transaction relationships
Example Implementation:
public function searchCategories(Request $request, $type)
{
$search = $request->input('search');
$categories = Category::query()
->latest()
->with('transactions')
->where('user_id', Auth::user()->id)
->where('type', $type)
->where(function ($query) use ($search) {
$query->where('name', 'like', '%'.$search.'%');
})
->get();
return view('categories.partials.results', compact('categories'));
}
HTMX Usage:
<input
type="text"
name="search"
hx-post="/search/categories/expense"
hx-trigger="keyup changed delay:300ms"
hx-target="#category-results"
placeholder="Search expense categories..."
>
<div id="category-results">
<!-- Results rendered here -->
</div>
searchIcons()
Search available icons by name and metadata tags.
public function searchIcons(Request $request)
The HTTP request containing icon search query
Request Parameters:
Search query to filter icons by name or metadata tags (case-insensitive)
Returns: View - Partial view categories.partials.icons with filtered icons
Response Data:
Array of icon filenames matching the search query
Search Algorithm:
- Load icon metadata from
config/icons.php
- Sort icons alphabetically
- Filter by:
- Icon filename contains query (case-insensitive)
- OR any metadata tag contains query (case-insensitive)
- Return matching icon filenames
Example Implementation:
public function searchIcons(Request $request)
{
$query = strtolower($request->input('icon-search', ''));
$iconMetadata = Config::get('icons');
usort($iconMetadata, function ($a, $b) {
return strcmp($a['icon'], $b['icon']);
});
$icons = [];
foreach ($iconMetadata as $data) {
if (stripos($data['icon'], $query) !== false || $this->matchesKeywords($query, $data['tags'])) {
$icons[] = $data['icon'];
}
}
return view('categories.partials.icons', compact('icons'));
}
private function matchesKeywords($query, $keywords)
{
foreach ($keywords as $keyword) {
if (stripos($keyword, $query) !== false) {
return true;
}
}
return false;
}
Icon Metadata Structure:
// config/icons.php
return [
[
'icon' => 'shopping-cart.png',
'tags' => ['shopping', 'cart', 'purchase', 'buy']
],
[
'icon' => 'restaurant.png',
'tags' => ['food', 'dining', 'restaurant', 'meal']
],
// ... more icons
];
HTMX Usage:
<input
type="text"
name="icon-search"
hx-post="/search/icons"
hx-trigger="keyup changed delay:300ms"
hx-target="#icon-grid"
placeholder="Search icons..."
>
<div id="icon-grid">
<!-- Icon grid rendered here -->
</div>
Example Requests
Search Categories
# Search expense categories for "food"
POST /search/categories/expense
Content-Type: application/x-www-form-urlencoded
search=food
# Response: HTML partial with matching categories
Search Icons
# Search icons for "shopping"
POST /search/icons
Content-Type: application/x-www-form-urlencoded
icon-search=shopping
# Response: HTML partial with icon grid (shopping-cart.png, etc.)
Both search methods use HTMX with debouncing (delay:300ms) to reduce server requests while typing.
Icon search loads all metadata into memory. For large icon sets (>1000 icons), consider caching the metadata or implementing pagination.