Using Bootstrap Modal with a foreach loop

  • I have a foreach loop which loops through my documents from a database, it only pulls in the IMAGES then I have a 4 images per row on my page, I would like to click one it opens a Modal with the image, click another same again. So i have this setup:

    @foreach (var item in Model.DocumentList)
        // Below I am currently using just a ID for modal (which i know is wrong)
        <div class="col-lg-3 col-md-4 col-xs-6 thumb">
            <a class="thumbnail" data-toggle="modal)" data-target="#myModal" title="@item.FileDescription">
                @Html.DocumentUrl(item.FileUrl, false)
            <span class="col-xs-12" style="text-align:center;">@item.CreatedDate.ToShortDateString()</span>
        <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
            <div class="modal-dialog">
                <div class="modal-content">
                    <div class="modal-header">
                        <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
                        <h4 class="modal-title" id="myModalLabel">Uploaded - @item.CreatedDate.ToShortDateString()</h4>
                    <div class="modal-body">
                        @Html.DocumentUrl(item.FileUrl, true)
                        <div class="row">
                            <div class="col-md-12">
                    <div class="modal-footer">
                        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
                        <button type="button" class="btn banner-background white-text">Download</button>

    I can see why the data-target id modal isn't working, when I hover it works i see the different title, however when I click the img even if I click img 4 it just shows the first img, first title etc. How can I do this so it works with each item properly? Also changing id modal to a class doesn't help either.

    In your particular solution you are using the same modal snippet for each item in your Model.DocumentList. For example:

    <a class="thumbnail" data-toggle="modal)" data-target="#myModal" title="@item.FileDescription"> @Html.DocumentUrl(item.FileUrl, false)</a>

    If always toggling the modal with an id of myModal. The first modal the page renders is winning out whenever you click the DocumentUrl. You are essentially creating 4 of the same modal with the only differentiator being the Url and Item, and because of this you're experiencing the strange behavior.

    To accomplish what you're trying to accomplish (at least in the way that you are approaching the problem), you could utilize a unique id on each modal by concatenating the id with a value off of your item. For example:

    <a class="thumbnail" data-toggle="modal)" data-target="#myModal-@(" title="@item.FileDescription"> @Html.DocumentUrl(item.FileUrl, false)</a>
    <div class="modal fade" id="myModal-@(" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"><!-- modal body etc --></div>

    By using the id off of the Model you will generate a unique HTML modal for each item in your Model.Document list and a unique data-target to match. This would accomplish what you're trying to do by using 4 seperate modals.

    A small alternative suggestion if you feel like refactoring this later. You could always load a single modal on the page and use JavaScript to modify the modal's body. This would clean up the HTML by using only a single modal rather than 4 seperate modal snippets. You would load an empty modal in your page for example and use the loop to generate the links with the proper data-atteributes. This way your code is DRY and your HTML is clean.

    Happy Coding!