Closed lennonpuype closed 8 months ago
If you use the htmx API then this might be easier to write. See https://putyourlightson.com/articles/htmx-has-a-javascript-api-btw
<button class="button1" hx-on:click="htmx.trigger('#sprig-popup', 'refresh')">
The above will cause the Sprig component to re-render. If you want a specific form to submit, then you should be able to do something like this.
<button class="button1" hx-on:click="htmx.find('#form1').submit()">
If that form has been Sprigified, then it will do its thing (otherwise it will submit as normal).
<form id="form1" sprig s-method="post" s-action="some/controller/action">
Hi Ben,
Thanks for the fast reply.
I tried some things with these inline hx-on attributes, but I don't really get what I want.
I kinda found a solution for what I want to do, but I don't really think this is THE way to go.
In Javascript when triggering the component like above in this issue, I append some info to the parameters of the URL.
const $sprigPopup = document.querySelector('#sprig-popup');
if($sprigPopup) {
$sprigPopup.dispatchEvent(new Event('refresh'));
const urlParams = new URLSearchParams(window.location.search);
urlParams.set('hx-trigger-id', popupType);
const newUrl = `${window.location.pathname}?${urlParams.toString()}`;
// Push the new URL to the browser's history
window.history.pushState({ path: newUrl }, '', newUrl);
htmx.trigger('#sprig-popup', 'refresh');
}
After doing that when the component has been refreshed, I do following to get the parameter like this:
{% set popupReferer = craft.app.request.getReferrer() ?? null %}
{% set parts = popupReferer|split('?') %}
{% set hxTriggerId = '' %}
{# SETS TRIGGER ID #}
{% if parts|length > 1 %}
{% set params = parts[1]|split('&') %}
{% if params %}
{% for param in params %}
{% set keyValue = param|split('=') %}
{% if keyValue[0] == 'hx-trigger-id' %}
{% set hxTriggerId = keyValue[1] %}
{% endif %}
{% endfor %}
{% endif %}
{% endif %}
As you see this is a tricky way and probably not the way to go. Do you have any suggestions so I am able to get the clicked trigger ID inside the component in a better way then I do now?
Can you explain to me in clear terms, with a simple example, what it is you’re trying to do?
Sure, so we have a site that is using barba.js for smooth page transitions. All pages can have a popup that is activated on button click. This popup can be a slideshow or a form, depending on what button you click. There are also a lot of possible forms. Because of barba js, we are running into some limitations with the current setup of predefining every possible slideshow or form we update and populate with the needed fields after changing the page. It just should get optimised.
That is where Sprig comes in handy to load server side data as if it is a page refresh and everything would work more convenient than it is now.
There are happening some frontend things with gsap to animate the opening of that popup as you see in the screenrecording below. I want the content of that popup to update after the popup has been activated when a button with certain id has been clicked. This ID can be slideshow, form-1, form-2...
https://github.com/putyourlightson/craft-sprig/assets/30866096/cd0563c9-4922-4eda-9118-c338f5694b95
As you see in the screenrecording, when clicking on the "Sprig trigger" button, inside that element that is opening. The sprig component should update to what button the user clicked on. What you see here is with the code I added above in my last message. You see it works, but it might just not be the best way of doing so.
So maybe you see a more convenient way of updating the ID, rather then how I now worked using the params in the URL. I tried to push a header with the sprig request, but didn't succeed in that.
I dont know if I am looking to far away from an easy solution? I looked into the htmx docs, but cant really find what I am searching for. I'm also pretty new to htmx since I only used sprig for simple filters until now
Thanks for the explanation. Could sprig.trigger
be what are looking for?
Returns the ID of the element that triggered the request.
I fixed it in another way.
The way you said by using sprig.trigger
didn't really work because the trigger was the sprig-component since the component got refreshed using the hx:on=...
there was like no way to get the ID of the clicked button as the trigger inside the sprig component that got refreshed.
That being said, how I did it now was the same way as above
...
const $sprigPopup = document.querySelector('#sprig-popup'); if($sprigPopup) { $sprigPopup.dispatchEvent(new Event('refresh')); const urlParams = new URLSearchParams(window.location.search); urlParams.set('hx-trigger-id', popupType); const newUrl = `${window.location.pathname}?${urlParams.toString()}`; // Push the new URL to the browser's history window.history.pushState({ path: newUrl }, '', newUrl); htmx.trigger('#sprig-popup', 'refresh'); }
...
I changed the working of things up by using a cookie since this is more user friendly, then inside the sprig component I get the cookie that was set in javascript. This feels more convenient than getting a url parameter.
Glad to here you found a solution you’re happy with! FYI you can also use a hidden input to store and change the state within a component.
In the Sprig component:
<input type="hidden" id="popupType" name="popupType" value="{{ popupType ?? '' }}>
Changing the value before refreshing:
<button class="button1" hx-on:click="htmx.find('#popupType').value = 'button1'; htmx.trigger('#sprig-popup', 'refresh')">
Then popupType
will be available in the Sprig component as a variable:
{{ popupType ?? '' }}
See https://putyourlightson.com/plugins/sprig#component-state
Oh thanks, this is exactly what I needed. It is a little difficult to find this when being new to htmx.
Now I understand how to do these kind of things, so thanks for the help!
Yeah I get that. Check out the Sprig trainings at https://putyourlightson.com/sprig/training
Hi,
I am kinda stuck on this thing using HTMX since I think this is the only way to go to get what I want, using Sprig. I will explain with a small example on what I want and what I might miss
There are 2 buttons on the screen. Both buttons are outside of a sprig component, since the sprig component that should update is something globally and the buttons are randomly on the webpage, I mean they can be inside text or whatever, so not inside the sprig component.
When clicking button 1, the sprig component should load FORM 1. When clicking button 2, it should obviously load FORM 2. Just tried something basic to see if the Trigger works, and after clicking, the sprig component actually updates. So that gives me the idea that refreshing the component using HTMX is the way to go, just as I read. I tried this by dumping the current time, and after clicking one of the buttons it making the sprig component refresh that time using the following codes:
The component is available in the DOM at:
body > sprigcomponent
Following triggers are available in the DOM at:
body > main > .text > .button1
orbody > main > nav > .button2
The JS:
My question: As you see I am just missing how I can update a form (or whatever content) based on the clicked trigger. fyi, I call a form on the website (not using sprig) as following:
{{ craft.formie.renderForm(formHandle) }}
Could you assist me in the right direction to be able to update that formhandle based on what I clicked?