2

I have a table of transactions, and I would like to add a small button to each row. When clicked, a small drop down should appear with two menu items, something like this:

<ul id="contextMenu" class="dropdown-menu" role="menu" style="display:none" >
    <li><a tabindex="-1" href="#">Pay</a></li>
    <li><a tabindex="-1" href="#">Delete</a></li>
</ul>

However, my table can have between zero and potentially hundreds of rows, so repeating the code, PLUS the button that has to create the drop down, would be a lot of page size addition.

Is there a way to have that code once, and somehow, from the button click, use the same code from each row? Additionally, I would need to change the href value for each row, based on the ID of that row. So the href would actually be something like:

\transaction\pay?id=10

With the ID changing for each row.

KyleMit
  • 30,350
  • 66
  • 462
  • 664
Craig
  • 18,074
  • 38
  • 147
  • 248

3 Answers3

4

Add a button to your rows like this:

<td class="dropdown">
    <a class="btn btn-default actionButton" data-toggle="dropdown" href="#">
        Action
    </a>
</td>

Dropdown will only automatically position itself when it is right after the data-toggle that's opening it. To avoid having to write a lot of positioning code, you can just move the dropdown menu before you open it:

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

$(".actionButton").click(function() {
    //get row ID
    var id = $(this).closest("tr").children().first().html();

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

    //update links
    $dropdown.find(".payLink").attr("href", "/transaction/pay?id="+id);
    $dropdown.find(".delLink").attr("href", "/transaction/delete?id="+id);

    //show dropdown
    $(this).dropdown();
});

Demo in jsFiddle

KyleMit
  • 30,350
  • 66
  • 462
  • 664
1

Thanks To KyleMit:

For any one who would prefer to use html5 data element rather than row ID.

change this....

<td class="dropdown">
   <a class="btn btn-default actionButton" data-toggle="dropdown" href="#" data-iteration-id="${current.id}" data-some-other-thing="someOther.thing"> 
        Action
    </a>
</td>

Then your menu outside of iteration:

<ul id="contextMenu" class="hiddenMenu dropdown-menu" role="menu" >
 <li><a id="edit"><g:message code="default.button.edit.label"/></a></li>
 <li><a id="delete" onclick="return 
   confirm('${message(code: 'default.button.delete.confirm.message', default: 'Are you sure?')}');">
  <g:message code="default.button.delete.label"/></a></li>
</ul>

Now finally script:

<script>
$(function() {
            $dropdown = $("#contextMenu");
            $(".actionButton").click(function() {
                var id = $(this).attr('data-iteration-id');
                //var otherElement = $(this).attr('data-some-other-thing');
                //var id = $(this).closest("tr").children().first().html();
                $(this).after($dropdown);
                $dropdown.find("#edit").attr("href", "${createLink(action: "edit")}/"+id);
                $dropdown.find("#delete").attr("href", "${createLink(action: "delete")}/"+id);
                $(this).dropdown();
            });
        });
</script>

This works perfectly for me under grails. Thanks again

V H
  • 8,382
  • 2
  • 28
  • 48
1

For Bootstrap 5

Moving the context menu on 'mousedown' instead of 'click' moves the element before the bootstrap dropdown is fired. I can't determine if it works on mobile at the moment.

    $contextMenu = $("#contextMenu");

    $(".day-context").on("mousedown",function() {
      //move dropdown menu
      $(this).after($contextMenu);
    });
Scott Jodoin
  • 175
  • 2
  • 8
  • This is the best solution since that feature (reuse a single Dropdown menu by appending) is **basically broken** in Bootstrap 5 (Popper JS). Using Bootstrap 3 there's still some working solutions (as [proposed by Kyle](https://stackoverflow.com/a/24975399/383904)). – Roko C. Buljan Jul 10 '22 at 19:50
  • 1
    Here's some more findings and a solution about the related problem in Bootstrap 5: https://stackoverflow.com/a/72935065/383904 – Roko C. Buljan Jul 11 '22 at 07:50