2

A ViewComponent in my ASP.NET Core 1.1 project on VS2015 has a confirm delete modal/dialog with Twitter bootstrap as shown below. But when a user clicks on the Delete button to confirm a delete it does not trigger the jquery function shown below. The modal/dialog pops up fine but when I click on delete button with id= DeleteBtnID inside the modal/dialog I would expect it to popup the `alert('Test') but that is not happening. Question: What I may be missing? No errors are shown in Chrome's Developer Tool.

View that calls ViewComponent:

@model MyProj.Models.TestModel

some html
....
....
<div id="DeleteBtnParentID">
   @await Component.InvokeAsync("TestVC")
</div>

ViewComponent:

@model IEnumerable<MyProj.Models.TestModel>

<table>
    @foreach (var item in Model)
    {
        <tr>
            <td>
                <a asp-action="TestAction">@item.Title</a>
            </td>
            <td>
                <button type="button" class="btn btn-info btn-xs" data-toggle="modal" data-target="#myModal">Delete</button>
                <!-- Modal -->
                <div id="myModal" class="modal fade" role="dialog">
                    <div class="modal-dialog modal-sm">

                        <!-- Modal content-->
                        <div class="modal-content">
                            <div class="modal-header btn-warning" style="font-weight:bold;color:white;">
                                <button type="button" class="close" data-dismiss="modal">&times;</button>
                                <h5 class="modal-title modal-sm">Delete Warning</h5>
                            </div>
                            <div class="modal-body">
                                <p>Click 'Delete' to <strong>parmenently</strong> delete this record. Click 'Cancel' to cancel your action.</p>
                            </div>
                            <div class="modal-footer">
                                <button type="button" class="btn btn-danger" id="DeleteBtnID" value="@item.id" data-dismiss="modal">Delete</button>
                                <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
                            </div>
                        </div>
                    </div>
                </div>
            </td>
        </tr>
    }
</table>
@section scripts
{
   <script>
        $(document).ready(function () {

            $('#DeleteBtnParentID').on('click', '#DeleteBtnID', function (event) {
                alert('Test');
            });
        });
   </script>
}

Snapshot of the page source when I use Chrome's developer toot [You can click on the image for a larger view]:

enter image description here

Camilo Terevinto
  • 31,141
  • 6
  • 88
  • 120
nam
  • 21,967
  • 37
  • 158
  • 332
  • How is that related to ASP.NET Core? angular/bootstrap is run completely in the client (=browser) – Tseng Apr 14 '17 at 22:44

2 Answers2

3

ANSWER UPDATE

From comment:

Being outside the table will cause the modal's Delete button to not to recognize the attribute value @item.id of since item variable is used in the foreach loop.

A way to solve this point can be:

  • attach the value attribute to the button and no more to the modal confirm button
  • on modal show event (i.e.: show.bs.modal) get this attribute from button and save it to modal confirm button
  • use this attribute when clicking on confirmation button

Updated snippet:

$('#DeleteBtnID').on('click', function (event) {
    console.log('Test: ' + $(this).attr('value'));
});

$('#myModal').on('show.bs.modal', function (e) {
    var btnValue = $(e.relatedTarget).attr('value');
    $('#DeleteBtnID').attr('value', btnValue);
})
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>


<button type="button" class="btn btn-info btn-xs" data-toggle="modal" data-target="#myModal" value="@item.id1">Delete1</button>
<button type="button" class="btn btn-info btn-xs" data-toggle="modal" data-target="#myModal" value="@item.id2">Delete2</button>
<button type="button" class="btn btn-info btn-xs" data-toggle="modal" data-target="#myModal" value="@item.id3">Delete3</button>
<!-- Modal -->
<div id="myModal" class="modal fade" role="dialog">
    <div class="modal-dialog modal-sm">

        <!-- Modal content-->
        <div class="modal-content">
            <div class="modal-header btn-warning" style="font-weight:bold;color:white;">
                <button type="button" class="close" data-dismiss="modal">&times;</button>
                <h5 class="modal-title modal-sm">Delete Warning</h5>
            </div>
            <div class="modal-body">
                <p>Click 'Delete' to <strong>parmenently</strong> delete this record. Click 'Cancel' to cancel your action.</p>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-danger" id="DeleteBtnID"  data-dismiss="modal">Delete</button>
                <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
            </div>
        </div>
    </div>
</div>

From your code:

@foreach (var item in Model)

The IDs must be unique. So, I suggest you to insert in each table cell only the button and move outside the modal, i.e.:

<!-- Modal -->
<div id="myModal" class="modal fade" role="dialog">
 ..........
</div>

So, the event will be attached to the unique modal button.

The snippet:

//
// If you need to delegate....
//
$(document).on('click', '#DeleteBtnID', function (event) {
    console.log('delegated Test');
});


$('#DeleteBtnID').on('click', function (event) {
    console.log('Test');
});
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>


<button type="button" class="btn btn-info btn-xs" data-toggle="modal" data-target="#myModal">Delete1</button>
<button type="button" class="btn btn-info btn-xs" data-toggle="modal" data-target="#myModal">Delete2</button>
<button type="button" class="btn btn-info btn-xs" data-toggle="modal" data-target="#myModal">Delete3</button>
<!-- Modal -->
<div id="myModal" class="modal fade" role="dialog">
    <div class="modal-dialog modal-sm">

        <!-- Modal content-->
        <div class="modal-content">
            <div class="modal-header btn-warning" style="font-weight:bold;color:white;">
                <button type="button" class="close" data-dismiss="modal">&times;</button>
                <h5 class="modal-title modal-sm">Delete Warning</h5>
            </div>
            <div class="modal-body">
                <p>Click 'Delete' to <strong>parmenently</strong> delete this record. Click 'Cancel' to cancel your action.</p>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-danger" id="DeleteBtnID" value="@item.id" data-dismiss="modal">Delete</button>
                <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
            </div>
        </div>
    </div>
</div>
gaetanoM
  • 41,594
  • 6
  • 42
  • 61
  • As you can see in my code, the `Delete` buttons that trigger the model are also outside the `Modal`. And, in your code, as well, all your 3 buttons have exactly the same attributes\values. So, I maybe not understanding something in your code. Where is the uniqueness? Can you please explain? – nam Apr 14 '17 at 19:17
  • That makes sense. But then how do I pass the Primary key value to the modal's delete button? Being outside the table will cause the modal's Delete button to not to recognize the attribute value `@item.id` of ` – nam Apr 14 '17 at 22:15
  • Your updated suggestion seems correct but for some reason, although the modal box shows up as expected, but `$('#myModal').on('show.bs.modal', function (e) { alert('Test' });` still does not trigger the `alert('Test')`. I'm using the latest version of Chrome that does not show any errors either. – nam Apr 15 '17 at 19:37
  • Snippet works as (when I click on `Delete` button in the Modal dialog for each delete) it displays: `Test: @item.id1, Test: @item.id2, Test: @item.id3` respectively. My Bootstrap files are the result of default installation by VS2015 at the time of project creation using the default `ASP.NET Core Web Application` template. On my project the version shown is Bottstrap 3.3.6. – nam Apr 17 '17 at 04:13
  • Yes I did. I think the issue has something to do with the me rendering the relevant html via ViewComponent (similar to Partial view) in my `jquery`. I noticed that when I use your html and jquery directly inside a view without using partial view it works fine on my `ASP.NET core` app. But if I'm using your same example in a partial view it does not work. Keep in mind that for partial view I have to use `DeleteBtnParentID` in your jquey since I've to use [Event Delegation](https://learn.jquery.com/events/event-delegation/). – nam Apr 17 '17 at 20:45
  • 1
    For reasons described in my comment above, I've created a separate post [here](http://stackoverflow.com/q/43459102/1232087) with your example.. – nam Apr 17 '17 at 20:46
0

you are trying to find DeleteBtnID on the first level under DeleteBtnParentID. try to use find instead, it will search all level that are under DeleteBtnParentID

 $('#DeleteBtnParentID').find("#DeleteBtnID").on('click', function (event) {
     alert('Test');
  });
Alen.Toma
  • 4,684
  • 2
  • 14
  • 31