复选框组选择的动态限制

时间:2018-11-23 15:34:57

标签: javascript jquery r checkbox shiny

我有一个checkboxGroupInput,有4种选择( A B C D )。
我想将允许的选择限制为2个选项。

允许允许用户选择第三个选项。
但是在那种情况下,只有选中的新(第三)和最后(第二)选项才保持选中状态。

例如,如果用户选择 B ,则选择 D ,然后选择 A -
结果应该仅进行 D A 检查。

我正在尝试在JS中实现此逻辑,因为它在R / Shiny中无法正常工作。
主要原因是更新不会立即发生。
(由于我原始的Shiny应用程序中的其他无效操作而被延迟,这需要花费一些时间)

最小示例:

library(shiny)

shinyApp(
  ui = fluidPage(
    tags$script(
      "JS code here..."
    ),

    checkboxGroupInput(
      inputId = "the_checkbox",
      label = "Checkbox",
      choices = c("A", "B", "C", "D")
    )
  ),

  server = function(input, output, session) {}
)

1 个答案:

答案 0 :(得分:1)

注意:生成的HTML外观可能有所不同,但是您所需的JS肯定是相同的。一切都用香草JS编写,以防万一您通常使用jQuery,只需更改最后的“激活”代码即可。

给出此HTML:

<div class="inputgroup">
  <div class="checkbox">
    <input type="checkbox" name="check1" value="A" id="c1">
    <label for="c1">A</label>
  </div>
  <div class="checkbox">
    <input type="checkbox" name="check2" value="B" id="c2">
    <label for="c2">B</label>
  </div>
  <div class="checkbox">
    <input type="checkbox" name="check3" value="C" id="c3">
    <label for="c3">C</label>
  </div>
  <div class="checkbox">
    <input type="checkbox" name="check4" value="D" id="c4">
    <label for="c4">D</label>
  </div>
</div>

要做这件事的JS代码非常简单(大量注释来解释发生了什么事情):

function justTwo (checkboxGroup) {
  // checkboxGroup is the <div class="inputgroup"> node
  // ---------

  // step 1: grab all <input> elements inside the group
  var boxes = Array.prototype.slice.call(checkboxGroup.querySelectorAll('input'));

  // step 2: create a list, where nodes which are checked are stored
  var checked = [];

  // step 3: create a function which unchecks boxes from the beginning
  //         of the list if a third checkbox is checked
  function handleCheckedChange (event) {
    if (event.target.checked) {    // if the user checked the box...
      if (checked.length >= 2) {   // ... and two or more boxes are checked already ...
        var fst = checked.shift(); // ... take the first/oldest checked ...
        fst.checked = null;        // ... uncheck it ...
      }
      checked.push(event.target);  // ... and save the reference to the newly checked
    } else {                                    // if he unchecked a box ...
      checked = checked.filter(function (box) { // ... remove possible references
        return box !== event.target;
      });
    }
  }

  // step 4: make every <input> "listen" to check-changes
  boxes.forEach(function (box) {
    box.addEventListener('change', handleCheckedChange);
  });
}

然后,您必须在每个复选框组上“激活”它。这是我一无所知的部分。希望它仍然可以帮助:)

justTwo(document.querySelector('.inputgroup'));

或使用jQuery:

$('.inputgroup').each(function () { justTwo(this); });