首页 > 解决方案 > 如何使用 jQuery 从多选输入中更改元素上的类

问题描述

我想在单个多选表单输入中更改有关所选项目的各种 div 的类?

我写的代码部分工作。当我有一个选择时,它就起作用了。一旦我在输入中选择了两个选项,它就不起作用了。

我无法修改或向 select 和 div 块代码添加参数。该代码是 WordPress 插件的一部分,为此添加额外的参数很复杂。

这是我所做的:

jQuery(document).ready(function ($) {

  $('#gd_placecategory').change(function() {
    if ($(this).val() == '220') {
      $("#stay_typecampingrv_row").addClass('ciDirShow');
      $("#stay_categoriescamping_row").addClass('ciDirShow');
      $("#stay_glampingcamping_row").addClass('ciDirShow');
    } else {
      $("#stay_typecampingrv_row").removeClass('ciDirShow');
      $("#stay_categoriescamping_row").removeClass('ciDirShow');
      $("#stay_glampingcamping_row").removeClass('ciDirShow');
    }
  });

  $('#gd_placecategory').change(function() {
    if ($(this).val() == '320') {
      $("#stay_typecampingrv_row").addClass('ciDirShow');
    } else {
      $("#stay_typecampingrv_row").removeClass('ciDirShow');
    }
  });

  $('#gd_placecategory').change(function() {
    if (['215', '221', '22', '217', '216'].includes($(this).val())){
      $("#stay_roomcomfort_row").addClass('ciDirShow');
    } else {
      $("#stay_roomcomfort_row").removeClass('ciDirShow');
    }
  });

});
#stay_roomcomfort_row,
#stay_comfortcampingrv_row,
#stay_typecampingrv_row,
#stay_categoriescamping_row,
#stay_glampingcamping_row {
  display:none
}

.ciDirShow {
  display:block!important
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
  <select id="gd_placecategory" multiple=""    field_type="multiselect">
    <option title="Apartments" value="215">Apartments</option>
    <option title="Campsites" value="220">Campsites</option>
    <option title="Guesthouses" value="221">Guesthouses</option>
    <option title="Hotels" value="22">Hotels</option>
    <option title="Houses" value="217">Houses</option>
    <option title="Resorts" value="216">Resorts</option>
    <option title="RV Parks" value="320">RV Parks</option>
  </select>
</div>
<div>Some HTML here</div>
<div id="stay_facilities_row" class="">Common content</div>
<div id="stay_roomcomfort_row" class="">Content to display when value is 215 or 221 or 22 or 217 or 216</div>
<div id="stay_comfortcampingrv_row" class="">Content to display when value is 220 or 320</div>
<div id="stay_typecampingrv_row" class="">Content to display when value is 220 or 320</div>
<div id="stay_categoriescamping_row" class="">Content to display when value is 220</div>
<div id="stay_glampingcamping_row" class="">Content to display when value is 220</div>
<div id="stay_services_row" class="">Common content</div>

任何人都可以帮助解决这个问题?非常感谢

更新了单个多选输入以便更好地理解。

标签: jquery

解决方案


我在这里的第一个想法是将值与行为分开并放入一些数据属性以指向“对”元素。我使用了一个 id 选择器,但它可能是一个类或更复杂的类。要做到这一点:

  1. 将数据属性添加到“配对”元素的选项中
  2. 获取所有“选定”选项,然后切换数据集值
  3. 使用 CSS 中的数据集值来添加颜色,但它可能是“显示”或其他一些 - 所以现在我们只需要切换这些值,而不是显示/隐藏类
  4. 在开始时触发了选择的更改 - 请注意我将 Rabbit 设置为选中,以便它从 CSS 中获取石灰色

我将“对”放在标记中,data-pair但您也可以拥有一组名称/值对(字典)

更新了第二个示例,该示例使用硬编码值与另一个示例基本相同 - 不花哨但可能可以从中构建。

$('#gd_placecategory').on('change', function() {
  //toggle them all off
  $('.my-things').find('.ciDirShow')
    .each(function(index, element) {
      element.dataset.toggle = 'off';
    });
  let pairs = [];
  let opt = $(this) // the option(s) selected
  let values = opt.val();
  let selected = $(this).find('option').filter(":selected"); //selected options
  selected.map(function(index, domElement) {
    pairs.push($(this).data("pair"));
  });
  pairs.forEach(function callbackFn(item, index, array) {
    item.forEach(function dbFn(ar, index, array) {
      $(ar)[0].dataset.toggle = 'on';
    });
  });
}).trigger('change');
[data-toggle="off"] {
  color: blue;
}

[data-toggle="on"] {
  color: lime;
}

.my-things {
  padding: 1rem;
}

.my-things>div {
  border: 1px solid #808080;
  margin: 1rem;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>I need HTML here</div>
<label for="gd_placecategory">Choose your pets Place:</label>
<select id="gd_placecategory" multiple="multiple">
  <option value="220" data-pair='["#stay_typecampingrv_row","#stay_categoriescamping_row","#stay_glampingcamping_row"]'>Dog</option>
  <option value="320" data-pair='["#stay_typecampingrv_row"]'>Cat</option>
  <option value="215" data-pair='["#stay_roomcomfort_row"]' selected>Rabbit</option>
  <option value="221" data-pair='["#stay_roomcomfort_row"]'>Parrot</option>
  <option value="22" data-pair='["#stay_roomcomfort_row"]'>Goat</option>
  <option value="217" data-pair='["#stay_roomcomfort_row"]'>Sheep</option>
  <option value="216" data-pair='["#stay_roomcomfort_row"]'>Whild Boar</option>
</select>
<div>
  <button id="check" type="button">Get Selected Values</button>
</div>
<div class="my-things">
  <div class="ciDirShow" id="stay_typecampingrv_row" data-choices="['220','320']">Howdy Campers</div>
  <div class="ciDirShow" id="stay_categoriescamping_row" data-choices="['220','320']">Howdy Categories</div>
  <div class="ciDirShow" id="stay_glampingcamping_row" data-choices="['220','320']">Howdy Glampers</div>
  <div class="ciDirShow" id="stay_roomcomfort_row" data-choices="['215','221' , '22', '217' , '216']">Howdy Be Comfortable</div>
</div>

没有markuo变化:

/* jshint esversion: 6 */
//create app or use one if exists
var myApp = myApp || {};
// add alerts data
myApp.data = {
  wrapClass: 'my-things',
  wrapper: {},
  targetClass: 'ciDirShow',
  targets: {},
  pairs: [{
    id: "stay_facilities_row",
    selector: "#stay_facilities_row",
    target: [],
    showAlways: true
  }, {
    id: "stay_categoriescamping_row",
    selector: "#stay_categoriescamping_row",
    target: ["220"]
  }, {
    id: "stay_comfortcampingrv_row",
    selector: "#stay_comfortcampingrv_row",
    target: ["220", "320"]
  }, {
    id: "stay_glampingcamping_row",
    selector: "#stay_glampingcamping_row",
    target: ["220"]
  }, {
    id: "stay_typecampingrv_row",
    selector: "#stay_typecampingrv_row",
    target: ["220", "320"]
  }, {
    id: "stay_roomcomfort_row",
    selector: "#stay_roomcomfort_row",
    target: ['215', '221', '22', '217', '216']
  }, {
    id: "get_alongwithbears",
    selector: "#get_alongwithbears",
    target: ["9876"]
  }, {
    id: "likes_chickens",
    selector: "#likes_chickens",
    target: ["1111"]
  }, {
    id: "stay_services_row",
    selector: "#stay_services_row",
    target: [],
    showAlways: true
  }]
};
myApp.func = {
  setToggle: function(me, val) {
    me.dataset.toggle = val;
  },
  hideAll: function(event) {
    $(this)
      .each(function(index, element) {
        myApp.func.setToggle(element, "off");
      });
  },
  showAll: function(event) {
    $(this)
      .each(function(index, element) {
        myApp.func.setToggle(element, "on");
      });
  },
  showDefaults: function() {
    let pairs = myApp.data.pairs;
    myApp.data.targets.trigger('show-all');
    let alwaysThese = pairs.filter(function(item) {
      return item.showAlways;
    });

    alwaysThese.forEach(function(el) {
      $(el.selector).trigger('showAll');
    });

    let notAlways = pairs.filter(function(item) {
      return alwaysThese.indexOf(item.id) === -1 && !!$(item.selector).length;
    });
    let all = myApp.data.targets.filter(function(index, el) {
      let pos = alwaysThese.map(function(item) {
        return item.id;
      }).indexOf(el.id);
      return pos === -1;
    });
    all.trigger('hide-all');
  },
  init: function() {
    let pairs = myApp.data.pairs;
    // this is a bit ugly/fragile but no classes on the elements after 
    // the first to we wrap them and add a class
    myApp.data.targets = $("div").not($('#gd_placecategory').parent('div'))
      .addClass(myApp.data.targetClass);
    myApp.data.targets.wrapAll('<div class="' + myApp.data.wrapClass + '"/>');
    myApp.data.wrapper = $('.' + myApp.data.wrapClass);
    // setup event handlers
    myApp.data.targets.on('hide-all', myApp.func.hideAll);
    myApp.data.targets.on('show-all', myApp.func.showAll);
    myApp.data.targets.data('pair', []);
    myApp.func.showDefaults();
    myApp.data.pairs.forEach(function(pair, index, array) {
      let t = $(pair.selector);
      let tEl = t.get(0);
      t.data("pair", pair);
    });
    $('#gd_placecategory').on('change', myApp.func.changeHandler); //.trigger('change');

  },
  changeHandler: function(event) {
    myApp.func.showDefaults();
    let myPairs = [];
    let sel = $(this); // the  select
    let values = sel.val();
    //selected options
    let selected = sel.find('option').filter(":selected");
    let x = selected.map(function(index, opt) {
      myPairs.push($(opt).val());
    });
    //console.log('pairs:', myPairs, 'Count:', myPairs.length);
    if (myPairs.length > 0) {
      myPairs.forEach(function(pair, index, array) {
        //console.log("pair:", pair);
        if (!!pair) {
          myApp.data.pairs.forEach(function(ar, index, array) {
            //console.log('ar:', ar);
            if (ar.target.indexOf(pair) != -1)
              $(ar.selector).trigger('show-all');
          });
        }
      });
    }
  }
};

(function($) {
  myApp.func.init();
})(jQuery);
[data-toggle="off"] {
  color: blue;
}

[data-toggle="on"] {
  color: lime;
}

.my-things {
  margin: 0.5rem;
  border: solid 1px orange;
}

.cheese {
  font-weight: bold;
}

.ciDirShow {
  border: solid #aaaaff 1px;
  margin: 1rem;
  padding: 0.5rem;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
  <select id="gd_placecategory" multiple="" field_type="multiselect">
    <option title="Apartments" value="215">Apartments</option>
    <option title="Campsites" value="220">Campsites</option>
    <option title="Guesthouses" value="221">Guesthouses</option>
    <option title="Hotels" value="22">Hotels</option>
    <option title="Houses" value="217">Houses</option>
    <option title="Resorts" value="216">Resorts</option>
    <option title="RV Parks" value="320">RV Parks</option>
  </select>
</div>
<div id="stay_facilities_row" class="">Common content</div>
<div id="stay_roomcomfort_row" class="">Content to display when value is 215 or 221 or 22 or 217 or 216</div>
<div id="stay_comfortcampingrv_row" class="">Content to display when value is 220 or 320</div>
<div id="stay_typecampingrv_row" class="">Content to display when value is 220 or 320</div>
<div id="stay_categoriescamping_row" class="">Content to display when value is 220</div>
<div id="stay_glampingcamping_row" class="">Content to display when value is 220</div>
<div id="stay_services_row" class="">Common content</div>


推荐阅读