COMPSCI 280 S2 2014 Enterprise Software Development Further exploring the View aspect of MVC Jim Warren, jim@cs.auckland.ac.nz Today’s learning objectives 2 To be able to develop Views in Razor/HTML syntax to suit application needs for MVC ASP.NET applications Including development of forms for interactive data collection from the user This requires adequate understanding of the interaction of the MVC elements and HTML, CSS and JavaScript libraries COMPSCI 280 ASP, ASP.NET Properly, what we’re learning to do here is create ASP.NET MVC 4 Web Applications using the Razor view syntax ASP.NET is an open source server-side Web application framework designed for Web development to produce dynamic Web pages Developed by Microsoft to allow programmers to build dynamic websites, Web applications and Web services By being ‘server-side’, we mean the server does most of the work using the code we write and serves up a processed result to the user’s browser 3 Unlike, say, Javascript or a Java Applet, which can be processed client-side by the browser software itself ASP.NET is the successor to Active Server Pages (ASP) technology, which was Microsoft’s first server-side script engine for dynamically generated web pages (originally release around 1996) COMPSCI 280 Handout 04 Razor syntax Razor is an ASP.NET programming syntax used to create dynamic web pages with the C# or Visual Basic .NET programming languages It’s relatively new (released with VS 2010 in January 2011) Starts with @ character as compared to the <% %> brackets used for ASP and ASP.NET Designed to give smoother integration of the server-side code into the HTML And no new syntax to learn – it’s C# or VB 4 E.g. the implicit ending to a razor expression within HTML Intelli-sense Which doesn’t mean that you don’t need to get used to a lot of new objects and the coding style – but it’s not another ‘language’ per se COMPSCI 280 Handout 04 Note that we explicitly chose the Razor rather than ASPX view syntax when we created the MVC project 5 Well, it was the default COMPSCI 280 Handout 04 Creating the Edit/Update form We’re aiming for something like this screen 6 We need to create a new .cshtml page We need to populate it with an HTML form containing HTML fields for data entry and an HTML submit button (labelled ‘Save it’ in this example) It also has that ‘Back to List’ hyperlink to return to the index/home page COMPSCI 280 Handout 04 Making the new page in the View In the VS Solution Explorer @{ } Right-click the Home subdirectory of the View And Add a new View Call it ‘Edit’ The defaults are fine and should give you something like: ViewBag.Title = "Edit"; <h2>Edit</h2> 7 COMPSCI 280 Handout 04 Making this view into what we want First, I’ll need to associate it with the Model: @model MvcLetsConnect.Models.Employee @{ ViewBag.Title = "Edit"; ... Actually I could’ve gotten this autogenerated if I’d ticked ‘Create a strongly typed view’ when adding the class (I’d then get a list of classes in the Model) Then I get into the real ‘payload’ of the form: ... I can put in various content using Razor <h1>@ViewBag.Title.</h1> expression, like items from the ViewBag into the <h2>@ViewBag.Message</h2> HTML heading, or accessing the system time @using (Html.BeginForm()) { @Html.ValidationSummary(true) Then I create this Razor code block <fieldset> with the various @Html <legend>Employee</legend> expressions in it <p>The time is @DateTime.Now</p> @Html.HiddenFor(model => model.IDnum) <div class="editor-label"> @Html.LabelFor(model => model.Surname) </div> <div class="editor-field"> @Html.EditorFor(model => model.Surname) @Html.ValidationMessageFor(model => model.Surname) </div> ... 8 COMPSCI 280 Handout 04 HTML Forms Remember, the Razor code is there to create HTML So what sort of HTML am I aiming for? Well, a simple HTML form might look like this (from http://www.w3schools.com/tags/att_form_method.asp) <form action="demo_form.asp" method="get"> The action points to the server page that will ‘catch’ the result; if the method is “get” then the user can see the values they filled out as parameters – alternatively, the “post” method doesn’t show the parameters First name: <input type="text" name="fname"><br> Last name: <input type="text" name="lname"><br> <input type="submit" value="Submit"> </form> A type of “submit” indicates to render a special button; when the user presses it, the browser sends the form data to the action URL 9 COMPSCI 280 <input> tags say to render input fields for the user. The ‘type’ attribute says what sort of data it is Handout 04 HTML5 and JavaScript/jQuery HTML5 (the latest version) adds lots of input field types Color, date, datetime, email, month, number, range, search, tel, time, url, week These give the browser greater information about the input expectation (as compared to, say, “text”) and thus opportunity to give helpful input controls HTML5 also greatly expands the input tag attributes for content validation 10 E.g. to provide date and colour pickers, or to customize the keyboard on a mobile touch display for ease of entering an email or URL Including: min, max, step, required (see http://www.w3schools.com/tags/tag_input.asp) This reduces the need for the application developer to provide custom client side scripting (generally in the Javascript language) to support valid data entry COMPSCI 280 Handout 04 HTML5 and Javascript/jQuery (contd.) Before HTML5, to get a good user experience on an HTML form you’d typically use heaps of Javascript jQuery is a very widely used Javascript library to simplify client-side scripting It ships with Visual Studio You’ll find it in numerous .js files by looking under Scripts in Solution Explorer in your MVC project Some gets included in a default View’s HTML in MVC 4 <script src="/Scripts/jquery-1.8.2.js"></script> <script src="/Scripts/jquery.unobtrusive-ajax.js"></script> <script src="/Scripts/jquery.validate.js"></script>, etc. 11 Nonetheless, the trend with HTML5 is for the HTML to let the browser bear more of the validation and less to need to be specified with Javascript COMPSCI 280 Handout 04 More on tidy form HTML Good to use the <label> tag to produce captions for your input fields Not strictly necessary, but gives the browser more information <label <input <label <input 12 for="male">Male</label> type="radio" name="sex" id="male" value="male"> for="female">Female</label> type="radio" name="sex" id="female" value="female"><br> Using the label tags let the browser configure this radio button group, with the bonus that the clicking the ‘Male’ and ‘Female’ text will make a selection COMPSCI 280 Handout 04 Back to our Edit/Update screen What HTML does that Razor from slide 8 give us? Inspecting the Surname input in Chrome gives: Note the id parameter to the Edit handler in the Home controller is passed on the action URL, but the method is ‘post’ for the return payload of an updated instance of the Employee class object The primary key went in as a hidden field (we want to have the value, but not to edit it), but VS still mechanically added data validation for it 13 The ‘data-’ properties aren’t interpreted by the browser, but instead are used by jquery.validate.unobtrusive.js to dynamically make the ‘unobtrusive’ data-val-required message visible when the field is blank COMPSCI 280 Handout 04 What about the date? Let’s go back and look at an revision of our Model [Table("employee")] public class Employee { The [Required] decorator caused VS to [Key] include that jQuery validation in the public int IDnum { get; set; } HTML (as per previous slide) [Required] public string Surname { get; set; } The Name parameter on [Display(Name="Given Names")] [Display] decides the field’s public string GivenNames { get; set; } label for the HTML form [Display(Name = "Date of Birth")] [DataType(DataType.Date)] [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)] public DateTime DateOfBirth { get; set; } } Cap “MM” for month because lower “mm” is for minutes in DateTime format strings 14 With DateOfBirth, we use the decorators to say to treat its type as Date (i.e. we aren’t interested in the time-of-day component). The specific “yyyy-MMdd” format is required so that Chrome will pick up the current value for editing (even though Chrome then shows it in a different culture-sensitive format for the actual editing in the browser!). COMPSCI 280 Handout 04 The rest of Edit.cshtml ... <div class="editor-label"> @Html.LabelFor(model => model.DateOfBirth) </div> <div class="editor-field"> @Html.EditorFor(model => model.DateOfBirth) @Html.ValidationMessageFor(model => model.DateOfBirth) </div> Actually the Razor for <p> <input type="submit" value="Save it" /> DateOfBirth (and GivenNames, too) is </p> really similar to the </fieldset> Razor for Surname. The } difference is conveyed <div> by the Model @Html.ActionLink("Back to List", "Index") </div> Link back to home page – essentially canceling the update @* creates data validation scripts and some internationalisation stuff as well *@ Razor’s block comment chars @section Scripts { @Scripts.Render("~/bundles/jqueryval") Includes the jQuery } 15 COMPSCI 280 Handout 04 Date HTML Reasonably pretty date picker in Chrome Note that yyyy-MM-dd format for the initial value 16 COMPSCI 280 Similar use of ‘data-’ attributes to communicate to the jQuery as we saw to implement Surname’s validation and message Handout 04 What about the ‘pretty’ home page we saw last lecture? Custom logo Reasonable alignment choices and padding between columns Striped rows to aid reading across ‘Relevant’ content for the static part of the page 17 COMPSCI 280 Handout 04 Back to Index.cshtml ... @grid.GetHtml(columns: grid.Columns( grid.Column("IDnum","Employee ID",style: "centercol"), grid.Column("Surname","Last Name"), grid.Column("GivenNames","Given Names"), grid.Column(format:@<text>@item.DateOfBirth.ToShortDateString()</t ext>,header:"Date of Birth",style:"centercol"), grid.Column(header: "Edit", format: (item) => Html.ActionLink("Edit", "Edit", new { id=item.IDnum })) ),rowStyle: "oddrow") <p>Note: All edits must be approved by Human Resources (HR).</p> The ‘style’ parameter on the Column declaration just literally added a ‘class’ attribute to the HTML And the “oddrow” rowStyle parameter on the entire .GetHtml method did much the same thing, but this time the class declaration is only on every other <tr> 18 COMPSCI 280 Handout 04 Back to Index.cshtml (contd.) ... @grid.GetHtml(columns: grid.Columns( grid.Column("IDnum","Employee ID",style: "centercol"), grid.Column("Surname","Last Name"), grid.Column("GivenNames","Given Names"), 2. Also in Site.css we need to define what we want the style and rowStyle to mean grid.Column(format:@<text>@item.DateOfBirth.ToShortDateString()</t .centercol { text-align: ext>,header:"Date of Birth",style:"centercol"), .oddrow { grid.Column(header: "Edit", format: Html.ActionLink("Edit", "Edit", new ),rowStyle: "oddrow") center;} background-color: #a6dbed;} (the dot in=> CSS means it applies to (item) of that class) })) {anything id=item.IDnum <p>Note: All edits must be approved by Human Resources (HR).</p> 1. 19 Note that the right-hand side of Chrome’s inspect element shows the CSS that matches the item. For the table padding we just added some padding to the existing entry for ‘th’ (tag of a table header cell) in the Site.css file (under Content in VS Solution Explorer) COMPSCI 280 Handout 04 The logo The top-left “your logo here” item isn’t in Index.html, it’s part of the site’s master template _Layout.cshtml under Views/Shared in Solution Explorer But as it turns out, the .cshtml declares that area with class=“sitetitle” and the best way to put an image there is to edit (yet again!) the Site.css file .site-title a, .site-title a:hover, .site-title a:active { background: url(https://www.cs.auckland.ac.nz/global_css/images/logo.png) no-repeat top left; display: block; width: 150px; height: 80px; text-indent: -9999px; /* hides the link text */ color: #c8c8c8; outline: none; text-decoration: none; } 20 COMPSCI 280 Handout 04 A bit more on that DataOfBirth column We don’t want the time on the DateOf Birth so we can use a Razor expression ... grid.Column(format:@<text>@item.DateOfBirth.ToShortDateString()</t ext>,header:"Date of Birth",style:"centercol"), ... item is referenced in a format parameter expression ‘format:’ is followed by @<someHTMLtag> and ends at </someHTMLtag> The content inside gets put in each table row at that column In this case I mainly wanted to put in a Razor expression so I use the inert <text> tag Also note the approach of using name, rather than position, to indicate the optional arguments (format, header) 21 Again we see the WebGrid’s magic ‘item’ object See http://msdn.microsoft.com/en-us/library/dd264739.aspx COMPSCI 280 Handout 04 Where we’re up to You should now feel you can bend the default MVC application to your needs Now… 22 You should be very focused on Assignment 2 Subsequent lectures will fill in further techniques and more indepth explanation of some of the C# language features COMPSCI 280 Handout 04