-1

I have a fairly straight-forward class toggle in jQuery. However I can't for the life of me figure out why it's not functioning as expected.

When clicking anywhere on the label, the class of the <p> should toggle. It works as expected if you click the checkbox. However, no toggle takes place if you click anywhere else

$('.xtrag p').on('click', function() {
  $(this).toggleClass('row9');
});
.xtrag {
  margin: 40px;
}
p {
  margin: 10px 0;
}
.row0 {
  background: #eee;
  padding: 4px 8px;
}
.row9 {
  background: #ffd;
}
.rt {
  float: right;
}
label {
  display: inline-block;
  width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="xtrag">
  <p class="row0">
    <label for="xg1">
      <span class="rt">
            <input type="checkbox" name="extrag[]" value="1" id="xg1" />
          </span>
      Item 1
    </label>
  </p>
  <p class="row0">
    <label for="xg2">
      <span class="rt">
            <input type="checkbox" name="extrag[]" value="2" id="xg2" />
          </span>
      Item 2
    </label>
  </p>
  <p class="row0">
    <label for="xg3">
      <span class="rt">
            <input type="checkbox" name="extrag[]" value="3" id="xg3" />
          </span>
      Item 1
    </label>
  </p>
</div>

What am I missing?

How can I toggle the class of the <p> when the label is clicked?

I've tried targeting the <label> and then using .parent() which doesn't change any of the behavior.

mplungjan
  • 169,008
  • 28
  • 173
  • 236
Scott
  • 21,475
  • 8
  • 43
  • 55

2 Answers2

1

It's because your input bubbles up click event and you get two event calls instead of one.

One way it would be to stop bubbling from input, other - check event target:

$('.xtrag p').on('click', function(e) {
  if (typeof $(e.target).attr('type') !== 'undefined') {
    $(this).toggleClass('row9');
  }
});
.xtrag {
  margin: 40px;
}
p {
  margin: 10px 0;
}
.row0 {
  background: #eee;
  padding: 4px 8px;
}
.row9 {
  background: #ffd;
}
.rt {
  float: right;
}
label {
  display: inline-block;
  width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="xtrag">
  <p class="row0">
    <label for="xg1">
      <span class="rt">
            <input type="checkbox" name="extrag[]" value="1" id="xg1" />
          </span>
      Item 1
    </label>
  </p>
  <p class="row0">
    <label for="xg2">
      <span class="rt">
            <input type="checkbox" name="extrag[]" value="2" id="xg2" />
          </span>
      Item 2
    </label>
  </p>
  <p class="row0">
    <label for="xg3">
      <span class="rt">
            <input type="checkbox" name="extrag[]" value="3" id="xg3" />
          </span>
      Item 1
    </label>
  </p>
</div>
Justinas
  • 41,402
  • 5
  • 66
  • 96
  • Not sure who down voted this. It solves the issue. Thank you. – Scott Jan 28 '17 at 17:43
  • Testing the existence of a type on the target is a bit clumsy in my eyes. Why not just toggle when the checkbox is, as I show in my answer? – mplungjan Jan 28 '17 at 17:46
0

Test the change of the checkbox instead. The label triggered another click

$('.xtrag input').on('change',  function() {
  $(this).closest("p").toggleClass('row9');
});
.xtrag {
  margin: 40px;
}
p {
  margin: 10px 0;
}
.row0 {
  background: #eee;
  padding: 4px 8px;
}
.row9 {
  background: #ffd;
}
.rt {
  float: right;
}
label {
  display: inline-block; 
  width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="xtrag">
  <p class="row0">
    <label for="xg1">
      <span class="rt">
            <input type="checkbox" name="extrag[]" value="1" id="xg1" />
          </span>
      Item 1
    </label>
  </p>
  <p class="row0">
    <label for="xg2">
      <span class="rt">
            <input type="checkbox" name="extrag[]" value="2" id="xg2" />
          </span>
      Item 2
    </label>
  </p>
  <p class="row0">
    <label for="xg3">
      <span class="rt">
            <input type="checkbox" name="extrag[]" value="3" id="xg3" />
          </span>
      Item 1
    </label>
  </p>
</div>
mplungjan
  • 169,008
  • 28
  • 173
  • 236
  • 1
    Yeah sorry. I was testing both solutions..... and creating typos :) It's set now :) Thanks. – Scott Jan 28 '17 at 17:51