【问题标题】:JQuery Show/Hide UL children and unselect other parents checkboxJQuery 显示/隐藏 UL 子项并取消选择其他父项复选框
【发布时间】:2019-01-24 13:56:39
【问题描述】:

我会尽力描述我的问题。这个社区以前帮助过我,所以我希望有人能再次向我提供帮助。我对 JQuery 了解不多。

我们正在使用 Easy Digital Downloads 建立一个 wordpress 网站,因此我们有一些限制,例如 无法更改 HTML,但我们可以在页面上添加添加 JQuery 元素.

这是一个类别选择系统,用户应该只能选择一个父类别和该父类别下的多个子类别。

我正在为以下场景寻找 JQuery 解决方案。

我们有 5 个,可能有 6 个“类别”。 这些类别具有由 UL 表示的子类别。默认情况下,应隐藏子类别。 当您单击父类别时,它应该显示下面的子类别。 如果您在任何时候单击相同的父类别,它应该取消选择所有子类别并再次隐藏它们。

我也只希望在任何给定点选择 1 个父类别。

让我给你一个场景。 您单击 Cat A,它会展开并显示 4 个子类别。 您单击其中的 2 个子类别。 你改变主意,改为点击 Cat B。 这应该会隐藏 Cat A 的子类别并取消选择子类别以及 Cat A 的父类别。

如果我说得不够清楚,重要的是您永远不能选择没有父类别的子类别。

我对在另一个线程中找到的东西做了一个基本的小提琴。只是为了显示和隐藏(虽然我还没有添加隐藏类)这有我们正在使用的html结构。

另一个问题是所有父类别都为子类别 (.children) 使用相同的类别

$('#in-download_category-156').click(function() {
  $(".children").toggle(this.checked);
});

FIDDLE

我知道这是一个很大的问题,所以我很感激你能给予我的任何帮助! 谢谢

【问题讨论】:

    标签: jquery html wordpress checkbox easy-digital-downloads


    【解决方案1】:

    试试这个(我在下面添加了一些注释):

    $('.fes-category-checklist > li > input[name^="download_category"]').change(function() {
      $(this)
        .closest('ul')
        .find('input[name^="download_category"]')
        .not(this)
        .prop('checked', false);
    });
    ul {
      list-style: none;
      padding-left: 20px;
    }
    
    ul.fes-category-checklist > li > input[name^="download_category"]:not(:checked) ~ ul.children {
      display: none;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    
    <ul class="fes-category-checklist">
      <li id="download_category-156">
        <input value="156" type="checkbox" name="download_category[]" id="in-download_category-156" />
        <label for="in-download_category-156" class="selectit">cat a</label>
    
        <ul class="children">
          <li id="download_category-161"><label class="selectit"><input value="161" type="checkbox" name="download_category[]" id="in-download_category-161"> cat a-1</label></li>
    
          <li id="download_category-162"><label class="selectit"><input value="162" type="checkbox" name="download_category[]" id="in-download_category-162"> cat a-2</label></li>
    
          <li id="download_category-163"><label class="selectit"><input value="163" type="checkbox" name="download_category[]" id="in-download_category-163"> cat a-3</label></li>
    
          <li id="download_category-183"><label class="selectit"><input value="183" type="checkbox" name="download_category[]" id="in-download_category-183"> cat a-4</label></li>
        </ul>
      </li>
    
      <li id="download_category-160">
        <input value="160" type="checkbox" name="download_category[]" id="in-download_category-160" />
        <label for="in-download_category-160" class="selectit">cat b</label>
    
        <ul class="children">
          <li id="download_category-198"><label class="selectit"><input value="198" type="checkbox" name="download_category[]" id="in-download_category-198"> cat b-1</label></li>
    
          <li id="download_category-199"><label class="selectit"><input value="199" type="checkbox" name="download_category[]" id="in-download_category-199"> cat b-2</label></li>
    
          <li id="download_category-200"><label class="selectit"><input value="200" type="checkbox" name="download_category[]" id="in-download_category-200"> cat b-3</label></li>
    
          <li id="download_category-201"><label class="selectit"><input value="201" type="checkbox" name="download_category[]" id="in-download_category-201"> cat b-4</label></li>
        </ul>
      </li>
    
      <li id="download_category-155">
        <input value="155" type="checkbox" name="download_category[]" id="in-download_category-155" />
        <label for="in-download_category-155" class="selectit">cat c</label>
    
        <ul class="children">
          <li id="download_category-164"><label class="selectit"><input value="164" type="checkbox" name="download_category[]" id="in-download_category-164"> cat c-1</label></li>
    
          <li id="download_category-165"><label class="selectit"><input value="165" type="checkbox" name="download_category[]" id="in-download_category-165"> cat c-2</label></li>
    
          <li id="download_category-166"><label class="selectit"><input value="166" type="checkbox" name="download_category[]" id="in-download_category-166"> cat c-3</label></li>
    
          <li id="download_category-169"><label class="selectit"><input value="169" type="checkbox" name="download_category[]" id="in-download_category-169"> cat c-4</label></li>
    
          <li id="download_category-171"><label class="selectit"><input value="171" type="checkbox" name="download_category[]" id="in-download_category-171"> cat c-5</label></li>
    
          <li id="download_category-168"><label class="selectit"><input value="168" type="checkbox" name="download_category[]" id="in-download_category-168"> cat c-6</label></li>
    
          <li id="download_category-170"><label class="selectit"><input value="170" type="checkbox" name="download_category[]" id="in-download_category-170"> cat c-7</label></li>
    
          <li id="download_category-202"><label class="selectit"><input value="202" type="checkbox" name="download_category[]" id="in-download_category-202"> cat c-8</label></li>
        </ul>
      </li>
    
      <li id="download_category-157">
        <input value="157" type="checkbox" name="download_category[]" id="in-download_category-157" />
        <label class="selectit" for="in-download_category-157">cat d</label>
      </li>
    </ul>

    请注意,我将第一个复选框组从 label and assigning a for attribute 中移出。

    要以上面示例中所示的方式将&lt;label&gt;&lt;input&gt; 元素相关联,您需要为&lt;input&gt; 提供id 属性。然后&lt;label&gt; 需要一个for 属性,其值与输入的id 相同。

    还使用了一些 CSS 技巧,允许您根据元素的 pseudo-class“样式化”任何相邻的兄弟姐妹,在我们的例子中:具有:checked 状态的复选框元素。由于我们的ul.childrens 不是复选框的直接兄弟,而不是child combinator,我们需要使用general sibling combinator 来定位它们以进行样式设置。这有助于您不需要任何 Javascript 来切换子类别 UL 的可见性状态。


    编辑

    好的,既然 HTML 结构必须保持完整,而且父元素和子元素共享相同的类,我们可能别无选择,只能使用 chained 子组合子,因为我们不希望任何孩子获得与父母相同的样式。 除非您能够为父母分配一些特殊的类或属性(例如&lt;li id="download_category-156" class="parent-category"&gt;)以将他们与孩子区分开来。

    这看起来有点难看(更长的选择器),但它应该可以解决问题:

    $('.fes-category-checklist > li > label.selectit > input[name^="download_category"]').change(function() {
      var categoryId = this.value;
      var $checkbox = $(this);
    
      $('.fes-category-checklist')
        .find('li[id^="download_category"]')
        .attr('data-open', function(index, value) {
          return this.id.endsWith(categoryId) && value === 'false';
        });
    
      $checkbox
        .closest('ul')
        .find('input[name^="download_category"]')
        .not(this)
        .prop('checked', false);
    });
    
    $(document).ready(function() {
      $('ul.fes-category-checklist')
        .find('> li[id^="download_category"]')
        .attr('data-open', false)
        .fadeIn();
    });
    ul {
      list-style: none;
      padding-left: 20px;
    }
    
    ul.fes-category-checklist > li {
      display: none;
    }
    
    li[data-open="false"] > ul.children {
      display: none;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
    
    <ul class="fes-category-checklist">
      <li id="download_category-156">
        <label class="selectit">
          <input value="156" type="checkbox" name="download_category[]" id="in-download_category-156"> cat a
        </label>
        <ul class="children">
          <li id="download_category-161"><label class="selectit"><input value="161" type="checkbox" name="download_category[]" id="in-download_category-161"> cat a-1</label></li>
    
          <li id="download_category-162"><label class="selectit"><input value="162" type="checkbox" name="download_category[]" id="in-download_category-162"> cat a-2</label></li>
    
          <li id="download_category-163"><label class="selectit"><input value="163" type="checkbox" name="download_category[]" id="in-download_category-163"> cat a-3</label></li>
    
          <li id="download_category-183"><label class="selectit"><input value="183" type="checkbox" name="download_category[]" id="in-download_category-183"> cat a-4</label></li>
        </ul>
      </li>
    
      <li id="download_category-160">
        <label class="selectit">
          <input value="160" type="checkbox" name="download_category[]" id="in-download_category-160"> cat b
        </label>
        <ul class="children">
          <li id="download_category-198"><label class="selectit"><input value="198" type="checkbox" name="download_category[]" id="in-download_category-198"> cat b-1</label></li>
    
          <li id="download_category-199"><label class="selectit"><input value="199" type="checkbox" name="download_category[]" id="in-download_category-199"> cat b-2</label></li>
    
          <li id="download_category-200"><label class="selectit"><input value="200" type="checkbox" name="download_category[]" id="in-download_category-200"> cat b-3</label></li>
    
          <li id="download_category-201"><label class="selectit"><input value="201" type="checkbox" name="download_category[]" id="in-download_category-201"> cat b-4</label></li>
        </ul>
      </li>
    
      <li id="download_category-155">
        <label class="selectit">
          <input value="155" type="checkbox" name="download_category[]" id="in-download_category-155"> cat c
        </label>
        <ul class="children">
          <li id="download_category-164"><label class="selectit"><input value="164" type="checkbox" name="download_category[]" id="in-download_category-164"> cat c-1</label></li>
    
          <li id="download_category-165"><label class="selectit"><input value="165" type="checkbox" name="download_category[]" id="in-download_category-165"> cat c-2</label></li>
    
          <li id="download_category-166"><label class="selectit"><input value="166" type="checkbox" name="download_category[]" id="in-download_category-166"> cat c-3</label></li>
    
          <li id="download_category-169"><label class="selectit"><input value="169" type="checkbox" name="download_category[]" id="in-download_category-169"> cat c-4</label></li>
    
          <li id="download_category-171"><label class="selectit"><input value="171" type="checkbox" name="download_category[]" id="in-download_category-171"> cat c-5</label></li>
    
          <li id="download_category-168"><label class="selectit"><input value="168" type="checkbox" name="download_category[]" id="in-download_category-168"> cat c-6</label></li>
    
          <li id="download_category-170"><label class="selectit"><input value="170" type="checkbox" name="download_category[]" id="in-download_category-170"> cat c-7</label></li>
    
          <li id="download_category-202"><label class="selectit"><input value="202" type="checkbox" name="download_category[]" id="in-download_category-202"> cat c-8</label></li>
        </ul>
      </li>
    
      <li id="download_category-157">
        <label class="selectit"><input value="157" type="checkbox" name="download_category[]" id="in-download_category-157"> cat d</label>
      </li>
    </ul>

    添加孩子可见性的初始状态

    以下几行将它们最初设置为hidden。如果您想单独调整状态,也可以传递function in the second argument

    $(document).ready(function() {
      $('ul.fes-category-checklist')
        .find('> li[id^="download_category"]')
        .attr('data-open', false)
        .fadeIn();
    });
    

    另外,如果您想在子 UL 被切换时给它们一些花哨的效果,请查看 my other post,了解如何使用 jQuery slideToggle 做到这一点。

    希望有帮助!

    【讨论】:

    • 不幸的是,原始帖子中的 html 结构必须保持不变。我无法以任何方式改变它。还有办法让它发挥作用吗?
    • 我明白了。是的,总是有办法的。但这次我们很可能需要一些脚本。
    • 啊好吧!那么这必须用javascript来完成吗?对不起,我对此不是很了解。
    • 我正在为您解决问题。真正的问题似乎是父元素和子元素共享相同的类。
    • 别担心,我现在所拥有的完全可以满足我的需要:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-17
    • 1970-01-01
    • 1970-01-01
    • 2012-03-24
    • 1970-01-01
    • 1970-01-01
    • 2016-02-12
    相关资源
    最近更新 更多