220 likes | 389 Views
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. To be able to develop Views in Razor/HTML syntax to suit application needs for MVC ASP.NET applications
E N D
COMPSCI 280 S2 2014Enterprise Software Development Further exploring the View aspect of MVC Jim Warren, jim@cs.auckland.ac.nz
Today’s learning objectives • 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 • 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
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 • E.g. the implicit ending to a razor expression within HTML • Intelli-sense • And no new syntax to learn – it’s C# or VB • 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
Note that we explicitly chose the Razor rather than ASPX view syntax when we created the MVC project • Well, it was the default COMPSCI 280
Creating the Edit/Update form • We’re aiming for something like this screen • 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
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> COMPSCI 280
Making this view into what we want • First, I’ll need to associate it with the Model: • Then I get into the real ‘payload’ of the form: @model MvcLetsConnect.Models.Employee @{ ViewBag.Title = "Edit"; ... Actually I could’ve gotten this auto-generated if I’d ticked ‘Create a strongly typed view’ when adding the class (I’d then get a list of classes in the Model) ... <h1>@ViewBag.Title.</h1> <h2>@ViewBag.Message</h2> @using (Html.BeginForm()) { @Html.ValidationSummary(true) <fieldset> <legend>Employee</legend> <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> ... I can put in various content using Razor expression, like items from the ViewBag into the HTML heading, or accessing the system time Then I create this Razor code block with the various @Html expressions in it COMPSCI 280
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) 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 <form action="demo_form.asp" method="get"> First name: <input type="text" name="fname"><br> Last name: <input type="text" name="lname"><br> <input type="submit" value="Submit"> </form> <input> tags say to render input fields for the user. The ‘type’ attribute says what sort of data it is 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 COMPSCI 280
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 • 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 • HTML5 also greatly expands the input tag attributes for content validation • 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
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. • 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
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 • 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 <label for="male">Male</label> <input type="radio" name="sex" id="male" value="male"> <label for="female">Female</label> <input type="radio" name="sex" id="female" value="female"><br> COMPSCI 280
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 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
What about the date? • Let’s go back and look at an revision of our Model [Table("employee")] public class Employee { [Key] public intIDnum { get; set; } [Required] public string Surname { get; set; } [Display(Name="Given Names")] public string GivenNames { get; set; } [Display(Name = "Date of Birth")] [DataType(DataType.Date)] [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)] public DateTimeDateOfBirth { get; set; } } The [Required] decorator caused VS to include that jQuery validation in the HTML (as per previous slide) The Name parameter on [Display] decides the field’s label for the HTML form 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-MM-dd” 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!). Cap “MM” for month because lower “mm” is for minutes in DateTime format strings COMPSCI 280
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> <p> <input type="submit" value="Save it" /> </p> </fieldset> } <div> @Html.ActionLink("Back to List", "Index") </div> @* creates data validation scripts and some internationalisation stuff as well *@ @section Scripts { @Scripts.Render("~/bundles/jqueryval") } Actually the Razor for DateOfBirth (and GivenNames, too) is really similar to the Razor for Surname. The difference is conveyed by the Model Link back to home page – essentially canceling the update Razor’s block comment chars Includes the jQuery COMPSCI 280
Date HTML Reasonably pretty date picker in Chrome Note that yyyy-MM-dd format for the initial value Similar use of ‘data-’ attributes to communicate to the jQuery as we saw to implement Surname’s validation and message COMPSCI 280
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 COMPSCI 280
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()</text>,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> COMPSCI 280
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"), grid.Column(format:@<text>@item.DateOfBirth.ToShortDateString()</text>,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> Also in Site.css we need to define what we want the style and rowStyle to mean .centercol { text-align: center;} .oddrow { background-color: #a6dbed;} (the dot in CSS means it applies to anything of that class) 2. 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) 1. COMPSCI 280
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=“site-title” 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; } COMPSCI 280
A bit more on that DataOfBirth column • We don’t want the time on the DateOf Birth so we can use a Razor expression • Again we see the WebGrid’s magic ‘item’ object • 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) • See http://msdn.microsoft.com/en-us/library/dd264739.aspx ... grid.Column(format:@<text>@item.DateOfBirth.ToShortDateString()</text>,header:"Date of Birth",style:"centercol"), ... COMPSCI 280
Where we’re up to • You should now feel you can bend the default MVC application to your needs • Now… • You should be very focused on Assignment 2 • Subsequent lectures will fill in further techniques and more in-depth explanation of some of the C# language features COMPSCI 280