Skip to content

Commit

Permalink
Using htmx.prefers to return the preferred content.
Browse files Browse the repository at this point in the history
  • Loading branch information
btoms20 committed Mar 8, 2024
1 parent 23edc1f commit ac92750
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 28 deletions.
34 changes: 22 additions & 12 deletions Sources/Demo/Controllers/InfiniteScroll.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,30 @@ struct InfiniteScrollController: RouteCollection {
let infiniteScroll = routes.grouped("infinite")

infiniteScroll.get { req async throws in
var nextPage = 1
if let pageParam = try? req.query.decode(Payload.NextPage.self) {
nextPage = pageParam.page
}

if nextPage == 1 {
return try await req.htmx.render("InfiniteScroll/infinite-scroll", ["in": generateAgents(page: nextPage)])
} else {
// Extract the `page` param from the URL if one is present, otherwise default to the first page
let nextPage = extractNextPage(req: req)?.page ?? 1
// Switch over the preferred response type
switch req.htmx.prefers {
case .html:
// The whole page is being requested
return try await req.htmx.render("InfiniteScroll/infinite-scroll", ["dto": generateAgents(page: nextPage)])
case .htmx:
// Just the fragment containing the next page of Agents is being requested
try await Task.sleep(for: .seconds(1))
return try await req.htmx.render("InfiniteScroll/infinite-rows", ["in": generateAgents(page: nextPage)])
return try await req.htmx.render("InfiniteScroll/infinite-rows", ["dto": generateAgents(page: nextPage)])
case .api:
// The next page of Agents is being requested as JSON
return try await generateAgents(page: nextPage).encodeResponse(for: req)
}
}
}

/// Extracts the `page` param from the URL if one is present
private func extractNextPage(req:Request) -> Payload.NextPage? {
return try? req.query.decode(Payload.NextPage.self)
}

/// Just generates the next ten Agents starting at the specified Page
func generateAgents(page: Int) -> Payload {
let startIndex = page * 20
return Payload(
Expand All @@ -43,14 +53,14 @@ struct InfiniteScrollController: RouteCollection {
let page:Int
}

struct User:Content {
struct Agent:Content {
let name:String
let email:String
var id:String
}

let agents:[User]
let lastAgent:User
let agents:[Agent]
let lastAgent:Agent
let nextPage: Int
}
}
16 changes: 8 additions & 8 deletions Sources/Demo/Views/InfiniteScroll/infinite-rows.leaf
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
#for(user in in.agents):
#for(agent in dto.agents):
<tr style="margin-bottom: 1.5em;">
<td style="padding-bottom: 1.5em;">#(user.name)</td>
<td style="padding-bottom: 1.5em;">#(user.email)</td>
<td style="padding-bottom: 1.5em;">#(user.id)</td>
<td style="padding-bottom: 1.5em;">#(agent.name)</td>
<td style="padding-bottom: 1.5em;">#(agent.email)</td>
<td style="padding-bottom: 1.5em;">#(agent.id)</td>
</tr>
#endfor
<tr style="margin-bottom: 1.5em;"
hx-get="/infinite/?page=#(in.nextPage)"
hx-get="/infinite/?page=#(dto.nextPage)"
hx-trigger="revealed"
hx-swap="afterend">
<td style="padding-bottom: 1.5em;">#(in.lastAgent.name)</td>
<td style="padding-bottom: 1.5em;">#(in.lastAgent.email)</td>
<td style="padding-bottom: 1.5em;">#(in.lastAgent.id)</td>
<td style="padding-bottom: 1.5em;">#(dto.lastAgent.name)</td>
<td style="padding-bottom: 1.5em;">#(dto.lastAgent.email)</td>
<td style="padding-bottom: 1.5em;">#(dto.lastAgent.id)</td>
</tr>
16 changes: 8 additions & 8 deletions Sources/Demo/Views/InfiniteScroll/infinite-scroll.leaf
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,20 @@
</tr>
</thead>
<tbody id="tbody">
#for(user in in.agents):
#for(agent in dto.agents):
<tr>
<td style="padding-bottom: 1.5em;">#(user.name)</td>
<td style="padding-bottom: 1.5em;">#(user.email)</td>
<td style="padding-bottom: 1.5em;">#(user.id)</td>
<td style="padding-bottom: 1.5em;">#(agent.name)</td>
<td style="padding-bottom: 1.5em;">#(agent.email)</td>
<td style="padding-bottom: 1.5em;">#(agent.id)</td>
</tr>
#endfor
<tr style="margin-bottom: 1.5em;"
hx-get="/infinite/?page=#(in.nextPage)"
hx-get="/infinite/?page=#(dto.nextPage)"
hx-trigger="revealed"
hx-swap="afterend">
<td style="padding-bottom: 1.5em;">#(in.lastAgent.name)</td>
<td style="padding-bottom: 1.5em;">#(in.lastAgent.email)</td>
<td style="padding-bottom: 1.5em;">#(in.lastAgent.id)</td>
<td style="padding-bottom: 1.5em;">#(dto.lastAgent.name)</td>
<td style="padding-bottom: 1.5em;">#(dto.lastAgent.email)</td>
<td style="padding-bottom: 1.5em;">#(dto.lastAgent.id)</td>
</tr>
</tbody>
</table>
Expand Down

0 comments on commit ac92750

Please sign in to comment.