Syllabus Schedule Project Labs Canvas Server Access CSS Tutorial Assignment 1 Assignment 2 Assignment 3 Assignment 4 Assignment 5 Assignment 6 Assignment 7 Assignment 8 Assignment 9

Assignment 4 - Web Forms, Layouts and Partial Views

  1. Snowboard - This is a two part exercise. The first part creates a form with validation. The second part retrieves the form data and displays an order confirmation. Steps:
    1. Model: The first part of this exercise builds upon BigWebForm from A03. The following instructions will focus on differences. Create a new model named SnowboardModel with the following properties:
      Property Type Validation
      Email string required
      ModelID string required
      ExperienceLevel string required
      DiscountStudent bool
      DiscountSenior bool
      DiscountGoldClub bool
      State string required
    2. Email and Model should use the Display attribute to provide user-friendly display names. Email should be validated using the EmailAddress Attribute validator as described by Ehsan.
    3. ViewModels: The snowboard order form will contain two dropdownlists and a list of RadioButtons. The data for these options will be stored in ViewModels.
    4. ListStateViewModel: Use the existing viewModel used in BigWebForm exercise, ListStateViewModel, Add an additional property "TaxRate" of type double. Add the tax rates for each state (state sales map.). A tax rate of 6.02% (Idaho) would be entered into the ViewModel as 0.0602.
    5. ListBoardsViewModel: Use ListStateViewModel from assignment 3 as a template. Copy it and Use "replace all" to replace "State" with "Boards"  Add a new property "ModelPrice" of type double. Populate the list with four snowboard models:
      ModelName ModelId Price
      Screamer $200 scr 200
      Terrorizer $300 ter 300
      Cliff Hopper $400 cli 400
      Low IQ $500 low 500
    6. ListExperienceViewModel: Again use ListStateViewModel as a template. Copy it and Use "replace all" to replace "State" with "Experience"  Edit it to populate the list as shown in the following table:
      ExperienceLevel Surcharge
      Beginner (no surcharge) 0.0
      Intermediate (10% surcharge) 0.1 
      Knuckle-dragger (20% surcharge) 0.2
      Out-of-control (30% surcharge) 0.3
    7. Controller: Create a new controller, similar to BigWebFormController.  
    8. View: Create a view using SnowboardModel. Add three using statements to reference the three view models created in the previous steps. Similar to BigWebForm you will need to manually change BoardModel and State from textboxes to dropdownlists. The radio buttonList can be generated from ListExperienceViewModel using the following Razor syntax:
       @foreach (Experience experience in ListExperiencesViewModel.ExperienceList)
               @Html.RadioButtonFor(m => m.ExperienceLevel, experience.ExperienceLevel)  @experience.ExperienceLevel 
    9. The two dropdown lists Model and State need the placeholders "Please select a model" and "Ship to State". The answer by jzm Add a placeholder to DropDownListFor shows how.
    10. The snowboard company has a business rule that disallows both student and senior discounts. Add a ValidationMessage control  below the three discount checkboxes. Validate the business rule in the controller by adding the following code to your the HttpPost ActionMethod:
      if (SbModel.DiscountSenior && SbModel.DiscountStudent)
          ModelState.AddModelError("Discounts", "Dude, you cannot take both student and senior discounts.");
      //return to view if any fields invalid
      if (!ModelState.IsValid) return View(SbModel);
    11. Test the page and check that the validation is working for all fields.
  2. Snowboard/OrderConfirmation - The second part of this exercise uses the data from the form to create an order confirmation.  Steps:
    1. The order confirmation displays the customer's order and calculates the total cost. Add a second model to SnowBoardModel.cs named CustomerOrderModel with the following properties:
        public string ModelName { get; set; }
        public double ModelPrice { get; set; }
        public double ExperienceSurchargePercent { get; set; }
        public double ExperienceSurchargeDollars { get; set; }
        public string DiscountsTaken { get; set; }
        public double DiscountsPercent { get; set; }
        public double DiscountDollars { get; set; }
        public double Subtotal { get; set; }
        public double TaxPercent { get; set; }
        public double TaxDollars { get; set; }
        public double TotalPrice { get; set; }
    2. Controller: The next step is to calculate the properties for the CustomerOrderModel. In the HttpPost ActionMethod instantiate an CustomerOrderModel object named custOrder.SnowBoardModel
    3. Model name and price: The order form returned ModelID (see image). To get the model name it is necessary to find the model in BoardModelList. This can be done using the Find method of List<> and Lambda syntax.  The syntax is:
      BoardModel boardModel = ListBoardsViewModel.ModelList.Find(m => m.ModelId == SbModel.ModelId);
      Note: The controller will need to access the SnowBoardViewModel so include the following at the top of the controller:

      using Mis324Assignments.ViewModels.ListBoardsViewModel;

    4. Assign the model name from boardModel to CustOrder with:
      custOrder.ModelName = boardModel.ModelName;
      Do the same for price.
    5. Experience: The ListExperiencesViewModel needs to be searched to find the surcharge percent.  Use Lambda syntax to search ExperienceList and return an experience object, similar to what you did for boardModel (above).
    6. Calculate ExperienceSurchargeDollars by multiplying Surcharge by Price.
    7. Discounts: The discount radio buttons have no data associated with them so check them individually and calculate the total discount. The discounts are 10% for students, 5% for seniors, and 8% for Gold Club. The C# syntax is similar to this:
      if (SbModel.DiscountStudent)
          custOrder.DiscountsTaken += "student, ";
          custOrder.DiscountsPercent += 0.1;
    8. The list of discounts could end with a comma. Trim the final comma with:

      if (custOrder.DiscountsTaken != null) custOrder.DiscountsTaken = custOrder.DiscountsTaken.TrimEnd(',', ' ');

    9. Calculate subtotal.  
    10. Tax: The StateList needs to be searched to find the tax rate. Use Lambda syntax to search StateList and return a state object, similar to what you did for boardModel (above).
    11. Calculate tax and total price. Double check that you have provided values for all of the properties in CustomerOrderModel.
    12. Return a view that calls an action method "OrderConfirmation" and passes custOrder model. Syntax:

      return View("OrderConfirmation", custOrder);

    13. In the Controller create a new action method named "OrderConfirmation" that takes CustomerOrderModel as an input parameter. It has only one statement:

      return View(custOrder);

    14. View: Create a view by right-clicking in the OrderConfirmation action method. Use template Details and model CustomerOrderModel.
    15. Test: Fill in the order form and submit it. You should see all the properties of the CustomerOrderModel and their values.
    16. Improve the appearance of the order confirmation by decorating the properties of CustomerOrderModel with user friendly names, currency formatting, and percentage formatting.The following snippet shows how to format as currency and percent.  Most of the properties will need formatting.
        [Display(Name = "Price")]
        public double ModelPrice { get; set; }
        [Display(Name = "Experience Surcharge %")]
        [DisplayFormat(DataFormatString = "{0:P0}")]  //percentage with no decimals
        public double ExperienceSurchargePercent { get; set; }
    17. Finally, copy the snowboard image tag from the sample and put it in your view. The appearance of the confirmation is pretty basic but it does contain the necessary information.
    18. Done!
  3. LayoutPartialViews - Layout pages allow us to define a layout for a site and use it with multiple views. Partial views are used for reusable page elements such as headers, footers, and menus. In this exercise you will create a layout page and three partial views. Steps:
    1. Overview: read the tutorials Layout View (we will not use RenderSection) and Partial View.
    2. Controller: Create a empty controller named LayoutPartialViewController.
    3. View: Create an index view with no model. Options: partial view unchecked, use layout page checked.
    4. _Layout: In the folder Views/shared is a file named "_Layout.cshtml." This is the default layout you have been using on previous exercises.  Copy it to your Views/LayoutPartialViews folder. 
    5. _ViewStart: In the top-level folder for your MVC project is a file named _ViewStart.cshtml. Copy this file into Views/LayoutPartialViews folder. Edit the copy to point to the Layout page created in the previous step.
    6. Test: Make sure that the index page is using your new layout page. Make an edit to Views/LayoutPartialView/_Layout and open the index view in a browser. Make sure that your edit is visible.
    7. Create three partial views: _header, _footer, and _leftMenu. Add some text to each one for testing purposes.
    8. _Layout: Replace the HTML div tags with the following:
          <div class="container body-content">
              <div class="row">
                  <div class="col-md-12">
              <div class="row">
                  <div class="col-md-3">
                  <div class="col-md-9">
                      <h2>Layout and Partial Views</h2>
              <div class="row">
                  <div class="col-md-12">
    9. Controller: _leftMenu contains content generated in the controller. We use a for loop to generate the letters A-Z  Add the following action handler to the controller:
              // GET: PartialView
              public ActionResult _leftMenu()
         = "<ul class='alphaList'>\n";
                  for (int i = 65; i <= 90; i++)
                      char c = (char) i;
                      string relativePath = Url.Content("~/LayoutPartialView/ShowImage/"); 
             += "<a href='" + relativePath + c + "'><div>" + c + "</div></a>\n ";
         += "</ul>";
                  return PartialView();
    10. _leftMenu.cshtml: Add to display the anchor tags generated in the previous step. Use @Html.Raw() to prevent the HTML tags from being encoded.
    11. CSS: Use the CSS from the sample site or write your own.  The link to LayoutExample.css is visible in the source code. (to copy the CSS click "view source" in the browser and click on the LayoutExample.css link). Create a new .css file in your Content folder and paste in the css. Add the following to your layout page:
                                  <link href="~/Content/layoutExample.css" rel="stylesheet" />
      (the tilde ~ points to the root of your application).
    12. ShowImage: Create a action method in the controller named ShowImage. It gets the character from the query string and puts it into the ViewBag:
              public ActionResult ShowImage(string id)
                  ViewBag.displayChar = id;
                  return View();
    13. ShowImage.cshtml: Create the view and display the appropriate image:
          <img src='' />
    14. Test!

Submission instructions: Submit assignments via the Canvas course management system. Submit the full URL for each exercise in the assignment, listing the URLs in the same order that they are listed in the assignment. To minimize typos in URLs it is strongly recommended that you copy the URLs from the address bar of the browser rather than trying to type them. Incorrect URLs will not be graded and no credit will be given.

When pages are connected via navigation (as in your music store project) it is only necessary to submit the URL of the first page.

Regular Expressions HTML Color Names Color Picker ASCII Character Codes Unicode Character Codes