BitLost
BitLost

Reputation: 185

Dynamically Set View Title

Not even sure if I asked the question the right way. Been looking at this for about an hour and its too simple to take to long. Trouble is I am too simple to know the answer or even how to correctly phrase a search to find the answer.

I have a history of jobs completed for a site set up.

Controller:

public async Task<IActionResult> JobSiteHistory(int id, int? page)
{
    var jobs = from j in _context.Job
        .Include(j => j.Site)
        .Include(j=>j.WaterBody)
        .Where(j=>j.Site.SiteID==id)
        .OrderByDescending(j=>j.BookingDate)
        select j;
    int pageSize = 9;
    return View(await PaginatedList<Job>.CreateAsync(jobs.AsNoTracking(), page ?? 1, pageSize));
}

This is returning the correct records all good.

I then have a view set up:

<h2> Site Jobs History</h2>

<p>
<a asp-action="Create">Add New Job</a>
</p>

<table class="table">
<thead>
    <tr>
        <th>Booking Date</th>
        <th>Job Number</th>
        <th>Waterbody</th>
        <th>Job Description</th>
        <th></th>
    </tr>
</thead>
<tbody>
@foreach (var item in Model) {
    <tr>
        <td>@Html.DisplayFor(modelItem => item.BookingDate)</td>
        <td>@Html.DisplayFor(modelItem => item.JobNumber)</td>
        <td>@Html.DisplayFor(modelItem => item.WaterBody.WBName)</td>
        <td>@item.JobDescription.Substring(0, Math.Min(item.JobDescription.Length, 30))</td>
        <td>
            <a asp-action="Edit" asp-route-id="@item.JobID">Edit</a> |
            <a asp-action="Details" asp-route-id="@item.JobID">Details</a> |
            <a asp-action="Delete" asp-route-id="@item.JobID">Delete</a> |
        </td>
    </tr>
  }
</tbody>
</table>

This is working wellish so far.

All I want to do is add something like:

@Html.DisplayFor(ModelItem=>item.Site.SiteName)

To the <h2> element. I know this wont work as typed, thanks for thinking that.

I just cant see a way to add it. I considered ViewData, but may be using it wrong as I cant get it to populate with SiteName.

Is there a way to do this or am I thinking all ass about as usual?

Upvotes: 0

Views: 114

Answers (1)

Jamadan
Jamadan

Reputation: 2313

The easiest change would be to use this:

<h2>@Html.DisplayFor(m => m[0].Site.SiteName);</h2>

Other options:

Is there any reason why you can't use the ViewBag? In controller:

ViewBag.SiteName = Site.name

In view:

<h2>@ViewBag.SiteName</h2>

If you must use your model to pass the whole site object then change your view model that you pass to the view.

You are currently returning a list of jobs with the site object for each job, but it looks like you only need it once.

I would change your view model to be something like:

public class SiteJobsHistoryModel
{
    public Site Site { get; set;}
    public PaginatedList<Job> Jobs { get; set; }
}

Then you don't have to include the site on your query, and just retrieve it once from the database:

var site = _context.Site.Single(j => j.Site.SiteID==id);
var jobs = from j in _context.Job
    //.Include(j => j.Site) -- this can be removed
    .Include(j=>j.WaterBody)
    .Where(j=>j.Site.SiteID==id)
    .OrderByDescending(j=>j.BookingDate)
    select j;

return View(new SiteJobsHistoryModel
    {
        Site = site,
        Jobs = await PaginatedList<Job>.CreateAsync(jobs.AsNoTracking(), page ?? 1, pageSize)
    });

Then for the title in <h2> tag you can use:

@Html.DisplayFor(ModelItem=>model.Site.SiteName)

And your foreach loop becomes:

@foreach (var item in Model.Jobs)

Upvotes: 1

Related Questions