I'm making my first personal project on Ruby on Rails (as well as my first post on Stack Overflow !).
I would like to implement a "productivity" page with dedicated keyboard shortcuts for Mac & Ubuntu users. Cf : Project image
The goal would be to click on the Mac / Linux buttons and display a shortcut version for each OS. I've used Stimulus JS to add a data controller/target/action on the button, when clicked it add / remove a class active or disable which hides the inactive card.
My issue is that the buttons of the second, third, etc. "article" are always linked to the first on. So when clicked on, it still changes the display of the first article instead of the second one.
I don't know if there is a way to compartmentalize each button with its related article with Stimulus ?
My code looks like this :
View :
<div ">
<% @productivity.article.each do |article| %>
<div >
<div >
<h3><%= article.title%></h3>
<p><%= article.description%></p>
<% if article.category == "code" %>
<div >
<div >
<button data-action="click->os-buttons#showLinux">Linux</button>
<button data-action="click->os-buttons#showMac">Mac</button>
</div>
<div >
<div data-os-buttons-target="linux">
<p>Test Linux</p>
</div>
<div data-os-buttons-target="mac">
<p>Test Mac</p>
</div>
</div>
</div>
<% end %>
</div>
</div>
<% end %>
</div>
JS Controller :
import { Controller } from "@hotwired/stimulus"
// Connects to data-controller="os-buttons"
export default class extends Controller {
static targets = ["linux", "mac"]
connect() {
}
showMac() {
this.linuxTarget.classList.remove("active")
this.linuxTarget.classList.add("disable")
this.macTarget.classList.remove("disable")
this.macTarget.classList.add("active")
}
showLinux() {
this.macTarget.classList.remove("active")
this.macTarget.classList.add("disable")
this.linuxTarget.classList.remove("disable")
this.linuxTarget.classList.add("active")
}
}
CodePudding user response:
Where is your data-controller-os-buttons
tag? You seem to have multiple targets with same target name, so a click on a button will will probably only change the first target. Put the controller on each set of buttons.
<div data-controller="os-buttons">
That should only take action on the set of buttons
If your controller is before the code you displayed, you have multiple targets (array) and need to figure out which target was clicked by index. Doable, but the multiple controllers should work.