Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refresh component B with s-val from component A #209

Closed
pimago opened this issue Mar 28, 2022 · 9 comments
Closed

Refresh component B with s-val from component A #209

pimago opened this issue Mar 28, 2022 · 9 comments
Labels
question Further information is requested

Comments

@pimago
Copy link

pimago commented Mar 28, 2022

Question

Hi Ben, I am trying to build a link which will load an entry into another component.
I have a list of entries wich is updated via sprig – just to give you some context.
Each list item has a link that should load the given entry into my overlay container.

This is a stripped down version of what I have. When I click the link it loads more entries from my list into the overlay component.
But it looks like my link is not passing the entryId to the entryOverlay component. Is it even possible to send a s-val from one component to another? I am sure I am just overlooking something in the docs.

{#-- main --#}
<main>
	{{ sprig('_components/entryList') }}

	{{ sprig('_components/entryOverlay', {}, {
		'id': 'entryOverlay',
	}) }}
</main>

{#-- _components/entryList --#}
{% set entries = craft.entries.section('mySeciton').offset(offset).limit(limit).all() %}

{% for entry in entries %}
	 <a sprig s-target="#entryOverlay" s-val:entry-id="{{entry.id}}">{{ entry.title }}</a>
	 {# limit and offset updated with a revealed trigger #}
{% endfor %}

{#-- _components/entryOverlay --#}
{% set entryId = entryId ?? false %}
{% set entry = craft.entries.id(entryId).one() %}

{% if entry %}
	<p>{{entry.title}}</p>
{% endif %}

So I am basically looking for button that refreshes another component with a new variable.

Additional context

I also tried a different button like this

<button onclick="htmx.trigger('#entryOverlay', 'refresh', {entryId: {{entry.id}}});">{{ entry.title }}</button>

But I it also doesn't pass the variable.

@pimago pimago added the question Further information is requested label Mar 28, 2022
@bencroker
Copy link
Collaborator

bencroker commented Mar 28, 2022

You can use a hidden input field to control the component's state.

{#-- _components/entryOverlay --#}
{% set entryId = entryId ?? '' %}

{{ hiddenInput('entryId', entryId) }}

{% if entryId %}
    {% set entry = craft.entries.id(entryId).one() %}
    {% if entry %}
	<p>{{entry.title}}</p>
    {% endif %}
{% endif %}

Which you can update via JavaScript.

<button onclick="htmx.find('#entryOverlay input[name=entryId]').value = {{ entry.id }}; htmx.trigger('#entryOverlay', 'refresh');">
    {{ entry.title }}
</button>

@pimago
Copy link
Author

pimago commented Mar 28, 2022

Perfect! Thank you Ben.

@pimago
Copy link
Author

pimago commented Mar 31, 2022

Hi, I have a follow up question. How can I use something like s-include="" on my javascript button in my entryList component? I didn't find or understand how to do it with the htmx api methods. I only need to send the entryId.

<a onclick="htmx.find('#entryOverlay input[name=entryId]').value = {{ entry.id }}; htmx.trigger('#entryOverlay', 'refresh');">
	{{ entry.title }}
</a>
{% endfor %}

Because inside my entryOverlay I am loading another entryList component with related entries. And there the link is sending all the verbb comments input values again.
Or maybe there is a way to use a sprig button to update the input field value?

@bencroker
Copy link
Collaborator

If none of the comment input field values should ever be submitted via Sprig, then adding s-include="" to the component itself should do the tick.

{{ sprig('_components/entryOverlay', {}, {
    'id': 'entryOverlay',
    's-include': '',
}) }}

@pimago
Copy link
Author

pimago commented Mar 31, 2022

Thanks. I think this also prevents the link from sending the hidden input entryId value? It doesn't seem to work.

My workaround now is that the entryOverlay is passing a variable to the second time I load the entryList. And there instead of the javascript Link I use this one.

<button sprig
	s-val:entryid="{{ entry.id }}"
	s-target="#projectOverlay"
	s-include="">
</button>

Which seems to work at this point. Don't know why though and if it's a good solution. So I am using two different Links now depending where load the component.

@bencroker
Copy link
Collaborator

Thanks. I think this also prevents the link from sending the hidden input entryId value? It doesn't seem to work.

Ah right, in that case you can include that input field only.

{{ sprig('_components/entryOverlay', {}, {
    'id': 'entryOverlay',
    's-include': 'input[name=entryId]',
}) }}

@pimago
Copy link
Author

pimago commented Apr 1, 2022

Cool, that did it. Thanks!

@pimago
Copy link
Author

pimago commented Apr 21, 2024

Hi Ben, I updated to Craft 5 and Sprig 3. I am getting a 500 error with this solution now.
Do I have to use it differently now?

URL: https://pnp22.ddev.site/index.php?p=actions/sprig-core/components/render&entryId=1427&entryId=1254&entryId=845&entryId=272&entryId=845&sprig%3Aconfig=5fb93e777a0b63120e7a0a63560cfda6dc1d68e5ddab551888f98bb49b9555b8%7B%22siteId%22%3A1%2C%22template%22%3A%22_components%5C%2FspProjectOverlay%22%2C%22variables%22%3A%7B%22parenturl%22%3A%22%5C%2F%22%2C%22parenttitle%22%3A%22Your%20feed%22%7D%7D
Status: 500
Source: Network
Address: 127.0.0.1:443
Initiator: htmx.min.js:1:40984

@bencroker
Copy link
Collaborator

It should continue to work in Sprig 3. Please create a new issue with some code I can use to reproduce locally, along with details, and I’ll take a look.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants