【问题标题】:How to change the class on an element using jQuery from a multiple select input如何从多选输入中使用 jQuery 更改元素上的类
【发布时间】:2021-07-11 14:55:08
【问题描述】:

我想在单个多选表单输入中更改有关所选项目的各种 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>

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

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

【问题讨论】:

  • 当您从下拉列表中选择时,所有处理程序都在运行。每一个都会覆盖其他人所做的更改。
  • 如果您有一个多选,则该值是所有选定对象的数组。为什么要与字符串进行比较?
  • 请添加您的 HTML 并解释每个选项应该发生什么。
  • 请添加您的 HTML 并解释每个选项会发生什么。将此信息放在问题中,而不是评论中。
  • 我将添加 HTML。基本上,我想这样做:如果选择项目 X 然后显示 X DIV,它是另一个项目 Y 选择显示 Y Div,如果选择 X 和 Y 然后显示 X 和 Y div。当然,如果 X 未被选中,隐藏 X div。

标签: jquery


【解决方案1】:

我在这里的第一个想法是将值与行为分开并放入一些数据属性以指向“对”元素。我使用了一个 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>

【讨论】:

  • 感谢您的回答。它看起来像这样更简单,但我无法修改选择输入添加数据对的代码(除非使用 jQuery 添加它),对于 div 块也是如此,我无法添加数据选择。该代码是插件的一部分。
  • 标记中的所有内容也可以从脚本中注入。如果我有时间,我将利用您在发布后添加的标记并添加第二个示例。
  • 感谢您的更新。我正在尝试,但这一行有一个错误:item.forEach(function dbFn(ar, index, array) (未捕获的类型错误:无法读取未定义的属性 'forEach')。我不知道如何解决它。你能帮我吗?谢谢
  • @Stuart66 进行了修改以使用最初无法注入的秒数
【解决方案2】:

到目前为止,我在这里。它在更新多选时运行良好,但当我选择 2 个或更多类别时它不起作用。

更新:我找到了适用于任何情况的解决方案。也许还有更简单的?

jQuery(document).ready(function ($) {
  $('#gd_placecategory').change(function() {
    var selected = $('#gd_placecategory').val();
    
    $("#stay_roomcomfort_row").removeClass('ciDirShow');
    $("#stay_typecampingrv_row").removeClass('ciDirShow');
    $("#stay_categoriescamping_row").removeClass('ciDirShow');
    $("#stay_glampingcamping_row").removeClass('ciDirShow');
    $("#stay_comfortcampingrv_row").removeClass('ciDirShow');

    if (($.inArray('215', selected) != -1) || ($.inArray('22', selected) != -1) || ($.inArray('221', selected) != -1) || ($.inArray('217', selected) != -1) || ($.inArray('216', selected) != -1)) {
        $("#stay_roomcomfort_row").addClass('ciDirShow');
    }
    if ($.inArray('220', selected) != -1) {
        $("#stay_typecampingrv_row").addClass('ciDirShow');
        $("#stay_categoriescamping_row").addClass('ciDirShow');
        $("#stay_comfortcampingrv_row").addClass('ciDirShow');
        $("#stay_glampingcamping_row").addClass('ciDirShow');
    }
    if ($.inArray('320', selected) != -1) {
        $("#stay_typecampingrv_row").addClass('ciDirShow');
        $("#stay_comfortcampingrv_row").addClass('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>

你怎么看?

【讨论】:

  • selected 是一个数组,而不是单个数字。所以selected == 215 应该是$.inArray(215, selected) != -1
  • 现在我看到您稍后会检查。为什么要进行这两种测试?
  • @Barmar 我用一种单一类型的测试更新了所有内容并简化了它。现在它工作得很好而且很简单(我认为)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-09
  • 1970-01-01
  • 2021-12-05
  • 1970-01-01
  • 2012-01-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多