4

I'm creating a table with multiple rows, all having an "Options" button that is supposed to show a dropdown context menu. To keep the code shorter, I'm using a single div in order to reuse it as a common markup for the context menu.

I'm using Bootstrap 5.1.3 and jQuery 3.6.0. Following is my code:

<!doctype html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Test Code</title>
  <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
</head>

<body>
  <table id="myTable" class="table table-hover">
    <thead>
      <tr>
        <th>#</th>
        <th>Document</th>
        <th>Reference</th>
        <th>Action</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>1</td>
        <td>General Policies</td>
        <td>GP-01-2022</td>
        <td>
          <div class="dropdown">
            <a href="#" class="btn btn-primary optionsButton" data-bs-toggle="dropdown" aria-expanded="false" id="doc1">Options</a>
          </div>
        </td>
      </tr>
      <tr>
        <td>2</td>
        <td>Training Material</td>
        <td>GP-02-2022</td>
        <td>
          <div class="dropdown">
            <a href="#" class="btn btn-primary optionsButton" data-bs-toggle="dropdown" aria-expanded="false" id="doc2">Options</a>
          </div>
        </td>
      </tr>
    </tbody>
  </table>

  <ul id="contextMenu" class="dropdown-menu">
    <li><a tabindex="-1" href="#" class="dropdown-item downloadLink">Download</a></li>
    <li><a tabindex="-1" href="#" class="dropdown-item propertiesLink">Properties</a></li>
  </ul>

  <script>
    //save the selector so you don't have to do the lookup everytime
    var $dropdown = $('#contextMenu');

    $('.optionsButton').click(function(event) {

      //get document ID
      var id = this.id;

      //move dropdown menu
      $(this).after($dropdown);

      //update links
      $dropdown.find(".downloadLink").attr("href", "/data/download?id=" + id);
      $dropdown.find(".propertiesLink").attr("href", "/data/viewproperties?id=" + id);

      //show dropdown
      $(this).dropdown();
    });
  </script>


</body>

</html>

In this code I'm facing two types of problems. Firstly, the dropdown menu isn't opening. When I inspect the code in Developer Mode, I can see that the jQuery script is successfully transferring the contextmenu DIV underneath the "Options" button so that it becomes nested as required by Bootstrap. But then the $(this).dropdown(); isn't opening the menu.

Second error is that in Developer Mode console, I see this error every time I click the 'Options' button:

dropdown.js:285 Uncaught TypeError: Failed to execute 'getComputedStyle' on 'Window': parameter 1 is not of type 'Element'.

And the stack trace of this error points to dropdown.js, does not specify where the error lies in my code.
Need help in trying to diagnose the issue here. I'm fairly new to Bootstrap and jQuery. Thanks.

Roko C. Buljan
  • 196,159
  • 39
  • 305
  • 313
Faraz Azhar
  • 562
  • 9
  • 28

3 Answers3

5

TL;DR: Don't move the #contextMenu anywhere. Read: Solution*


The error you're getting

dropdown.js:285 Uncaught TypeError: Failed to execute 'getComputedStyle' on 'Window': parameter 1 is not of type 'Element'.

is related to the Bootstrap (v5.1.3): dropdown.js code:

// @l62:
const SELECTOR_MENU = '.dropdown-menu'

// @l103:
  constructor(element, config) {
    super(element);
    //...
    this._menu = this._getMenuElement()
    //...
  }

// @l269:
  _getMenuElement() {
    return SelectorEngine.next(this._element, SELECTOR_MENU)[0]
  }

// @l285:
   _getPlacement() {
    // ...
    const isEnd = getComputedStyle(this._menu).getPropertyValue('--bs-position').trim() === 'end'
    // ...
  }

here: SelectorEngine.next(this._element,

as you can see, there's no way to pass to the constructor another Element .menu-dropdown besides the one that BS hardcoded, and that's a next Sibling element in the Method _getMenuElement() ~line285.

BS assigns a "click" Event to every button with data-bs-toggle="dropdown" and blindly expects to toggle a next sibling Element dropdown — which does not actually exists (yet)!

I would either:

  • extend the class Dropdown manually, or
  • raise an Issue and create a pull-request to the related Bootstrap module

as a way to pass any desired Element as the this._menu; something like:

  constructor(element, config) {
    //...
    // Fix: allow for custom reusable menu Element
    this._menu = config.menuElement || this._getMenuElement()
    //...
  }

Disclaimer: There are some changes in the main branch regarding the above stripped-off code, I'm not sure if at the time of writing those issues were addressed.


In the meantime what you can simply do, without using the "mousedown" Event (to be one step ahead the BS's "click" event - like in this duplicate question's answer), and without using the silly Event.stopPropagation() (which should never be used, besides you really, really know what you're doing, or for debugging purpose only) — is:

Solution:

Don't move the UL#contextMenu using .after() or (with JS) .insertAdjacentElement(), rather, on instantiation of the extended Popper instances change the expected Bootstrap this._menu property to point to the desired reusable Element — your in-body "#contextMenu" like:

<!doctype html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Test Code</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
</head>

<body>
  <table id="myTable" class="table table-hover">
    <thead>
      <tr>
        <th>#</th>
        <th>Document</th>
        <th>Reference</th>
        <th>Action</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>1</td>
        <td>General Policies</td>
        <td>GP-01-2022</td>
        <td>
          <div class="dropdown">
            <button type="button" class="btn btn-primary optionsButton" data-bs-toggle="dropdown" aria-expanded="false" id="doc1">Options</button>
          </div>
        </td>
      </tr>
      <tr>
        <td>2</td>
        <td>Training Material</td>
        <td>GP-02-2022</td>
        <td>
          <div class="dropdown">
            <button type="button" class="btn btn-primary optionsButton" data-bs-toggle="dropdown" aria-expanded="false" id="doc2">Options</button>
          </div>
        </td>
      </tr>
    </tbody>
  </table>

  <ul id="contextMenu" class="dropdown-menu">
    <li><button type="button" tabindex="-1" class="dropdown-item downloadLink">Download</button></li>
    <li><button type="button" tabindex="-1" class="dropdown-item propertiesLink">Properties</button></li>
  </ul>

  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>

  <script>
    // DOM utility functions:
    const el = (sel, par) => (par || document).querySelector(sel);
    const els = (sel, par) => (par || document).querySelectorAll(sel);

    // Task: BS5 Popper fix for single static dropdown menu:
    const elDropdown = el('#contextMenu');
    const elsBtns = els(".optionsButton");
    const dropdownList = [...elsBtns].map(function(elBtn) {
      const instance = new bootstrap.Dropdown(elBtn);
      instance._menu = elDropdown;
      return instance;
    });
    // console.log(dropdownList); 
  </script>

</body>

</html>

The nice thing of the above is that there are no changes in the DOM that would trigger a reflow. The Popper code will calculate the best position of your floating contextMenu and call it job-done.
The not so nice thing is that special care should be given in the case you dynamically add TR elements to the Table; in the means that every newly added Button should be instantiated upon creation as a new bootstrap.Dropdown(elBtn)

Using "mousedown"

Another (not so good) solution to your original idea is to (unnecessarily) move the dropdown in DOM. It can be achieved using the "mousedown" Event, in order to move the dropdown "ahead-of-time" — before the BS's "click" event triggers (as suggested in this related question's answer). But such will not work correctly. Clicking one button after the other, a flash of content / glitch (of the actual dropdown) can be seen. There might be ways to mitigate the issue… but, why. Anyways, FYEO here's the code:

<!doctype html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Test Code</title>

  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
</head>

<body>
  <table id="myTable" class="table table-hover">
    <thead>
      <tr>
        <th>#</th>
        <th>Document</th>
        <th>Reference</th>
        <th>Action</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>1</td>
        <td>General Policies</td>
        <td>GP-01-2022</td>
        <td>
          <div class="dropdown">
            <button type="button" class="btn btn-primary optionsButton" data-bs-toggle="dropdown" aria-expanded="false" id="doc1">Options</button>
          </div>
        </td>
      </tr>
      <tr>
        <td>2</td>
        <td>Training Material</td>
        <td>GP-02-2022</td>
        <td>
          <div class="dropdown">
            <button type="button" class="btn btn-primary optionsButton" data-bs-toggle="dropdown" aria-expanded="false" id="doc2">Options</button>
          </div>
        </td>
      </tr>
    </tbody>
  </table>

  <ul id="contextMenu" class="dropdown-menu">
    <li><button type="button" tabindex="-1" class="dropdown-item downloadLink">Download</button></li>
    <li><button type="button" tabindex="-1" class="dropdown-item propertiesLink">Properties</button></li>
  </ul>

  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>

  <script>
    // DOM utility functions:
    const el = (sel, par) => (par || document).querySelector(sel);
    const els = (sel, par) => (par || document).querySelectorAll(sel);

    // Task: BS5 Popper fix for single static dropdown menu:
    const elDropdown = el('#contextMenu');
    const elsBtns = els(".optionsButton");

    const prepareDropdown = (evt) => {
      const elBtn = evt.currentTarget;
      elBtn.insertAdjacentElement("afterend", elDropdown);
    };

    elsBtns.forEach(elBtn => elBtn.addEventListener("mousedown", prepareDropdown));
  </script>


</body>

</html>

PS: use always <button type="button"> instead of Anchors (as in the examples above) if you don't need to navigate, but just a plain UI interaction button Element.

The way that BS uses and implements popups, selects etc. is kind of broken anyways. If a popup (or modal) is already opened, by clicking another button — the second (or the same) popup should be shown immediately (not after a second click). It's a UI/UX flaw in the design. Bootstrap often implements ideas quite oddly, but don't forget you can always help the Open Source community by providing a Pull Request.


If you're interested on how to create a (similar) Popup from scratch using JavaScript — you can find out more here: Show custom popup on mouse location.

Roko C. Buljan
  • 196,159
  • 39
  • 305
  • 313
  • Thanks for the very detailed answer. It clears my mystery of why errors were happening. Clearly there's something in BS 5 that's causing the error, because the same original code of mine seems to be working on a lower version of JSQuery and BS, but I cannot afford to downgrade at this moment. Thanks! – Faraz Azhar Jul 13 '22 at 02:30
  • @FarazAzhar exactly, [Kyle's answer on this other similar question](https://stackoverflow.com/a/24975399/383904) works pretty fine with BS3. You're welcome. – Roko C. Buljan Jul 13 '22 at 06:08
  • I came across your nice solution while trying to brew something with jQuery (which did not work). I am trying to figure out how to extract data- attribute values and also the id value using your solution. I need to pass these values +id to the contextMenu buttons, so that they can be utilized accordingly. Would you have any idea how to do this? And can your solution be accomplished with jQuery? – Sha Dec 07 '22 at 13:51
  • 1
    @Sha this is a quite heavy request that goes out of the scope of this answer. Perhaps try to ask a New question. I'll be happy to take a look at it. – Roko C. Buljan Dec 07 '22 at 14:03
  • @RokoC.Buljan - I have posted a new question. If you find time, please take a look - would love your inputs: https://stackoverflow.com/questions/74719066/reusable-dropdown-using-jquery-and-bootstrap – Sha Dec 07 '22 at 15:26
0

I have commented your loading of the bootstrap cdn and dealt with only with your actual Javascript.

You only had a logic to display the dropdown, albeit I changed it from $(this).dropdown(); to $dropdown.show(), because your dropdown is already tracked with this variable.

I have also implemented the toggling effect, that is, if your dropdown is opened, then we have the following scenarios:

  • you click somewhere else in the table, in which case the dropdown will be hidden
  • you click on the same button, in which case the dropdown will be hidden
  • you click on a similar button in another line, in which case the dropdown will be properly moved to the appropriate place using the appropriate parameters

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Test Code</title>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
</head>
<body>
    <table id="myTable" class="table table-hover" onclick="hideall()">
        <thead>
            <tr>
                <th>#</th>
                <th>Document</th>
                <th>Reference</th>
                <th>Action</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>1</td>
                <td>General Policies</td>
                <td>GP-01-2022</td>
                <td>
                    <div class="dropdown">
                        <a href="#" class="btn btn-primary optionsButton" aria-expanded="false" id="doc1">
                            Options
                        </a>
                    </div>
                </td>
            </tr>
            <tr>
                <td>2</td>
                <td>Training Material</td>
                <td>GP-02-2022</td>
                <td>
                    <div class="dropdown">
                        <a href="#" class="btn btn-primary optionsButton" aria-expanded="false" id="doc2">
                            Options
                        </a>
                    </div>
                </td>
            </tr>
        </tbody>
    </table>
    


    <ul id="contextMenu" class="dropdown-menu">
        <li><a tabindex="-1" href="#" class="dropdown-item downloadLink">Download</a></li>
        <li><a tabindex="-1" href="#" class="dropdown-item propertiesLink">Properties</a></li>
    </ul>
    
    <script>
        //save the selector so you don't have to do the lookup everytime
        var $dropdown = $('#contextMenu');
        var activeOptionsButton;

        $('.optionsButton').click(function(event) {
        
            event.stopPropagation();
            if (activeOptionsButton === this) {
                hideall();
                activeOptionsButton = undefined;
                return;
            }
            activeOptionsButton = this;
            //get document ID
            var id = this.id;
            
            //move dropdown menu
            $(this).after($dropdown);

            //update links
            $dropdown.find(".downloadLink").attr("href", "/data/download?id="+id);
            $dropdown.find(".propertiesLink").attr("href", "/data/viewproperties?id="+id);
            
            //show dropdown
            $dropdown.show();
        });
        
        function hideall() {
            $dropdown.hide();
        }
    
    </script>


</body>
</html>
Lajos Arpad
  • 64,414
  • 37
  • 100
  • 175
  • Although your code works well, its not the solution for me. I cannot disable the Bootstrap's JS because it will break the rest of the UI (not part of this post). The `$(this).dropdown();` is a Bootstrap function which is called on the container holding the context menu, not the context menu itself. – Faraz Azhar Jul 10 '22 at 16:32
  • @FarazAzhar uncommented bootstrap and removed `data-bs-toggle="dropdown"` from the options buttons. Can you test again with the edited snippet. I think the current snippet either solves your problem or is very close to solving it. – Lajos Arpad Jul 10 '22 at 17:06
  • 1
    **Never** use `event.stopPropagation()`. An app should **always** be able to be notified and eventually respond on any kind of Events both from your code or third-party. There's not a single valid point in using `stopPropagation()`. Also this example does not works properly. – Roko C. Buljan Jul 10 '22 at 17:54
  • @RokoC.Buljan have you tried to solve this without `stopPropagation`? Was it working? Can you show us the snipped/fiddle? Also, can you provide the error/glitch that you have seen testing my snippet? Do you have reproduction steps or other debugging details? Thanks! – Lajos Arpad Jul 10 '22 at 18:40
  • 1
    On a second click the Dropdown does not open. Using a *manual* Query .show() and .hide() defies the purpose of the plugin - to internally handle the state. The plugin clearly got broken somewhere between Bootstrap version 3 and 5, see in [this duplicate question](https://stackoverflow.com/q/24974679/383904). As soon you assign `data-bs-toggle` the Popper and BS logic becomes too invasive, not allowing (as far as I've tested and researched) to reuse a single dropdown as component. No, stopPropagation is still for the same reasons not a good solution. – Roko C. Buljan Jul 11 '22 at 06:10
  • *"mousedown* is the closest you can get to get it working since that event is triggered before the BS's (Popper) `"click"` which necessitates that `.dropdown-menu` element to be already present in the DOM as a next sibling in order for their silly JS logic to work. And no. `stopPropagation` should still not be used. Actually forget that method exists - unless you really know what you're doing or you solely need it for debugging purpose. – Roko C. Buljan Jul 11 '22 at 06:14
  • The [Bootstrap 5 documentation](https://getbootstrap.com/docs/5.0/components/dropdowns/#via-javascript) lacks many methods and options. I tried also to tap into the Popper one, but with no luck so far. Perhaps the authors could take a look into a filed issue. I'm not saying that the current could not be hacked around to get it working (in a proper way!) but, too much research and work for a simple code that can be done in a dozen of lines of JS (toggle a reusable popup with dynamic positioning and scroll-aware). – Roko C. Buljan Jul 11 '22 at 06:19
  • Anyways, added an in-depth answer. – Roko C. Buljan Jul 11 '22 at 07:30
  • @RokoC.Buljan thanks for describing your thoughts and presenting your arguments. I have tested my snippet and it was working in the scenario you have described. – Lajos Arpad Jul 11 '22 at 13:50
  • @LajosArpad interestingly I cannot reproduce any more the afore mentioned regarding the "second click". But there's new bugs: since the Dropdown #textcontentMenu is appended to the TD cell the cells size changes to accommodate the Dropdown. Also, by clicking the document (not the table) the dropdown does not closes. As I said you disrupted the behavior of the Popper plugin by *simply* using `.hide()` and `.show()`. That's not the way to tackle this issue. :) – Roko C. Buljan Jul 11 '22 at 14:34
  • @RokoC.Buljan "since the Dropdown #textcontentMenu is appended to the TD cell the cells size changes to accommodate the Dropdown" this was not my addition. I have taken the snippet of the op and have used that as a starting point. "Also, by clicking the document (not the table) the dropdown does not closes." If you add a click handler to the body, then clicking on that will not trigger the click handler for some mobile browsers. The solution to this is to have a wrapper tag for the whole content and have a handler for this wrapper. But, since this question was not about this wrapper, – Lajos Arpad Jul 12 '22 at 09:58
  • @RokoC.Buljan for the sake of simplicity I refrained from adding further information about this aspect unless the op has further questions tackling it. Anyway, thanks for your comments! – Lajos Arpad Jul 12 '22 at 09:59
-2

try this..

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Test Code</title>
  
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css" integrity="sha384-zCbKRCUGaJDkqS1kPbPd7TveP5iyJE0EjAuZQTgFLD2ylzuqKfdKlfG/eSrtxUkn" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.min.js" integrity="sha384-VHvPCCyXqtD5DqJeNxl2dtTyhF78xXNXdkwX1CZeRusQfRKp+tA7hAShOK/B/fQ2" crossorigin="anonymous"></script>
  
</head>
<body>
    <table id="myTable" class="table table-hover">
        <thead>
            <tr>
                <th>#</th>
                <th>Document</th>
                <th>Reference</th>
                <th>Action</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>1</td>
                <td>General Policies</td>
                <td>GP-01-2022</td>
                <td>
                    <div class="dropdown">
                        <a href="#" class="btn btn-primary optionsButton" data-bs-toggle="dropdown" aria-expanded="false" id="doc1">
                            Options
                        </a>
                    </div>
                </td>
            </tr>
            <tr>
                <td>2</td>
                <td>Training Material</td>
                <td>GP-02-2022</td>
                <td>
                    <div class="dropdown">
                        <a href="#" class="btn btn-primary optionsButton" data-bs-toggle="dropdown" aria-expanded="false" id="doc2">
                            Options
                        </a>
                    </div>
                </td>
            </tr>
        </tbody>
    </table>
    


    <ul id="contextMenu" class="dropdown-menu">
        <li><a tabindex="-1" href="#" class="dropdown-item downloadLink">Download</a></li>
        <li><a tabindex="-1" href="#" class="dropdown-item propertiesLink">Properties</a></li>
    </ul>
    
    <script>
        //save the selector so you don't have to do the lookup everytime
        var $dropdown = $('#contextMenu');

        $('.optionsButton').click(function(event) {
            
            //get document ID
            var id = this.id;
            
            //move dropdown menu
            $(this).after($dropdown);

            //update links
            $dropdown.find(".downloadLink").attr("href", "/data/download?id="+id);
            $dropdown.find(".propertiesLink").attr("href", "/data/viewproperties?id="+id);
            
            //show dropdown
            $(this).dropdown();
        });
    
    </script>


</body>
</html>
  • Thanks. You've downgraded the Bootstrap script version? I tried this code, the dropdown menu opens up but never closes again, even if clicked outside or on the button again. – Faraz Azhar Jul 05 '22 at 11:50
  • pls check your js – Mithun Deshan Jul 05 '22 at 11:51
  • My JS is right there in the post. I need help in diagnosing the issue with the JS, that's why I posted the question. Appreciate if you can identify what the problem with the JS is. Thanks. – Faraz Azhar Jul 05 '22 at 19:11