Reputation: 107
Very simple landing page, thought it would be a good place to start playing with HTMX. The objective is really simple:
Landing page with a query string in the URL. onLoad it fires a request to server, sending the params from the query string along. Server does its thing and sends back a success or error HTML snippet.
I do not need a button or form, all the info I need comes from the queryString. Users get redirected to this page from another app.
Question 1: How can I get the searchParms into the hx-get
?
I must be missing something but I couldn't find any other way than using some JS.
HTMX:
<div
hx-get="https://jsonplaceholder.typicode.com/users"
hx-vals="js:{id: id, comment: comment}"
hx-trigger="load"
hx-target="#result"
></div>
<div id="result" class="m-8 p-8 bg-slate-200">Loading…</div>
JS:
function getParams() {
// const urlParams = new URLSearchParams(window.location.search);
const urlParams = new URLSearchParams('id=4&comment=25');
const id = urlParams.get('id');
const comment = urlParams.get('comment');
return { id: id, comment: comment };
}
const { id, comment } = getParams();
Sample:
https://stackblitz.com/edit/stackblitz-starters-9z2kgg?file=index.html
Question 2: I would have thought the entire idea behind HTMX was that for the very largest part I don't need to write the JS. Or is this a case where I would look at Hyperscript?
Question 3: hx-trigger="load"
on a div looks odd to me, surely that's not exactly how it's thought to be done?
In production I would of course do the entire parsing of the queryString and writing the HTML response in the backend - but for that I need to get the params from the queryString back there first. What am I missing?
Upvotes: 2
Views: 3922
Reputation: 150
If you have access to the backend and can use hx-post, you can send what you need like this:
<button id="btnModal" type="button" hx-post="/api/htmx/test/update/modal" hx-vals='js:{blogId: getblogId()}' hx-target="body" hx-swap="beforeend" style="visibility:hidden;" >Open a Modal</button>
Where getblogId() is a vanilla javascript function to get the id to send, however you may need to do that.
If you have to use hx-get, it will append the name and value of the sending element to the url by default. It's a little hacky, but I made a test page to send a url parameter to a C# WebAPI on page load:
// http://localhost:53455/admin/apitest/fromurl.html?param=1234654
<button id="btnModal" name="modalm" type="button" hx-get="/api/htmx/test/update/modal2/" hx-target="body" hx-swap="beforeend" style="visibility:hidden;">Open a Modal</button>
<script>
window.addEventListener("load", function () {
openModal();
});
function openModal() {
var modal = document.getElementById("btnModal");
modal.value = getParams();
modal.click();
}
function getParams() {
const urlParams = new URLSearchParams(window.location.search);
const id = urlParams.get('param');
return id;
}
</script>
That's just using a hidden button and vanilla javascript to change the button's value and programmatically clicking it on page load.
Using that url and code, my request on the backend was:
{Method: GET, RequestUri: 'http://localhost:53455/api/htmx/test/update/modal2/?modalm=1234654', Version: 1.1,
I know you said you don't need a button, but this could be adapted to other controls. I have some similar code working well using one hidden button and javascript, and other events just "click" this button and send the id to the backend.
Upvotes: 0
Reputation: 107
After digging into this I would like to present a more elegant solution:
HTMX adds additional headers to HTTP request headers. You can inspect these and tailor your response. In particular the HX-Current-URL
is of interest here.
If you don't serve from or have access to your web server directly and interact with and/or have access to an endpoint you can read the request url from this additional header HTMX appends:
const requestUrl = request.headers.get("HX-Current-URL")!;
And you can then extract the query string, in this example id
:
const postId = new URL(requestUrl).searchParams.get("id");
And then append the id
to your fetch call, e.g.:
const res = await fetch(
`https://jsonplaceholder.typicode.com/posts/${postId}`
);
This way on page load you can feed the query string variables from your current URL into a fetch call to any API.
<div hx-get="/api/getPost" hx-trigger="load" hx-target="#result"></div>
<div id="result" class="m-8 p-8 bg-slate-200">Loading…</div>
Upvotes: 1