Skip to content

active search - #37

Merged
yamcodes merged 1 commit into
mainfrom
34-remove-search-button-live-search-with-htmx
Mar 20, 2026
Merged

active search#37
yamcodes merged 1 commit into
mainfrom
34-remove-search-button-live-search-with-htmx

Conversation

@yamcodes

@yamcodes yamcodes commented Mar 20, 2026

Copy link
Copy Markdown
Owner
  • Move empty state HTML for the contact table to a reusable fragment.
  • Implement HTMX for dynamic search updates on keyup with delay.
  • Update ContactController to return HTML fragment for HTMX requests.
  • Improve empty state design consistency across templates.

Closes #34

Summary by CodeRabbit

  • Improvements
    • Search now dynamically updates results without requiring a full page reload
    • Enhanced "No contacts found" messaging when search returns empty results

- Move empty state HTML for the contact table to a reusable fragment.
- Implement HTMX for dynamic search updates on keyup with delay.
- Update `ContactController` to return HTML fragment for HTMX requests.
- Improve empty state design consistency across templates.
@yamcodes yamcodes linked an issue Mar 20, 2026 that may be closed by this pull request
@coderabbitai

coderabbitai Bot commented Mar 20, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

Implemented live search functionality using HTMX. Modified ContactController to detect HTMX search requests via trigger ID and conditionally return either a partial template fragment or full page. Updated templates to support debounced live search with HTMX attributes and simplified empty state handling across views.

Changes

Cohort / File(s) Summary
Controller Enhancement
src/main/java/codes/yam/contacts/ContactController.java
Added HtmxRequest parameter to contacts() handler. Introduced conditional logic that checks trigger ID: returns fragment view fragments/contact-list-rows :: rows when triggered by nav-search, otherwise returns full page view. Extracts page.getContent() separately into contacts model attribute.
Template Live Search Configuration
src/main/resources/templates/layout.html
Enhanced search input with HTMX attributes: hx-get="/contacts", hx-trigger="search keyup changed delay:200ms", and hx-target="tbody" for live search functionality with debounce.
View Refactoring
src/main/resources/templates/contacts/index.html
Removed empty state conditional wrapper (th:unless="${contactPage.content.isEmpty()}") and associated empty-state messaging block to consolidate empty handling into the reusable fragment.
Fragment Empty State
src/main/resources/templates/fragments/contact-list-rows.html
Added search as a fragment variable declaration and new conditional table row that displays "No contacts found" message when contacts list is empty, with optional search-term guidance.

Sequence Diagram

sequenceDiagram
    actor User
    participant Browser
    participant Controller
    participant Service
    participant Template

    User->>Browser: Types in search input
    Browser->>Browser: Debounce trigger (200ms delay)<br/>after keyup + changed
    Browser->>Controller: HTMX GET /contacts<br/>(hx-trigger: "nav-search")
    Controller->>Service: contactService.list(q, pageable)
    Service-->>Controller: Page<Contact>
    Controller->>Template: Render fragment<br/>(contacts, search vars)
    Template->>Template: Check if contacts.isEmpty()
    alt Contacts Found
        Template-->>Browser: HTML rows (th:each loop)
    else No Contacts Found
        Template-->>Browser: Empty state row
    end
    Browser->>Browser: HTMX swaps tbody content
    Browser->>User: Updated results displayed
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 As users type, the search comes alive,
HTMX fragments help our results thrive!
No button clicks, just debounced delight,
Live search hopping—pure magic in sight! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'active search' directly reflects the main change: implementing HTMX-driven live search functionality on the contact search input.
Linked Issues check ✅ Passed The PR successfully implements all requirements from issue #34: removes the Search button and Clear link, adds HTMX live search with debounce delay, and returns only table rows fragment instead of full page.
Out of Scope Changes check ✅ Passed All changes are directly aligned with implementing active/live search: controller method updated for HTMX support, templates modified to handle fragments and empty states, and search input enhanced with HTMX attributes.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 34-remove-search-button-live-search-with-htmx
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/main/resources/templates/contacts/index.html (1)

31-32: Pagination text may display confusingly for empty results.

When contactPage.content is empty, the pagination text will render as "1–0 of 0", which could confuse users. Consider hiding or adjusting the pagination controls when there are no results.

💡 Potential fix to hide pagination when empty
-                <div class="flex items-center gap-1">
+                <div class="flex items-center gap-1" th:if="${!contactPage.content.isEmpty()}">
                     <span class="px-1 text-xs text-base-content/50"
                           th:text="${contactPage.number * contactPage.size + 1} + '–' + ${contactPage.isLast() ? contactPage.totalElements : (contactPage.number + 1) * contactPage.size} + ' of ' + ${`#numbers.formatInteger`(contactPage.totalElements, 0, 'COMMA')}"></span>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/resources/templates/contacts/index.html` around lines 31 - 32, The
pagination line using contactPage currently renders "1–0 of 0" for empty
results; wrap or replace the span that computes the range (the element with
th:text using contactPage.number, contactPage.size, contactPage.isLast(), and
contactPage.totalElements) with a Thymeleaf conditional so it is only shown when
contactPage.content is not empty (e.g., th:if="${not
contactPage.content.isEmpty()}" or th:if="${contactPage.totalElements > 0}"), or
alternatively render a clearer message like "0 of 0" when
contactPage.totalElements == 0 by using a ternary expression on
contactPage.totalElements to avoid displaying "1–0".
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/main/resources/templates/contacts/index.html`:
- Around line 31-32: The pagination line using contactPage currently renders
"1–0 of 0" for empty results; wrap or replace the span that computes the range
(the element with th:text using contactPage.number, contactPage.size,
contactPage.isLast(), and contactPage.totalElements) with a Thymeleaf
conditional so it is only shown when contactPage.content is not empty (e.g.,
th:if="${not contactPage.content.isEmpty()}" or
th:if="${contactPage.totalElements > 0}"), or alternatively render a clearer
message like "0 of 0" when contactPage.totalElements == 0 by using a ternary
expression on contactPage.totalElements to avoid displaying "1–0".

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 6af92ec4-17e0-4916-a65f-a57539b9bbe6

📥 Commits

Reviewing files that changed from the base of the PR and between b148813 and 5b3dfe1.

📒 Files selected for processing (4)
  • src/main/java/codes/yam/contacts/ContactController.java
  • src/main/resources/templates/contacts/index.html
  • src/main/resources/templates/fragments/contact-list-rows.html
  • src/main/resources/templates/layout.html

@yamcodes
yamcodes merged commit 217e8c1 into main Mar 20, 2026
1 check passed
@yamcodes
yamcodes deleted the 34-remove-search-button-live-search-with-htmx branch March 20, 2026 06:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

active search

1 participant