jQuery "contains word" selector does not work as expected

2

I'm trying to use jQuery's contains word selector to hide / show some elements dynamically on my page, however the selector is not working as expected. I'm using the 3.1.1 version of jQuery.

Notice by% w_that the code considers only the last value of the attribute when selected, so in cases B and C there are the impression that the selection worked .. however the A / B and A / C options should be visible also when A is selected again.

Anyone have any idea why? Is it a bug? Or is it really supposed to work? (not what the documentation implies).

Thank you in advance!

var options = {
  A: $('*[data-visibleOn~="A"]'),
  B: $('*[data-visibleOn~="B"]'),
  C: $('*[data-visibleOn~="C"]'),
}


$("#opt").on('change', function(evt) {
	var selected = $(this).val();
  
  for(var key in options) {
  	if(options.hasOwnProperty(key)) {
    	if(key == selected) {
      	options[key].show();
      } else {
      	options[key].hide();
      }
    }
  }
})
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script><selectname="option" id="opt">
  <option value="A">A</option>
  <option value="B">B</option>
  <option value="C">C</option>
</select>



<div data-visibleOn="A">A</div>
<div data-visibleOn="A B">A ou B</div>
<div data-visibleOn="B">B</div>
<div data-visibleOn="A C">A ou C</div>
<div data-visibleOn="C">C</div>
    
asked by anonymous 09.11.2018 / 20:26

2 answers

4

One way for you to implement this is to disappear with all items before showing them:

$(function() {
  var options = {
    A: $('[data-visibleOn~="A"]'),
    B: $('[data-visibleOn~="B"]'),
    C: $('[data-visibleOn~="C"]')
  };

  $("#opt").on("change", function(evt) {
      $('[data-visibleOn]').hide();    
      var selected = $(this).val();

      options[selected].show();

   }).trigger("change");
});

The problem is that you make a .hide() on items that contain "A", for example, but are in the other sets.

DEMO

    
09.11.2018 / 20:49
1

Using the $.prop() method you can pass a function that will be executed for each element.

In this role you can use the $.is() method to test whether the element matches the selector passed to then change any property that is required.

In the example below I used the global attribute hidden for this.

let $data = $("[data-visibleOn]");

$("#opt").on('change', function(evt) {
    let value = this.value;
    
    $data.prop('hidden', function() {
      return !$(this).is('[data-visibleOn~="${value}"]');
    });
})
[hidden] {
  display: none;
}
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script><selectname="option" id="opt">
  <option value="A">A</option>
  <option value="B">B</option>
  <option value="C">C</option>
</select>

<div data-visibleOn="A">A</div>
<div data-visibleOn="A B">A ou B</div>
<div data-visibleOn="B">B</div>
<div data-visibleOn="A C">A ou C</div>
<div data-visibleOn="C">C</div>
    
09.11.2018 / 21:05