Fred J.
Fred J.

Reputation: 6029

get html nextSibling

This Meteor client code tries to get 2 values.
(1)The value in the this.label of <span class="radio-label">{{this.label}}</span> line.
(2)The value in {{this.result}} in the line <input type="radio" name="rbtn" value={{this.result}}>
And that needs to happen when I click on either the input or on the span elements. How can that be done? thx

Template.results.events({
  'click .twin-item': (event) => {
    event.preventDefault();
    event.stopPropagation();
    if (event.target.tagName === 'SPAN') {
      console.log(event.target.innerHTML);
    } else if (event.target.tagName === 'INPUT') {
      console.log(event.target.value);
    }
  }
});


<template name="results">
 <p id="result" data-id={{_id}}>{{{display.name}}} <br>
{{display.address}} <br>
<span id="category">{{display.result}}</span></p> <br>
  <div class="twin-group js-radioGroup" data-id={{_id}}>
    <ul class="upShift">
      {{#each display.deciders}}
        <li>
          <label class="twin-item">
            <input type="radio" name="rbtn" value={{this.result}}>
            <span class="radio-label">{{this.label}}</span>
          </label>
        </li>
      {{/each}}
    </ul>
  </div>
</template>

Upvotes: 0

Views: 88

Answers (2)

Fred J.
Fred J.

Reputation: 6029

The following worked for me. but I am hoping this is a better solution. By adding different class to the input and the span elements and play around with the event handler.

Template.results.events({
  'click .radio-label': (event) => {
    event.preventDefault();
    event.stopPropagation();
    let option = event.target.innerHTML;
    let btn = event.target.parentElement.children[0];
    let res = btn.getAttribute('value');
    btn.checked = true;
    console.log(option + ' ' + res);
  },
  'click .radio-btn': (event) => {
    let res = event.target.parentElement.children[0].getAttribute('value');
    let option = event.target.parentElement.children[1].innerHTML;
    console.log(option + ' ' + res);
  }
});
<template name="results">
  <p id="result" data-id={{_id}}>{{{display.name}}} <br>
    {{display.address}} <br>
    <span id="category">{{display.result}}</span></p>

  <div class="twin-group js-radioGroup">
    <ul class="upShift">
      {{#each display.deciders}}
        <li>
          <label class="twin-item">
            <input class="radio-btn" type="radio" name="rbtn" value={{this.result}}>
            <span class="radio-label">{{this.label}}</span>
          </label>
        </li>
      {{/each}}
    </ul>
  </div>
</template>

Upvotes: 0

Michel Floyd
Michel Floyd

Reputation: 20226

Whenever you are trying to extract something from the DOM that you originally put there in your template you are probably doing it wrong.

You can nest another template inside your {{#each}} loop then in the event of that nested template handler the value of this will be the current data context so you can do:

html:

<template name="results">
<p id="result" data-id={{_id}}>{{{display.name}}} <br>
{{display.address}} <br>
<span id="category">{{display.result}}</span></p> <br>
  <div class="twin-group js-radioGroup" data-id={{_id}}>
    <ul class="upShift">
      {{#each display.deciders}}
        {{> inner}}
      {{/each}}
    </ul>
  </div>
</template>

<template name="inner">
<li>
  <label class="twin-item">
    <input type="radio" name="rbtn" value={{result}}>
    <span class="radio-label">{{label}}</span>
  </label>
</li>
</template>

Also it can be simpler to attach an event to each control rather than trying to figure out which control the event came from:

js:

Template.inner.events({
  'click input'(event) => {
    event.stopPropagation();
    console.log(this.result);
  },
  'click span'(event) =>{
    event.stopPropagation();
    console.log(this.label);  
  }
});

Upvotes: 1

Related Questions