Crezzur
Crezzur

Reputation: 1479

Dropdown choices-js stays under div in a bootstrap table-responsive class

When I use the choices-js drop-down menu in a Bootstrap 5 responsive table, it doesn't display correctly. In the example, ID 1 is wrong and ID 3 responds correctly.

It is important that overflow-x uses a scroll bar and overflow-y does not.

For example using overflow: inherit does not have the correct effect.

.table-responsive{ overflow: inherit !important; }

Snippet:

let task_data = [
  { value: "1", label: "TASK 100" },
  { value: "2", label: "TASK 101" },
  { value: "3", label: "TASK 102" },
  { value: "4", label: "TASK 103" },
  { value: "5", label: "TASK 104" },
  { value: "6", label: "TASK 105" },
];

new Choices($(`#task_0`)[0], {
  position: "bottom",
  choices: task_data,
  allowHTML: true,
});
body {
  background-color: #f5f5f5;
}

.table-responsive {
  overflow-y: visible!important;
}

#calplaceholder {
  max-height: 400px;
  height: auto!important;
  min-height: auto!important;
}

.cal-viewmonth,
.cal-toprow,
.cal-toprow-pro td:first-child {
  text-align: center;
  vertical-align: middle !important;
  font-weight: 600 !important;
}

.cal-toprow {
  font-size: 0.8rem;
  width: 162px;
  min-width: 162px;
  color: #3e5569;
  background-color: #F7F9FB!important;
  border: 1px solid #CCCCCC;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.0.2/css/bootstrap.min.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/choices.js/10.1.0/choices.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.1.3/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/choices.js/10.1.0/choices.min.js"></script>

<div class="row mt-5 justify-content-center">
  <div class="col-sm-11 col-md-8">
    <div id="calplaceholder" class="table-responsive bg-white p-3">
      <table class="table table-striped table-bordered cal-borders">
        <thead>
          <tr>
            <th class="cal-toprow">1</th>
            <th class="cal-toprow">2</th>
            <th class="cal-toprow">3</th>
            <th class="cal-toprow">4</th>
            <th class="cal-toprow">5</th>
            <th class="cal-toprow">6</th>
            <th class="cal-toprow">7</th>
            <th class="cal-toprow">8</th>
            <th class="cal-toprow">9</th>
            <th class="cal-toprow">10</th>
            <th class="cal-toprow">11</th>
            <th class="cal-toprow">12</th>
            <th class="cal-toprow">13</th>
            <th class="cal-toprow">14</th>
            <th class="cal-toprow">15</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td class="p-0">
              <select id="task_0" class="form-select"></select>
            </td>
            <td class="p-0"></td>
            <td class="p-0">
              <div id="task_1">
                <select class="form-select">
                  <option value="1">TASK 100</option>
                  <option value="2">TASK 101</option>
                  <option value="3">TASK 102</option>
                  <option value="4">TASK 103</option>
                  <option value="5">TASK 104</option>
                  <option value="6">TASK 105</option>
                </select>
              </div>
            </td>
            <td class="p-0"></td>
            <td class="p-0"></td>
            <td class="p-0"></td>
            <td class="p-0"></td>
            <td class="p-0"></td>
            <td class="p-0"></td>
            <td class="p-0"></td>
            <td class="p-0"></td>
            <td class="p-0"></td>
            <td class="p-0"></td>
            <td class="p-0"></td>
            <td class="p-0"></td>
          </tr>
        </tbody>
      </table>
    </div>
  </div>
</div>

Upvotes: 0

Views: 1413

Answers (1)

adel
adel

Reputation: 852

You need a few tricks to bring the dropdown out of the relative box.

Use the following function to manipulate the dropdown style:

// scrollableElement is the table container
// selectElement is the element you want to apply Choices to it
// options is Choices options
function applyChoices(scrollableElement, selectElement, options) {
  const choices = new Choices(selectElement, options);

  const containerOuter = choices.containerOuter.element;
  const dropdown = choices.dropdown.element;
  const containerRec = containerOuter.getBoundingClientRect();

  dropdown.style.position = 'fixed';
  dropdown.style.left = `${containerRec.x}px`;
  dropdown.style.top = `${containerRec.y + containerRec.height}px`;
  dropdown.style.width = `${containerOuter.offsetWidth}px`;

  scrollableElement.addEventListener('scroll', function () {
    choices.hideDropdown();
    dropdown.style.left = `${
      containerRec.x - scrollableElement.scrollLeft
    }px`;
    dropdown.style.top = `${
      containerRec.y - scrollableElement.scrollTop + containerRec.height
    }px`;
  });
}

You also can change the position of dropdown!

Take a look at this Codesandbox code to see how to use this function.

Upvotes: 1

Related Questions