简体   繁体   中英

Select a specific Target from a Stimulus Controller

I am looking for a simple and elegant way (a Stimulus-way) to select a specific element from the targets elements form my Stimulus controller.

For example: I have a list of 4 links and 4 paragraphs (both inside the scope of the controller). When clicking the link, I want something to happen (eg adding a class) with the paragraph, which has the same data-id as the link. The paragraphs have been defined as Stimulus-Targets.

Please see this JS-Fiddle for a code-example: https://jsfiddle.net/nbLvafxy/

Stimulus is giving me the following accesses to the target elements:

  • event.currentTarget -> gives the clicked element (the link) - where its possible to access the dataset and therefore the data-id of the clicked element ( event.currentTarget.dataset.linkId )
  • this.elementTarget -> returns the first element target (paragraph) - but I cannot select a specific one.
  • this.elementTargets -> returns an array of target-elements (paragraphs) - but also here, I cannot filter for a specific one.

For the latest one ( this.elementTargets ), I would hope, there is a JS method to somehow select a specific element from this array of HTML elements.

I want to avoid document.querySelector(...) as the element with the data-id could be present on the page multiple times (see second list in the JS-Fiddle). Therefore, a solution within the "scope" of the Stimulus controller would be the best solution.

I though this would work, but it doesn't

I have used multiple controllers on the same page before and it worked, but I'll agree with the one of the commenter that the naming convention seems to screw things up. The targets are selected on both sides, the add class works, but it seem to reload or reconnect the page.

OH!! It's reconnecting because of the # href! Change your <a tags to button and remove the href and it works.

Sorry

The index thing would work, but elements and links are not in same order.

So, your html

<div class="flex bg-white">
  <div class="half" data-controller="effect" >
    <p><a href="#" data-action="effect#highlight" data-effect-target="link" data-link-id="1">Link 1</a></p>
    <p><a href="#" data-action="effect#highlight" data-effect-target="link" data-link-id="2">Link 2</a></p>
    <p><a href="#" data-action="effect#highlight" data-effect-target="link" data-link-id="3">Link 3</a></p>
    <p><a href="#" data-action="effect#highlight" data-effect-target="link" data-link-id="4">Link 4</a></p>
    <p data-effect-target="element" data-element-id="4">Element 4</p>
    <p data-effect-target="element" data-element-id="3">Element 3</p>
    <p data-effect-target="element" data-element-id="1">Element 1</p>
    <p data-effect-target="element" data-element-id="2">Element 2</p>
  </div>

  <div class="half" data-controller="effect">
    <p><a href="#" data-action="effect#highlight" data-effect-target="link" data-link-id="3">Link 3</a></p>
    <p><a href="#" data-action="effect#highlight" data-effect-target="link" data-link-id="4">Link 4</a></p>
    <p><a href="#" data-action="effect#highlight" data-effect-target="link" data-link-id="5">Link 5</a></p>
    <p><a href="#" data-action="effect#highlight" data-effect-target="link" data-link-id="6">Link 6</a></p>
    <p data-effect-target="element" data-element-id="4">Element 4</p>
    <p data-effect-target="element" data-element-id="5">Element 5</p>
    <p data-effect-target="element" data-element-id="6">Element 6</p>
    <p data-effect-target="element" data-element-id="3">Element 3</p>
  </div>
</div>

Stimulus controller

import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  static targets = ["link", 'element']

  connect(){
  }

  highlight() {
    var lnk = event.target.dataset.linkId
    var elems = this.elementTargets
    for (var i = elems.length - 1; i >= 0; i--) {
      if (elems[i].dataset.elementId == lnk){
        elems[i].classList.add('text-blue-700')
        console.log(elems[i])
        break
      }
    }
  }

For some reason the class added to element is in the html, but not change?(in Safari, but ok in firefox) anyway no DOM id, just targets.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM