Views
As you know an MVC model is concerned with displaying HTML
The required view pages are in the expected location Views/Photo (MVC Views Folder under Photo)
These are Razor pages (with .cshtml extension) named following the same conventions as those scaffolded by Visual Studio for CRUD operations
- Create creates a new photo record which also initiates image processing operations
- Delete removes a record and all versions of the image file from the file system
- Details displays all the fields in the photo record and the image
- Edit allows you to change values of a limited subset of the record (those that are not autogenerated or programmatically changed)
- Index is the gallery interface
Plus one called Metadata which displays Image metadata stored in the actual image
Create
@model Ben.Models.PhotoCreateViewModel
<link href="~/Content/FileUpload.css" rel="stylesheet" />
<link href="~/Content/jquery.modal.css" rel="stylesheet" />
<script src="~/Scripts/jquery.modal.min.js"></script>
@{
ViewBag.Title = "Create Photo";
}
<h2>Create a Photo</h2>
@using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
<label class="control-label col-md-2" for="Description">Description <span style="font-size:large; color:indianred;">*</span></label>
<div class="col-md-10">
@Html.EditorFor(model => model.Description, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Description, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Creator, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Creator, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Creator, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Keywords, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Keywords, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Keywords, "", new { @class = "text-danger" })
</div>
</div>
<div class="file-upload col-sm-6" style="">
<div class="file-select">
<div class="file-select-button" id="fileName">Add Image <span class="glyphicon glyphicon-camera" style=" font-size:medium; "></span></div>
<input id="UploadedFile" name="UploadedFile" class="custom-file-input" type="file"
data-val="true" data-val-required="The UploadedFile field is required." aria-describedby="UploadedFile-error" aria-invalid="true">
<label class="custom-file-label">Choose Image...</label>
</div>
<span class="text-danger field-validation-error" data-valmsg-for="UploadedFile" data-valmsg-replace="true"><span id="UploadedFile-error"></span></span>
</div>
<img id="file-image" src="#" alt=" " class="thumb-100" style=" height: 100px; width: auto; ">
<p> </p>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
<div id="progress" class="modal" style="text-align:center;">
<img src="~/images/loader4.gif" style=" margin-left: auto; margin-right: auto;" />
</div>
}
<p>
@Html.ActionLink("Back to List", "Index")
</p>
<script>
// validate image file extension and display local file
$(document).ready(function () {
$('.custom-file-input').on("change", function () {
var fileName = $(this).val().split("\\").pop();
var isGood = (/\.(?=gif|jpg|png|jpeg)/gi).test(fileName);
if (isGood) {
document.getElementById('file-image').src = URL.createObjectURL(event.target.files[0]);
} // TODO raise error
$(this).next('.custom-file-label').text(fileName);
});
});
// disable the submit button to stop trigger happy users making multiple posts
$(document).on('submit', 'form', function () {
var buttons = $(this).find('[type="submit"]');
if ($(this).valid()) {
buttons.each(function (btn) {
$(buttons[btn]).prop('disabled', true);
$('#progress').modal()({
escapeClose: false,
clickClose: false,
showClose: false
}); // show uncloseable modal popup with loading spinner
});
} else {
buttons.each(function (btn) {
$(buttons[btn]).prop('disabled', false);
});
}
});
</script>
Delete
@model Ben.Models.Photo
@{
ViewBag.Title = "Delete";
}
<h2>Delete</h2>
<h3 style="color:red;">Are you sure you want to delete this?</h3>
<div>
<img src="~/P/photos/zoom/@Model.Id.ToString()@(".jpg")"
class="img-responsive"
alt="" /> <hr />
<dl class="dl-horizontal">
<dt>
@Html.DisplayNameFor(model => model.Creator)
</dt>
<dd>
@Html.DisplayFor(model => model.Creator)
</dd>
<dt>
@Html.DisplayNameFor(model => model.SourceFilename)
</dt>
<dd>
@Html.DisplayFor(model => model.SourceFilename)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Description)
</dt>
<dd>
@Html.DisplayFor(model => model.Description)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Keywords)
</dt>
<dd>
@Html.DisplayFor(model => model.Keywords)
</dd>
<dt>
@Html.DisplayNameFor(model => model.AspNetUserID)
</dt>
<dd>
@Html.DisplayFor(model => model.AspNetUserID)
</dd>
<dt>
@Html.DisplayNameFor(model => model.ForeignKeyTable)
</dt>
<dd>
@Html.DisplayFor(model => model.ForeignKeyTable)
</dd>
<dt>
@Html.DisplayNameFor(model => model.DateCreated)
</dt>
<dd>
@Html.DisplayFor(model => model.DateCreated)
</dd>
<dt>
@Html.DisplayNameFor(model => model.DateSaved)
</dt>
<dd>
@Html.DisplayFor(model => model.DateSaved)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Flag)
</dt>
<dd>
@Html.DisplayFor(model => model.Flag)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Count)
</dt>
<dd>
@Html.DisplayFor(model => model.Count)
</dd>
<dt>
@Html.DisplayNameFor(model => model.GUID)
</dt>
<dd>
@Html.DisplayFor(model => model.GUID)
</dd>
</dl>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<p class="form-actions no-color">
<input type="submit" value="Delete" class="btn btn-warning" /> |
@Html.ActionLink("Back to List", "Index")
</p>
}
</div>
Details
@model Ben.Models.Photo
@{
ViewBag.Title = "Details " + Model.Description;
}
<h2>@ViewBag.Title</h2>
<div>
<img src="~/P/photos/zoom/@Model.Id.ToString()@(".jpg")"
class="img-responsive"
alt="" /> <hr />
<dl class="dl-horizontal">
<dt>
@Html.DisplayNameFor(model => model.Description)
</dt>
<dd>
@Html.DisplayFor(model => model.Description)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Creator)
</dt>
<dd>
@Html.DisplayFor(model => model.Creator)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Keywords)
</dt>
<dd>
@Html.DisplayFor(model => model.Keywords)
</dd>
<dt>
@Html.DisplayNameFor(model => model.SourceFilename)
</dt>
<dd>
@Html.DisplayFor(model => model.SourceFilename)
</dd>
<dt>
<label class="control-label col-md-2" for="AspNetUserID">UserID</label>
</dt>
<dd>
@Html.DisplayFor(model => model.AspNetUserID)
</dd>
<dt>
@Html.DisplayNameFor(model => model.ForeignKeyTable)
</dt>
<dd>
@Html.DisplayFor(model => model.ForeignKeyTable)
</dd>
<dt>
@Html.DisplayNameFor(model => model.DateCreated)
</dt>
<dd>
@Html.DisplayFor(model => model.DateCreated)
</dd>
<dt>
@Html.DisplayNameFor(model => model.DateSaved)
</dt>
<dd>
@Html.DisplayFor(model => model.DateSaved)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Flag)
</dt>
<dd>
@Html.DisplayFor(model => model.Flag)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Count)
</dt>
<dd>
@Html.DisplayFor(model => model.Count)
</dd>
@if (User.IsInRole("Admin"))
{
<dt>
@Html.DisplayNameFor(model => model.GUID)
</dt>
<dd>
@Html.DisplayFor(model => model.GUID)
</dd>
}
</dl>
</div>
<p>
@Html.ActionLink("Edit", "Edit", new { id = Model.Id }) |
@Html.ActionLink("Back to List", "Index")
</p>
Edit
@model Ben.Models.Photo
@{
ViewBag.Title = "Edit " + Model.Description;
}
<link href="~/Content/jquery.modal.css" rel="stylesheet" />
<script src="~/Scripts/jquery.modal.min.js"></script>
<h2>@ViewBag.Title</h2>
<div style="width:300px;">
<a href="#ex_@Model.Id" class="open-modal" rel="modal:open">
<img src="~/P/photos/zoom/@Model.Id.ToString()@(".jpg")"
class="img-responsive"
alt="" />
</a>
<div id="ex_@Model.Id" class="modal">
<img src="~/P/photos/@Model.Id.ToString()@(".jpg")"
alt="" class="img-responsive" />
<div class="comment more">
@Model.Description
</div>
<a href="#" rel="modal:close">Close</a>
<span style="float:right;">
<a href="~/photos/details/@Model.Id" title="info"><span class="glyphicon glyphicon-info-sign"></span></a>
@if (User.IsInRole("Admin"))
{
<a href="~/photos/edit/@Model.Id" title="edit"><span class="glyphicon glyphicon-edit"></span></a>@:
<a href="~/photos/delete/@Model.Id" title="info"><span class="glyphicon glyphicon-warning-sign"></span></a>
}
</span>
</div>
</div>
<div class="row photo-item">
<div class="col-sm-6" style="">
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@Html.HiddenFor(model => model.Id)
<div class="form-group">
<label class="control-label col-md-4" for="Description">Description <span style="font-size:large; color:indianred;">*</span></label>
<div class="col-md-8">
@Html.EditorFor(model => model.Description, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Description, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Creator, htmlAttributes: new { @class = "control-label col-md-4" })
<div class="col-md-8">
@Html.EditorFor(model => model.Creator, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Creator, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Keywords, htmlAttributes: new { @class = "control-label col-md-4" })
<div class="col-md-8">
@Html.EditorFor(model => model.Keywords, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Keywords, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Flag, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
<div class="checkbox">
@Html.EditorFor(model => model.Flag)
@Html.ValidationMessageFor(model => model.Flag, "", new { @class = "text-danger" })
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
</div>
<div class="col-md-6" style="">
<dl>
<dt>
@Html.DisplayNameFor(model => model.SourceFilename)
</dt>
<dd>
@Html.DisplayFor(model => model.SourceFilename)
</dd>
<dt>
@Html.DisplayNameFor(model => model.AspNetUserID)
</dt>
<dd>
@Html.DisplayFor(model => model.AspNetUserID)
</dd>
<dt>
@Html.DisplayNameFor(model => model.ForeignKeyTable)
</dt>
<dd>
@Html.DisplayFor(model => model.ForeignKeyTable)
</dd>
<dt>
@Html.DisplayNameFor(model => model.DateCreated)
</dt>
<dd>
@Html.DisplayFor(model => model.DateCreated)
</dd>
<dt>
@Html.DisplayNameFor(model => model.DateSaved)
</dt>
<dd>
@Html.DisplayFor(model => model.DateSaved)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Count)
</dt>
<dd>
@Html.DisplayFor(model => model.Count)
</dd>
</dl>
</div>
</div>
<p>
@Html.ActionLink("Back to List", "Index")
</p>
Index
@using PagedList
@model IPagedList<Ben.Models.PhotoListViewModel>
@{
ViewBag.Title = "Photos";
}
<link href="~/Content/jquery.modal.css" rel="stylesheet" />
<script src="~/Scripts/jquery.modal.min.js"></script>
<div style="color:white;background-color:black;">
<h1>Photo Gallery</h1>
</div>
<div style=" padding:10px; clear:both; ">
<form method="get" action="@Url.Action("Index")" data-ben-ajax="true" data-ben-target="#downloadlist">
<input type="search" name="SearchTerm" data-ben-autocomplete="@Url.Action("Autocomplete")" class="clearable" style="background-color:white;color:black" />
<input type="submit" value="search" class="ben-btn-default" />
@if (User.IsInRole("Admin"))
{ // bring the next three lines into this code block if you want to limit access to create
}
<span style=" display:inline-block; float:right; clear:both; ">
@Html.ActionLink("show all", "Index", "", new { @class = "ben-btn-default" }) @Html.ActionLink("New", "Create", "", new { @class = "ben-btn-default" })
</span>
</form>
</div>
@Html.Partial("_PhotosPartial", Model)
Metadata
@model Ben.Models.Photo
@using Ben.Classes;
@{
ViewBag.Title = "Image Metadata: " + Model.Description;
}
<h1>@ViewBag.Title</h1>
@{string filename = "/p/photos/" + Model.Id + ".jpg"; }
<img src="@filename" />
@{
Ben.Classes.Jpeg metadata = new Ben.Classes.Jpeg(filename);
Dictionary<string, object> myDictionary = metadata.ClassPropertiesToDictionary();
<table id="pagedTable">
<thead>
<tr>
<th>Name</th>
<th>Value</th>
</tr>
</thead>
@foreach (KeyValuePair<string, object> entry in myDictionary)
{
<tr>
<td>@entry.Key.ToString()</td>
<td>@entry.Value.IsNull("value not set").ToString()</td>
</tr>
}
</table>
}
<p>
@Html.ActionLink("Edit", "Edit", new { id = Model.Id }) |
@Html.ActionLink("Back to List", "Index")
</p>
Next >>>