Search code examples
asp.net-corebootstrap-modalcrudmaster-detail

Master Detail not showing details table in modal popup - ASP.NET Core


I am doing CRUD operations on a Master Detail models Team and TeamMember using modal popup. I followed this post to perform the Create operation and it is ok, now i am doing the Detail operation:

TeamController:

public IActionResult Detail(int id)
    {
        Team team = _dbcontext.Team
            .Include(a => a.TeamMembers)
            .Where(e => e.TeamId == id).FirstOrDefault();
        return PartialView("_DetailTeamPartialView", team);
    }

Index.cshtml detail button:

<button class="btn btn-success" data-toggle="modal" data-target="@("#DetailTeam-"+item.TeamId)" data-url="@Url.Action($"Detail/{item.TeamId}")">Detail</button>
@await Html.PartialAsync("_DetailTeamPartialView", item)

_DetailTeamPartialView.cshtml:

    @model Team

@{
    ViewData["Title"] = "_DetailTeamPartialView";
}
<div class="modal fade" role="dialog" tabindex="-1" id="@("DetailTeam-"+Model.TeamId)" aria-labelledby="DetailTeamLabel" aria-hidden="true" data-backdrop="static" data-keyboard="false">
    <div class="modal-dialog modal-xl modal-dialog-scrollable" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title">Detail Team</h5>
                <button type="button" class="close" data-dismiss="modal" aria-label="Close" onclick="javascript:window.location.reload()">
                    <span aria-hidden="true">&times;</span>
                </button>
            </div>
            <div>
                <dl class="row">
                    <dt class="col-sm-2">
                        @Html.DisplayNameFor(model => model.TeamName)
                    </dt>
                    <dd class="col-sm-10">
                        @Html.DisplayFor(model => model.TeamName)
                    </dd>
                    .......

                    <dt class="col-sm-2">
                        @Html.DisplayNameFor(model => model.TeamMembers)
                    </dt>
                    <dd class="col-sm-10">
                        <table class="table table-bordered table-sm">
                            <thead>
                                <tr>
                                    <th>Member name</th>
                                    <th>Birth date</th>
                                </tr>
                            </thead>
                            <tbody>
                                @for (int i = 0; i < Model.TeamMembers.Count; i++)
                                {
                                    <tr>
                                        <td>
                                            <input asp-for="@Model.TeamMembers[i].MemberName" class="form-control-plaintext" readonly />
                                        </td>
                                        <td>
                                            <input asp-for="@Model.TeamMembers[i].BirthDate" class="form-control-plaintext" readonly />
                                        </td>
                                        
                                    </tr>
                                }
                                
                            </tbody>
                        </table>
                    </dd>
                </dl>
                
            </div>           
        </div>
    </div>
</div>

This code displays only team details and doesn't show the TeamMember details. Any help??

EDIT these are the classes:

public class Team
{
    
    [Key]
    public int TeamId { get; set; }
   
    [Required]
    public string TeamName { get; set; }
    
    public virtual List<TeamMember> TeamMembers { get; set; } = new List<TeamMember>();       
}
public class TeamMember
{
    

    [Key]
    public int TeamMemberId { get; set; }
    
    [Required]
    public string MemberName{ get; set; }
    [Required]
    public DateTime BirthDate{ get; set; }
    
    [ForeignKey("TeamId")]
    public int TeamId { get; set; }

    public virtual Team Team{ get; set; }        
}

'Model.TeamMembers.Count' in '@for (int i = 0; i < Model.TeamMembers.Count; i++)' return 0 why??


Solution

  • Master Detail not showing details table in modal popup - ASP.NET Core

    I have gone through your shared code snippet between the line altough, you haven't shared your index page's code that certainly playing important role here. Nontheless, I tried to visualize what you are trying to achieve.

    Expected Behaviour:

    enter image description here

    From the shared code, I have managed to build above output therefore, the expected behaviour might be while clicking on details button on the team's list which is the index page should display the details list of all the team member of that particular team. If that is the business scenario, then I would say, your approach were wrong and you are doing mess of course here thus, follow the steps below which will help to resolve your issue.

    Database:

    enter image description here

    Note: Models would be same as yours. So not repeating that part.

    Controller:

    public class TeamController : Controller
        {
            private readonly ApplicationDbContext _context;
            private readonly IWebHostEnvironment _environment;
    
    
            public TeamController(IWebHostEnvironment environment, ApplicationDbContext context)
            {
                _environment = environment;
                _context = context;
            }
            public IActionResult Index()
            {
                var teamList = _context.Teams.Include(a => a.TeamMembers).ToList();
                return View(teamList);
            }
            
        }
    

    Note: You are doing the mess here as you are using another details action for the _DetailTeamPartialView which is complete Irelevant here. Only Index action is capable here what you are trying to achieve. Just need to use Include(a => a.TeamMembers) which the action.

    View Of Index()

    @model IEnumerable<DotNet6MVCWebApp.Models.Team>
    
    @{
        ViewData["Title"] = "Index";
    }
    
    <table class="table">
        <thead>
            <tr>
                <th>
                    @Html.DisplayNameFor(model => model.TeamId)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.TeamName)
                </th>
                <th>
                    Member Details
                </th>
            </tr>
        </thead>
        <tbody>
            @foreach (var item in Model)
            {
                <tr>
                    <td>
                        @Html.DisplayFor(modelItem => item.TeamId)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.TeamName)
                    </td>
                    <td>
                        <button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="@("#DetailTeam-"+item.TeamId)">Detail</button>
                        @await Html.PartialAsync("_DetailTeamPartialView", item)
                    </td>
         
                </tr>
               
               
            }
        </tbody>
    </table>
    

    _DetailTeamPartialView

    Though, your _DetailTeamPartialView is alrigh and no vital issue has not seen,

    @model DotNet6MVCWebApp.Models.Team
    
    @{
        ViewData["Title"] = "_DetailTeamPartialView";
    }
    <div class="modal fade" role="dialog" tabindex="-1" id="@("DetailTeam-"+Model.TeamId)" aria-labelledby="DetailTeamLabel" aria-hidden="true" data-backdrop="static" data-keyboard="false">
        <div class="modal-dialog modal-xl modal-dialog-scrollable" role="document">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title">Detail Team</h5>
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close" onclick="javascript:window.location.reload()">
                        <span aria-hidden="true">&times;</span>
                    </button>
                </div>
                <div>
    
                    <dl class="row">
                        <div style="margin-left:10px">
                            <dt class="col-sm-2">
                                @Html.DisplayNameFor(model => model.TeamName)
                            </dt>
                            <dd class="col-sm-10">
                                @Html.DisplayFor(model => model.TeamName)
                            </dd>
                            .......
    
                            <dt class="col-sm-2">
                                @Html.DisplayNameFor(model => model.TeamMembers)
                            </dt>
                            <dd class="col-sm-10">
                                <table class="table table-bordered table-sm">
                                    <thead>
                                        <tr>
                                            <th>Member name</th>
                                            <th>Birth date</th>
                                        </tr>
                                    </thead>
                                    <tbody>
                                        @for (int i = 0; i < Model.TeamMembers.Count; i++)
                                        {
                                            <tr>
                                                <td>
                                                    <input asp-for="@Model.TeamMembers[i].MemberName" class="form-control-plaintext" readonly />
                                                </td>
                                                <td>
                                                    <input asp-for="@Model.TeamMembers[i].BirthDate" class="form-control-plaintext" readonly />
                                                </td>
    
                                            </tr>
                                        }
    
                                    </tbody>
                                </table>
                            </dd>
                        </div>
    
                    </dl>
    
                </div>
            </div>
        </div>
    </div>
    

    Output

    enter image description here

    Takeaways:

    As you are using HTML Tag helper class that is @await Html.PartialAsync("_DetailTeamPartialView", item) so you don't need to use below Detail action on your controller. Index action would handled the _DetailTeamPartialView autometically.

    public IActionResult Detail(int id)
        {
            Team team = _dbcontext.Team
                .Include(a => a.TeamMembers)
                .Where(e => e.TeamId == id).FirstOrDefault();
            return PartialView("_DetailTeamPartialView", team);
        }