mirror of
https://github.com/bigskysoftware/hypermedia-systems.git
synced 2025-08-14 00:04:00 -04:00
Compare commits
3 Commits
ab8b4a7fbe
...
3236cb9417
Author | SHA1 | Date | |
---|---|---|---|
|
3236cb9417 | ||
|
19755a1723 | ||
|
dd4515dd08 |
@ -134,7 +134,7 @@ we are going to redirect to another path, the `/contacts` path. Redirects are a
|
|||||||
redirect a client to another location with an HTTP response.
|
redirect a client to another location with an HTTP response.
|
||||||
|
|
||||||
We are going to display a list of contacts as our root page, and, arguably, redirecting to the `/contacts` path to
|
We are going to display a list of contacts as our root page, and, arguably, redirecting to the `/contacts` path to
|
||||||
display this information is a bit more consistent with notion of resources with REST. This is a judgement call on our
|
display this information is a bit more consistent with the notion of resources with REST. This is a judgement call on our
|
||||||
part, and not something we feel is too important, but it makes sense in terms of routes we will set up later in the
|
part, and not something we feel is too important, but it makes sense in terms of routes we will set up later in the
|
||||||
application.
|
application.
|
||||||
|
|
||||||
|
@ -11,7 +11,8 @@ was built using nothing but forms and anchor tags, the traditional hypermedia co
|
|||||||
The application exchanges hypermedia (HTML) with the server over HTTP, issuing `GET` and `POST` HTTP requests and
|
The application exchanges hypermedia (HTML) with the server over HTTP, issuing `GET` and `POST` HTTP requests and
|
||||||
receiving back full HTML documents in response.
|
receiving back full HTML documents in response.
|
||||||
|
|
||||||
It is a basic web application, but it is also definitely a Hypermedia-Driven Application. It is robust, it leverages the web's native technologies, and it is simple to understand.
|
It is a basic web application, but it is also definitely a Hypermedia-Driven Application. It is robust, it leverages the
|
||||||
|
web's native technologies, and it is simple to understand.
|
||||||
|
|
||||||
So what's not to like about the application?
|
So what's not to like about the application?
|
||||||
|
|
||||||
@ -33,7 +34,8 @@ cousins.
|
|||||||
|
|
||||||
We could address this issue by adopting a Single Page Application framework, and updating our server-side to
|
We could address this issue by adopting a Single Page Application framework, and updating our server-side to
|
||||||
provide JSON-based responses. Single Page Applications eliminate the clunkiness of web 1.0 applications by updating a
|
provide JSON-based responses. Single Page Applications eliminate the clunkiness of web 1.0 applications by updating a
|
||||||
web page directly: they mutate the Document Object Model (DOM) directly, without doing a full page refresh.
|
web page without refreshing it: they can mutate parts of the Document Object Model (DOM) of the existing page without
|
||||||
|
needing to replace (and re-render) the entire page.
|
||||||
|
|
||||||
.The DOM
|
.The DOM
|
||||||
****
|
****
|
||||||
@ -55,19 +57,24 @@ with the application sacrificing the advantages of hypermedia in order to provid
|
|||||||
Many web developers today would not even consider the hypermedia approach due to the perceived "`legacy`" feel of these
|
Many web developers today would not even consider the hypermedia approach due to the perceived "`legacy`" feel of these
|
||||||
web 1.0 style applications.
|
web 1.0 style applications.
|
||||||
|
|
||||||
The second, technical point may strike you as a bit pedantic, and we are the first to admit that conversations around
|
Now, the second more technical issue we mentioned may strike you as a bit pedantic, and we are the first to admit that
|
||||||
REST and which HTTP Action is right for a given operation can become very tedious. But still, it's odd that,
|
conversations around REST and which HTTP Action is right for a given operation can become very tedious. But still, it's
|
||||||
when using plain HTML, it is impossible to use HTTP fully.
|
odd that, when using plain HTML, it is impossible to use all the functionality of HTTP!
|
||||||
|
|
||||||
|
Just seems wrong, doesn't it?
|
||||||
|
|
||||||
== A Close Look At A Hyperlink
|
== A Close Look At A Hyperlink
|
||||||
|
|
||||||
It turns out that we can boost the interactivity of our application without resorting to the SPA approach, by using one of several available hypermedia-oriented JavaScript libraries.
|
It turns out that we can boost the interactivity of our application and address both of these issues _without_ resorting
|
||||||
We'll use the library that we've developed, https://htmx.org[htmx], not only because we know it inside and out, but because we built it purely to extend HTML as a hypermedia.
|
to the SPA approach. We can do so by using one of several available _hypermedia-oriented_ JavaScript libraries.
|
||||||
|
In this book, naturally, we will use the library that we've developed, https://htmx.org[htmx]. We will use it not only
|
||||||
|
because we know it inside and out, but also because we built it to extend HTML as a hypermedia and address the issues
|
||||||
|
with legacy HTML applications we mentioned above (as well as few others.)
|
||||||
|
|
||||||
To understand how htmx allows us to improve the UX of our Web 1.0 style
|
Before we get into how htmx allows us to improve the UX of our Web 1.0 style application, let's revisit the
|
||||||
application without abandoning hypermedia, let's revisit the hyperlink/anchor tag from Chapter 1. Recall, a hyperlink
|
hyperlink/anchor tag from Chapter 1. Recall, a hyperlink is what is known as a _hypermedia control_, a mechanism that
|
||||||
is what is known as a _hypermedia control_, a mechanism that describes some sort of interaction by encoding information about that interaction directly and completely within
|
describes some sort of interaction with a server by encoding information about that interaction directly and completely
|
||||||
itself.
|
within the control itself.
|
||||||
|
|
||||||
Consider again this simple anchor tag which, when interpreted by a browser, creates a hyperlink to the website for
|
Consider again this simple anchor tag which, when interpreted by a browser, creates a hyperlink to the website for
|
||||||
this book:
|
this book:
|
||||||
@ -87,8 +94,8 @@ Let's break down exactly what happens with this link:
|
|||||||
* The browser will issue an HTTP `GET` to `https://hypermedia.systems`...
|
* The browser will issue an HTTP `GET` to `https://hypermedia.systems`...
|
||||||
* The browser will load the HTML body of the HTTP response into the browser window, replacing the current document.
|
* The browser will load the HTML body of the HTTP response into the browser window, replacing the current document.
|
||||||
|
|
||||||
So we have four aspects of a simple hypermedia link like this, with the last three aspects supplying the mechanism that distinguishes
|
So we have four aspects of a simple hypermedia link like this, with the last three aspects supplying the mechanism that
|
||||||
a hyperlink from "`normal`" text and makes this a hypermedia control.
|
distinguishes a hyperlink from "`normal`" text and, thus, makes this a hypermedia control.
|
||||||
|
|
||||||
Now, let's take a moment and think about how we can _generalize_ these last three aspects of a hyperlink.
|
Now, let's take a moment and think about how we can _generalize_ these last three aspects of a hyperlink.
|
||||||
|
|
||||||
@ -99,10 +106,10 @@ Consider: what makes anchor tags (and forms) so special?
|
|||||||
Why can't other elements issue HTTP requests as well?
|
Why can't other elements issue HTTP requests as well?
|
||||||
|
|
||||||
For example, why shouldn't `button` elements be able to issue HTTP requests? It seems arbitrary to have to wrap a
|
For example, why shouldn't `button` elements be able to issue HTTP requests? It seems arbitrary to have to wrap a
|
||||||
form tag around a button just to make deleting contacts work in our application.
|
form tag around a button just to make deleting contacts work in our application, for example.
|
||||||
|
|
||||||
Maybe: other elements should be able
|
Maybe: other elements should be able to issue HTTP requests as well. Maybe other elements should be able to act as
|
||||||
to issue HTTP requests as well, and act as hypermedia controls on their own.
|
hypermedia controls on their own.
|
||||||
|
|
||||||
This is our first opportunity to generalize HTML as a hypermedia.
|
This is our first opportunity to generalize HTML as a hypermedia.
|
||||||
|
|
||||||
@ -112,13 +119,13 @@ This is our first opportunity to generalize HTML as a hypermedia.
|
|||||||
HTML could be extended to allow _any_ element to issue a request to the server and act as a hypermedia control.
|
HTML could be extended to allow _any_ element to issue a request to the server and act as a hypermedia control.
|
||||||
====
|
====
|
||||||
|
|
||||||
=== Why Only Clicks & Submits?
|
=== Why Only Click & Submit Events?
|
||||||
|
|
||||||
Next, let's consider the event that triggers the request to the server on our link: a click event.
|
Next, let's consider the event that triggers the request to the server on our link: a click event.
|
||||||
|
|
||||||
Well, what's so special about clicking (in the case of anchors) or submitting (in the case of forms)? Those are just two
|
Well, what's so special about clicking (in the case of anchors) or submitting (in the case of forms) things? Those are
|
||||||
of many, many events that are fired by the DOM, after all. Events like mouse down, or key up, or blur are all events
|
just two of many, many events that are fired by the DOM, after all. Events like mouse down, or key up, or blur are all
|
||||||
you might want to use to issue an HTTP request.
|
events you might want to use to issue an HTTP request.
|
||||||
|
|
||||||
Why shouldn't these other events be able to trigger requests as well?
|
Why shouldn't these other events be able to trigger requests as well?
|
||||||
|
|
||||||
@ -164,10 +171,11 @@ HTML could be extended so that it allows access to the missing three HTTP method
|
|||||||
As a final observation, consider the last aspect of a hyperlink: it replaces the _entire_ screen when a user clicks on it.
|
As a final observation, consider the last aspect of a hyperlink: it replaces the _entire_ screen when a user clicks on it.
|
||||||
|
|
||||||
It turns out that this technical detail is the primary culprit for poor user experience in Web 1.0 Applications.
|
It turns out that this technical detail is the primary culprit for poor user experience in Web 1.0 Applications.
|
||||||
A full page refresh can cause a flash of unstyled content, it destroys the scroll state of the user by scrolling to the
|
A full page refresh can cause a flash of unstyled content, where content "jumps" on the screen as it transitions from
|
||||||
top of the page, and so forth.
|
its initial to its styled final form. It also destroys the scroll state of the user by scrolling to the
|
||||||
|
top of the page, removes focus from a focused element and so forth.
|
||||||
|
|
||||||
But there is no rule saying that hypermedia exchanges _must_ replace the entire document.
|
But, if you think about it, there is no rule saying that hypermedia exchanges _must_ replace the entire document.
|
||||||
|
|
||||||
This gives us our fourth, final and perhaps most important opportunity to generalize HTML:
|
This gives us our fourth, final and perhaps most important opportunity to generalize HTML:
|
||||||
|
|
||||||
@ -202,7 +210,7 @@ can be added to a web application by simply including it via a `script` tag in y
|
|||||||
|
|
||||||
Because of this simple installation model, you can take advantage of tools like public CDNs to install the library.
|
Because of this simple installation model, you can take advantage of tools like public CDNs to install the library.
|
||||||
|
|
||||||
Below is an example using the popular https://unpkg.com[unpkg] Content Delivery Network (CDN) to install version `1.7.0`
|
Below is an example using the popular https://unpkg.com[unpkg] Content Delivery Network (CDN) to install version `1.9.2`
|
||||||
of the library. We use an integrity hash to ensure that the delivered JavaScript content matches what we expect. This
|
of the library. We use an integrity hash to ensure that the delivered JavaScript content matches what we expect. This
|
||||||
SHA can be found on the htmx website.
|
SHA can be found on the htmx website.
|
||||||
|
|
||||||
@ -213,9 +221,9 @@ We also mark the script as `crossorigin="anonymous"` so no credentials will be s
|
|||||||
[source,html]
|
[source,html]
|
||||||
----
|
----
|
||||||
<head>
|
<head>
|
||||||
<script src="https://unpkg.com/htmx.org@1.7.0"
|
<script src="https://unpkg.com/htmx.org@1.9.2"
|
||||||
integrity="sha384-EzBXYPt0/T6gxNp0nuPtLkmRpmDBbjg6WmCUZRLXBBwYYmwAUxzlSGej0ARHX0Bo"
|
integrity="sha384-L6OqL9pRWyyFU3+/bjdSri+iIphTN/bvYyM37tICVyOJkWZLpP2vGn6VUEXgzg6h"
|
||||||
crossorigin="anonymous"></script>
|
crossorigin="anonymous"></script>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
----
|
----
|
||||||
@ -234,11 +242,10 @@ Once htmx has been installed, you can begin using it immediately.
|
|||||||
|
|
||||||
=== No JavaScript Required...
|
=== No JavaScript Required...
|
||||||
|
|
||||||
And here we get to the fun part of htmx: htmx does not require you,
|
And here we get to the interesting part of htmx: htmx does not require you, the user of htmx, to actually write any JavaScript.
|
||||||
the user of htmx, to actually write any JavaScript.
|
|
||||||
|
|
||||||
Instead, you will use _attributes_ placed directly on elements in your HTML to drive more dynamic behavior. Htmx extends
|
Instead, you will use _attributes_ placed directly on elements in your HTML to drive more dynamic behavior. Htmx extends
|
||||||
HTML as a hypermedia, and it wants that extension to be as natural and consistent as possible with existing
|
HTML as a hypermedia, and it is designed so that extension is as natural and consistent as possible with existing
|
||||||
HTML concepts. Just as an anchor tag uses an `href` attribute to specify the URL to retrieve, and forms use an `action`
|
HTML concepts. Just as an anchor tag uses an `href` attribute to specify the URL to retrieve, and forms use an `action`
|
||||||
attribute to specify the URL to submit the form to, htmx uses HTML _attributes_ to specify the URL that an HTTP request
|
attribute to specify the URL to submit the form to, htmx uses HTML _attributes_ to specify the URL that an HTTP request
|
||||||
should be issued to.
|
should be issued to.
|
||||||
@ -282,8 +289,8 @@ Very easy to understand and very consistent with the rest of HTML.
|
|||||||
|
|
||||||
With the request issued by the button above, we get to perhaps the most important thing to understand about htmx:
|
With the request issued by the button above, we get to perhaps the most important thing to understand about htmx:
|
||||||
it expects the response to this AJAX request _to be HTML_. Htmx is an extension of HTML. A native hypermedia control
|
it expects the response to this AJAX request _to be HTML_. Htmx is an extension of HTML. A native hypermedia control
|
||||||
like an anchor tag will typically get an HTML response to a request it creates. Similarly, htmx expects the server to
|
like an anchor tag will typically get an HTML response to an HTTP request it creates. Similarly, htmx expects the server to
|
||||||
respond to the requests that it makes with HTML.
|
respond to the requests that _it_ makes with HTML.
|
||||||
|
|
||||||
This may surprise web developers who are used to responding to an AJAX request with JSON,
|
This may surprise web developers who are used to responding to an AJAX request with JSON,
|
||||||
which is far and away the most common response format for such requests. But AJAX requests are just HTTP requests and
|
which is far and away the most common response format for such requests. But AJAX requests are just HTTP requests and
|
||||||
@ -341,10 +348,10 @@ content into the existing page (rather than replacing the entire page), the ques
|
|||||||
content be placed?
|
content be placed?
|
||||||
|
|
||||||
It turns out that the default htmx behavior is to simply put the returned content inside the element that triggered the
|
It turns out that the default htmx behavior is to simply put the returned content inside the element that triggered the
|
||||||
request. That's obviously _not_ a good thing in the case of our button: we will end up with a list of contacts awkwardly embedded within
|
request. That's _not_ a good thing in the case of our button: we will end up with a list of contacts awkwardly embedded within
|
||||||
the button element. That will look pretty silly and is obviously not what we want.
|
the button element. That will look pretty silly and is obviously not what we want.
|
||||||
|
|
||||||
Fortunately htmx provides another attribute, `hx-target` which can be used to specify exactly where in the DOM the
|
Fortunately htmx provides another attribute, `hx-target` which can be used to specify exactly _where_ in the DOM the
|
||||||
new content should be placed. The value of the `hx-target` attribute is a Cascading Style Sheet (CSS) _selector_ that
|
new content should be placed. The value of the `hx-target` attribute is a Cascading Style Sheet (CSS) _selector_ that
|
||||||
allows you to specify the element to put the new hypermedia content into.
|
allows you to specify the element to put the new hypermedia content into.
|
||||||
|
|
||||||
@ -465,15 +472,14 @@ four opportunities for improvement that we enumerated regarding plain HTML:
|
|||||||
* Opportunity 1: We can now issue an HTTP request with _any_ element (in this case we are using a button).
|
* Opportunity 1: We can now issue an HTTP request with _any_ element (in this case we are using a button).
|
||||||
* Opportunity 3: We can issue _any sort_ of HTTP request we want, `PUT`, `PATCH` and `DELETE`, in particular.
|
* Opportunity 3: We can issue _any sort_ of HTTP request we want, `PUT`, `PATCH` and `DELETE`, in particular.
|
||||||
|
|
||||||
And, with `hx-target` and `hx-swap` we have addressed a third shortcoming:
|
And, with `hx-target` and `hx-swap` we have addressed a third shortcoming: the requirement that the entire page be replaced.
|
||||||
the requirement that the entire page be replaced.
|
|
||||||
|
|
||||||
* Opportunity 4: We can now replace any element we want in our page via transclusion, and we can do so in any manner want.
|
* Opportunity 4: We can now replace any element we want in our page via transclusion, and we can do so in any manner want.
|
||||||
|
|
||||||
So, with only seven relatively simple additional attributes, we have addressed most of the shortcomings of HTML as a
|
So, with only seven relatively simple additional attributes, we have addressed most of the shortcomings of HTML as a
|
||||||
hypermedia that we identified earlier.
|
hypermedia that we identified earlier.
|
||||||
|
|
||||||
What's next? Recall the other shortcoming we noted: the fact that only a `click` event (on an anchor) or a `submit` event
|
What's next? Recall the one other opportunity we noted: the fact that only a `click` event (on an anchor) or a `submit` event
|
||||||
(on a form) can trigger a HTTP request. Let's look at how we can address that limitation.
|
(on a form) can trigger a HTTP request. Let's look at how we can address that limitation.
|
||||||
|
|
||||||
== Using Events
|
== Using Events
|
||||||
@ -547,7 +553,7 @@ Note that we have a comma separated list of events that can trigger this element
|
|||||||
one potential triggering event. We still want to respond to the `click` event and load the contacts, in addition
|
one potential triggering event. We still want to respond to the `click` event and load the contacts, in addition
|
||||||
to handling the `Ctrl-L` keyboard shortcut.
|
to handling the `Ctrl-L` keyboard shortcut.
|
||||||
|
|
||||||
There are, unfortunately, two problems with our `keyup` addition: As it stands, it will trigger requests on _any_ keyup
|
Unfortunately there are two problems with our `keyup` addition: As it stands, it will trigger requests on _any_ keyup
|
||||||
event that occurs. And, worse, it will only trigger when a keyup occurs _within_ this button. The
|
event that occurs. And, worse, it will only trigger when a keyup occurs _within_ this button. The
|
||||||
user would need to tab onto the button to make it active and then begin typing.
|
user would need to tab onto the button to make it active and then begin typing.
|
||||||
|
|
||||||
@ -625,7 +631,7 @@ outlined at the start of this chapter:
|
|||||||
|
|
||||||
That's a grand total of eight, count 'em, _eight_ attributes that all fall squarely within the same conceptual model as
|
That's a grand total of eight, count 'em, _eight_ attributes that all fall squarely within the same conceptual model as
|
||||||
normal HTML and that, by extending HTML as a hypermedia, open up a whole new world of user interaction possibilities
|
normal HTML and that, by extending HTML as a hypermedia, open up a whole new world of user interaction possibilities
|
||||||
within HTML.
|
within it.
|
||||||
|
|
||||||
Here is a table summarizing those opportunities and which htmx attributes address them:
|
Here is a table summarizing those opportunities and which htmx attributes address them:
|
||||||
|
|
||||||
|
@ -255,10 +255,14 @@ support and so on. And, if JavaScript isn't enabled, it will fall back to the n
|
|||||||
|
|
||||||
All this with one htmx attribute.
|
All this with one htmx attribute.
|
||||||
|
|
||||||
The `hx-boost` attribute is more "`magic`" than others. Htmx attributes generally are lower level and require more explicit
|
The `hx-boost` attribute is neat, but is different than other htmx attributes in that it is pretty "`magical`": by
|
||||||
annotation in order to specify exactly what you want htmx to do. In general, this is the design philosophy of htmx:
|
making one small change you modify the behavior of a large number of elements on the page, turning them into
|
||||||
prefer explicit to implicit and obvious to "`magic.`" However, the `hx-boost` attribute is too useful to allow dogma to
|
AJAX-powered elements. Most other htmx attributes are generally lower level and require more explicit annotations in
|
||||||
override practicality, and so it is included as a feature in the library.
|
order to specify exactly what you want htmx to do. In general, this is the design philosophy of htmx: prefer explicit
|
||||||
|
over implicit and obvious over "`magic.`"
|
||||||
|
|
||||||
|
However, the `hx-boost` attribute was too useful to allow dogma to override practicality, and so it is included as a
|
||||||
|
feature in the library.
|
||||||
|
|
||||||
== A Second Step: Deleting Contacts With HTTP DELETE
|
== A Second Step: Deleting Contacts With HTTP DELETE
|
||||||
|
|
||||||
@ -308,9 +312,9 @@ A couple of things to notice:
|
|||||||
Note that we have done something pretty magical here: we have turned this button into a _hypermedia control_. It is no
|
Note that we have done something pretty magical here: we have turned this button into a _hypermedia control_. It is no
|
||||||
longer necessary that this button be placed within a larger `form` tag in order to trigger an HTTP request: it is a
|
longer necessary that this button be placed within a larger `form` tag in order to trigger an HTTP request: it is a
|
||||||
stand-alone, and fully featured hypermedia control on its own. This is at the heart of htmx, allowing any element to become
|
stand-alone, and fully featured hypermedia control on its own. This is at the heart of htmx, allowing any element to become
|
||||||
a hypermedia control and fully participate in the Hypermedia-Driven Application.
|
a hypermedia control and fully participate in a Hypermedia-Driven Application.
|
||||||
|
|
||||||
We should note that, unlike with the `hx-boost` examples above, this solution will _not_ degrade gracefully. To make
|
We should also note that, unlike with the `hx-boost` examples above, this solution will _not_ degrade gracefully. To make
|
||||||
this solution degrade gracefully, we would need to wrap the button in a form element and handle a `POST` on the server
|
this solution degrade gracefully, we would need to wrap the button in a form element and handle a `POST` on the server
|
||||||
side as well.
|
side as well.
|
||||||
|
|
||||||
@ -489,9 +493,9 @@ all while using declarative attributes in our HTML and staying firmly within the
|
|||||||
|
|
||||||
=== Progressive Enhancement?
|
=== Progressive Enhancement?
|
||||||
|
|
||||||
One thing to note about this solution, however, is that it is _not_ a progressive enhancement to our web application: if
|
As we noted earlier about this solution: it is _not_ a progressive enhancement to our web application: if
|
||||||
someone has disabled JavaScript then this "`Delete Contact`" button will no longer work. We could do additional work to keep
|
someone has disabled JavaScript then this "`Delete Contact`" button will no longer work. We would need to do additional
|
||||||
the older mechanism working in a JavaScript-disabled environment.
|
work to keep the older form-based mechanism working in a JavaScript-disabled environment.
|
||||||
|
|
||||||
Progressive Enhancement can be a hot-button topic in web development, with lots of passionate opinions and perspectives.
|
Progressive Enhancement can be a hot-button topic in web development, with lots of passionate opinions and perspectives.
|
||||||
Like nearly all JavaScript libraries, htmx makes it possible to create applications that do not function in the absence of
|
Like nearly all JavaScript libraries, htmx makes it possible to create applications that do not function in the absence of
|
||||||
@ -826,7 +830,7 @@ experience to our web application. Even better, any email validation rules we a
|
|||||||
_automatically_ just work using this model: because we are using hypermedia as our communication mechanism there is no
|
_automatically_ just work using this model: because we are using hypermedia as our communication mechanism there is no
|
||||||
need to keep a client-side and server-side model in sync with one another.
|
need to keep a client-side and server-side model in sync with one another.
|
||||||
|
|
||||||
A great demonstration of the power of the hypermedia architecture.
|
A great demonstration of the power of the hypermedia architecture!
|
||||||
|
|
||||||
== Another Application Improvement: Paging
|
== Another Application Improvement: Paging
|
||||||
|
|
||||||
@ -838,7 +842,7 @@ all 10,000 contacts on the root page. Showing so much data can bog a browser (a
|
|||||||
adopt a concept of "`paging`" to deal with data sets this large, where only one "`page`" of a smaller number of items is
|
adopt a concept of "`paging`" to deal with data sets this large, where only one "`page`" of a smaller number of items is
|
||||||
shown, with the ability to navigate around the pages in the data set.
|
shown, with the ability to navigate around the pages in the data set.
|
||||||
|
|
||||||
Let's fix our application, so that we only show ten contacts at a time with a "`Next`" and "`Previous`" link if there are more
|
Let's fix our application so that we only show ten contacts at a time with a "`Next`" and "`Previous`" link if there are more
|
||||||
than 10 contacts in the contact database.
|
than 10 contacts in the contact database.
|
||||||
|
|
||||||
The first change we will make is to add a simple paging widget to our `index.html` template.
|
The first change we will make is to add a simple paging widget to our `index.html` template.
|
||||||
@ -904,7 +908,7 @@ knows which page to return.
|
|||||||
|
|
||||||
And, with that small change, we are done: we now have a very basic paging mechanism for our web application.
|
And, with that small change, we are done: we now have a very basic paging mechanism for our web application.
|
||||||
|
|
||||||
And, believe it or not, it is already using AJAX, thanks to our use of `hx-boost` in the application. Easy.
|
And, believe it or not, it is already using AJAX, thanks to our use of `hx-boost` in the application. Easy!
|
||||||
|
|
||||||
=== Click To Load
|
=== Click To Load
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user