hey, need some help toggling specific items in a list.
I have a page which lists a number of products, and each product has many variants. when the mouse clicks on variants
under a product I won’t to only show the variants of the product that is clicked. this is a gif of the behaviour currently : https://share.getcloudapp.com/KouBPEqY
it always shows only the first products variants.
currently my code is like this
<tr>
<td>
<%= product.title %>
<button data-action="click->toggle#toggle">Variants</button>
</td>
<td>
<%= render partial: "image", collection: product.images %>
</td>
</tr>
<tr class="hidden" data-target="toggle.field">
<td></td>
<td>
<%= render partial: "variant", collection: product.variants %>
</td>
</tr>
and the stimulus controller
export default class extends Controller {
static targets = ['field']
toggle() {
this.fieldTarget.classList.toggle('hidden')
}
}
just wondering how I should fix this so that only a products associate variants are shown when I click on them.
I’m thinking I should be passing the id
of the product with something like data-toggle-product_id="<%= (product.id) %>"
- but am a little stuck on what to do after…
please let me know if you have any suggestions…
thank you!
Arjun
Hey @arjunrajkumar!
So generally speaking, you’ll want to use one controller instance for each product rather than one controller instance that surrounds all products. This will necessitate reworking your HTML so that controller can be specified on a tag that encapsulates both the button and the hidden area with the variants. However, I’d say this would be the preferred approach - it keeps things very simple and can allow you to reuse the ToggleController
elsewhere, as well.
I have a similar controller in the current app I’m working on that is used in a few very different ways, because the flexibility of simply turning a class on and off can be very powerful.
To make the ToggleController a bit more reusable, allow the class that you’ll be toggling (in this case “hidden”) to be passed in as a data attribute.
Here’s an example from my ToggleController
:
export default class extends Controller {
static targets = [ 'toggle' ]
initialize() {
this.classes = []
if(this.data.has('classes')) {
this.classes = this.data.get('classes').split(' ')
}
}
toggle() {
this.toggleTargets.forEach((target) => {
this.classes.forEach(c => target.classList.toggle(c))
})
}
}
This allows me to toggle a different class each time I use it, it allows multiple classes to be toggled (for instance, if you’re using a CSS framework and want to toggle your own “hidden” class but also toggle one of the framework classes on and off, allows multiple targets to be toggled.
Hope this helps!
1 Like
hey @welearnednothing, thanks
I’ll try redoing it by having a controller instance for each product
I like the way you’ve set up the ToggleController … lots to explore.