fix(pagination): update URL on pagination and search
This commit addresses two issues with pagination and search: 1. **Pagination URL Update**: Added `hx-push-url` to pagination buttons in the customer, order, and invoice list templates. This ensures the browser URL and history are updated when navigating pages via HTMX. The query parameters for `status` and `search` are now conditionally included, preventing empty parameters (e.g., `&status=`) in the URL. 2. **Search URL Reset**: Updated the `CustomerList` handler to send the `HX-Push-Url` header when performing a search via HTMX. This ensures that when a search is executed (or cleared), the URL correctly reflects the new state (reseting the page to 1), fixing a mismatch where the URL could show page 4 while the content was reset to page 1.
This commit is contained in:
parent
aa3b63095c
commit
2dfe0a48ea
@ -1,6 +1,7 @@
|
|||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
@ -39,6 +40,13 @@ func (h *Handler) CustomerList(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
// HTMX partial for search
|
// HTMX partial for search
|
||||||
if r.Header.Get("HX-Request") == "true" && r.URL.Query().Get("partial") == "true" {
|
if r.Header.Get("HX-Request") == "true" && r.URL.Query().Get("partial") == "true" {
|
||||||
|
// Construct clean URL for history
|
||||||
|
u := fmt.Sprintf("/customers?page=%d", page)
|
||||||
|
if search != "" {
|
||||||
|
u += "&search=" + search
|
||||||
|
}
|
||||||
|
w.Header().Set("HX-Push-Url", u)
|
||||||
|
|
||||||
h.renderPartial(w, "customers/list.html", "customer-table", data)
|
h.renderPartial(w, "customers/list.html", "customer-table", data)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@ -72,7 +72,8 @@
|
|||||||
<nav class="isolate inline-flex -space-x-px rounded-md shadow-sm" aria-label="Pagination">
|
<nav class="isolate inline-flex -space-x-px rounded-md shadow-sm" aria-label="Pagination">
|
||||||
{{if .HasPrev}}
|
{{if .HasPrev}}
|
||||||
<button
|
<button
|
||||||
hx-get="/customers?page={{.PrevPage}}&search={{.Search}}&partial=true"
|
hx-get="/customers?page={{.PrevPage}}{{if .Search}}&search={{.Search}}{{end}}&partial=true"
|
||||||
|
hx-push-url="/customers?page={{.PrevPage}}{{if .Search}}&search={{.Search}}{{end}}"
|
||||||
hx-target="#customer-table"
|
hx-target="#customer-table"
|
||||||
class="relative inline-flex items-center rounded-l-md px-2 py-2 text-gray-400 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:z-20 focus:outline-offset-0">
|
class="relative inline-flex items-center rounded-l-md px-2 py-2 text-gray-400 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:z-20 focus:outline-offset-0">
|
||||||
<span class="sr-only">Previous</span>
|
<span class="sr-only">Previous</span>
|
||||||
@ -83,7 +84,8 @@
|
|||||||
{{end}}
|
{{end}}
|
||||||
{{if .HasNext}}
|
{{if .HasNext}}
|
||||||
<button
|
<button
|
||||||
hx-get="/customers?page={{.NextPage}}&search={{.Search}}&partial=true"
|
hx-get="/customers?page={{.NextPage}}{{if .Search}}&search={{.Search}}{{end}}&partial=true"
|
||||||
|
hx-push-url="/customers?page={{.NextPage}}{{if .Search}}&search={{.Search}}{{end}}"
|
||||||
hx-target="#customer-table"
|
hx-target="#customer-table"
|
||||||
class="relative inline-flex items-center rounded-r-md px-2 py-2 text-gray-400 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:z-20 focus:outline-offset-0">
|
class="relative inline-flex items-center rounded-r-md px-2 py-2 text-gray-400 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:z-20 focus:outline-offset-0">
|
||||||
<span class="sr-only">Next</span>
|
<span class="sr-only">Next</span>
|
||||||
|
|||||||
@ -76,7 +76,8 @@
|
|||||||
<nav class="isolate inline-flex -space-x-px rounded-md shadow-sm" aria-label="Pagination">
|
<nav class="isolate inline-flex -space-x-px rounded-md shadow-sm" aria-label="Pagination">
|
||||||
{{if .HasPrev}}
|
{{if .HasPrev}}
|
||||||
<button
|
<button
|
||||||
hx-get="/invoices?page={{.PrevPage}}&status={{.FilterStatus}}&partial=true"
|
hx-get="/invoices?page={{.PrevPage}}{{if .FilterStatus}}&status={{.FilterStatus}}{{end}}&partial=true"
|
||||||
|
hx-push-url="/invoices?page={{.PrevPage}}{{if .FilterStatus}}&status={{.FilterStatus}}{{end}}"
|
||||||
hx-target="#invoice-table"
|
hx-target="#invoice-table"
|
||||||
class="relative inline-flex items-center rounded-l-md px-2 py-2 text-gray-400 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:z-20 focus:outline-offset-0">
|
class="relative inline-flex items-center rounded-l-md px-2 py-2 text-gray-400 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:z-20 focus:outline-offset-0">
|
||||||
<span class="sr-only">Previous</span>
|
<span class="sr-only">Previous</span>
|
||||||
@ -87,7 +88,8 @@
|
|||||||
{{end}}
|
{{end}}
|
||||||
{{if .HasNext}}
|
{{if .HasNext}}
|
||||||
<button
|
<button
|
||||||
hx-get="/invoices?page={{.NextPage}}&status={{.FilterStatus}}&partial=true"
|
hx-get="/invoices?page={{.NextPage}}{{if .FilterStatus}}&status={{.FilterStatus}}{{end}}&partial=true"
|
||||||
|
hx-push-url="/invoices?page={{.NextPage}}{{if .FilterStatus}}&status={{.FilterStatus}}{{end}}"
|
||||||
hx-target="#invoice-table"
|
hx-target="#invoice-table"
|
||||||
class="relative inline-flex items-center rounded-r-md px-2 py-2 text-gray-400 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:z-20 focus:outline-offset-0">
|
class="relative inline-flex items-center rounded-r-md px-2 py-2 text-gray-400 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:z-20 focus:outline-offset-0">
|
||||||
<span class="sr-only">Next</span>
|
<span class="sr-only">Next</span>
|
||||||
|
|||||||
@ -78,7 +78,8 @@
|
|||||||
<nav class="isolate inline-flex -space-x-px rounded-md shadow-sm" aria-label="Pagination">
|
<nav class="isolate inline-flex -space-x-px rounded-md shadow-sm" aria-label="Pagination">
|
||||||
{{if .HasPrev}}
|
{{if .HasPrev}}
|
||||||
<button
|
<button
|
||||||
hx-get="/orders?page={{.PrevPage}}&status={{.FilterStatus}}&partial=true"
|
hx-get="/orders?page={{.PrevPage}}{{if .FilterStatus}}&status={{.FilterStatus}}{{end}}&partial=true"
|
||||||
|
hx-push-url="/orders?page={{.PrevPage}}{{if .FilterStatus}}&status={{.FilterStatus}}{{end}}"
|
||||||
hx-target="#order-table"
|
hx-target="#order-table"
|
||||||
class="relative inline-flex items-center rounded-l-md px-2 py-2 text-gray-400 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:z-20 focus:outline-offset-0">
|
class="relative inline-flex items-center rounded-l-md px-2 py-2 text-gray-400 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:z-20 focus:outline-offset-0">
|
||||||
<span class="sr-only">Previous</span>
|
<span class="sr-only">Previous</span>
|
||||||
@ -89,7 +90,8 @@
|
|||||||
{{end}}
|
{{end}}
|
||||||
{{if .HasNext}}
|
{{if .HasNext}}
|
||||||
<button
|
<button
|
||||||
hx-get="/orders?page={{.NextPage}}&status={{.FilterStatus}}&partial=true"
|
hx-get="/orders?page={{.NextPage}}{{if .FilterStatus}}&status={{.FilterStatus}}{{end}}&partial=true"
|
||||||
|
hx-push-url="/orders?page={{.NextPage}}{{if .FilterStatus}}&status={{.FilterStatus}}{{end}}"
|
||||||
hx-target="#order-table"
|
hx-target="#order-table"
|
||||||
class="relative inline-flex items-center rounded-r-md px-2 py-2 text-gray-400 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:z-20 focus:outline-offset-0">
|
class="relative inline-flex items-center rounded-r-md px-2 py-2 text-gray-400 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:z-20 focus:outline-offset-0">
|
||||||
<span class="sr-only">Next</span>
|
<span class="sr-only">Next</span>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user