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.

3 Answers 3

5

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

Sign up to request clarification or add additional context in comments.

Comments

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

Comments

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);
    });

2 Comments

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).
Here's some more findings and a solution about the related problem in Bootstrap 5: stackoverflow.com/a/72935065/383904

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.