Skip to content

Adding Search and Filtering

Search and filtering are important features that help users quickly find what they need in your application. As the data managed by the application data grows, these features become essential for maintaining a good user experience.

Why Add Search and Filtering?

  • Improved user experience: Users can find information quickly instead of scrolling through long lists or cycle through all pages,
  • Better performance: Display only relevant results instead of loading all data,
  • Increased engagement: Users interact more with applications that help them find content efficiently.

This guide walks you through implementing search and filtering functionality in your Slim MVC application.


It’s important to understand the difference between search and filtering before implementing these features:

  • What: Text-based queries that look for matches in content
  • User Input: Free-text search box where users type keywords
  • Database: Usually uses LIKE queries or full-text search
  • Examples:
    • Searching for “laptop” in product names/descriptions
    • Finding users by typing part of their name
    • Looking for posts containing specific words

  • What: Narrowing results based on predefined criteria
  • User Input: Dropdowns, checkboxes, radio buttons, date pickers
  • Database: Uses exact matches with WHERE clauses
  • Examples:
    • Filter by category (Electronics, Clothing, Books)
    • Filter by status (Active, Inactive, Pending)
    • Filter by date range or price range

Most applications use both search and filtering together:

  • Search box for text queries: “Find products containing ‘gaming’”
  • Filters for structured data: “In Electronics category”, “Under $500”, “In stock only”

  1. Add search methods to your model class:
    • search($criteria) => Search with multiple filters
    • getFiltered($filters) => Apply specific filters
    • getAllPaginated($page, $limit, $search) => Paginated results with search
  2. Keep all data logic in the model following MVC pattern
  1. Update your controller’s index method to accept search parameters
  2. Get search terms from query parameters using $request->getQueryParams()
  3. Pass search parameters to your model’s search methods
  4. Pass current search values back to the view for form persistence

  1. Add a search form to your index.php view
  2. Use GET method so search parameters appear in URL
  3. Make form fields retain their values using passed data
  4. Include filter options (dropdowns, checkboxes) as needed

Basic Search Implementation (in Controller):

  1. Extract search parameters from query string
  2. Validate and sanitize search inputs
  3. Pass validated parameters to your model’s search methods
  4. Get filtered results from model and pass to view

Model Implementation:

  1. Create search methods in your model that handle data filtering
  2. Keep all database queries and data logic in the model
  3. Return structured data back to the controller

Common Filter Types:

  • Text Search: Search in specific fields (name, description, etc.)
  • Category Filter: Dropdown with predefined options
  • Date Range: Start and end date filtering
  • Status Filter: Active/inactive, published/draft, etc.
  • Sorting: Order by different fields (name, date, price, etc.)

  1. Check if filtered results are empty
  2. Display appropriate message to user
  3. Provide option to clear filters
  4. Show total count of results

  1. Add pagination methods to your model (e.g., getAllPaginated($page, $limit, $filters))
  2. Calculate total number of filtered results in the model
  3. Determine current page from query parameters in controller
  4. Call model’s pagination methods with search filters
  5. Generate pagination links in view that preserve search parameters

// Your existing index route handles search automatically
$app->get('/products', [ProductController::class, 'index'])
->setName('products.index');
// Optional: dedicated search route
$app->get('/products/search', [ProductController::class, 'search'])
->setName('products.search');

Getting Search Parameters:

  1. Use $request->getQueryParams() to get all query string data
  2. Provide default values for missing parameters
  3. Validate search inputs before using them
  4. Store search parameters to pass back to view

Preserving Search State:

  1. When redirecting after operations (create/update/delete), preserve search parameters
  2. Use $query_params in your redirect calls to maintain current search
  3. Include current page number if using pagination

Search URL Examples:

  • Basic search: /products?search=laptop
  • Multiple filters: /products?search=laptop&category=electronics&status=active
  • With pagination: /products?search=laptop&page=2
  • With sorting: /products?search=laptop&sort=price&order=asc

Search Form Best Practices:

  1. Use GET method for search forms
  2. Include hidden fields for maintaining sort order
  3. Add “Clear Filters” link that goes to base index route
  4. Show current search criteria above results
  5. Display result count

User Experience:

  1. Show loading states for search operations
  2. Highlight search terms in results
  3. Provide search suggestions if possible
  4. Make it clear when no results are found
  5. Allow users to easily modify their search

After Create/Update/Delete:

  1. Redirect back to index with preserved search parameters
  2. Use flash messages to show success/error feedback
  3. Maintain user’s current view state

Example Redirect After Delete:

// Preserve current search when redirecting
$currentSearch = $request->getQueryParams();
return $this->redirect($request, $response, 'products.index', [], $currentSearch);