Динамический предел выбора группы флажков - PullRequest
0 голосов
/ 23 ноября 2018

У меня есть checkboxGroupInput с 4 вариантами выбора ( A , B , C , D ).
Iхотите ограничить разрешенный выбор двумя вариантами.

Пользователь может выбрать третий вариант.
Но в этом случае только новый (третий) и последний (второй)выбранные параметры должны оставаться отмеченными.

Например, если пользователь выбирает 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 голосов
/ 23 ноября 2018

Примечание: HTML-код, который вы создаете, скорее всего, выглядит иначе, но JS, который вам нужен, наверняка, тот же.Все написано на vanilla 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); });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...