BTI420 Assignment 6

Working with a many-to-many association, “edit existing” use case.

Read/skim all of this document before you begin work.

 

Due date

Sunday, March 5, 2017, at 11:00pm ET

Notice that this due date is at the end of study week, so you can take your time and do this right.

Grade value: 5% of your final course grade

If you wish to submit the assignment before the due date and time, you can do that.

 

Objective(s)

Work with many-to-many associated data, with “edit existing” functionality. Your web app will enable users to work with Playlist objects.

 

Introduction to the problem to be solved

We need an app that will enable a browser user to view and edit playlists.

 

Specifications overview and work plan

Here’s a brief list of specifications that you must implement:

  • Follows best practices
  • Implements the recommended system design guidance
  • Customized appearance, with an added menu item
  • Displays invoice and associated data

Here is a brief work plan sequence:

  1. Create the project, based on the project template
  2. Customize the app’s appearance
  3. Create view models and mappers that cover the use cases
  4. Add methods to the Manager class that handle the use cases
  5. Add controllers, with code to work with the manager object
  6. For the playlist entity, implement the “get all” and “get one” use cases; including controller code, and views
  7. For the playlist entity, implement the “edit existing” use case; including controller code, and view

During the class/session, your professor will help you get started and make progress on this assignment.

Every week, in the computer-lab class/session, your teacher will record a grade when you complete a specific small portion of the assignment. We call this “in-class grading“.

The in-class grading will be announced in-class by your professor.

 

Getting started

Create a new web app, named Assignment6. It MUST use the “Web app project v1” project template.

Build/compile, and run the app, to ensure that you are starting with a working error-free base. Then, as you write code, build/compile frequently.

 

Customize the app’s appearance

You will customize the appearance all of your web apps and assignments. Never submit an assignment that has the generic auto-generated text content. Make the time to customize the web app’s appearance.

For this assignment, you can defer this customization work until later. Come back to it at any time, and complete it before you submit your work. 

Follow the guidance from Assignment 1 to customize the app’s appearance.

 

Overall goal: Enable basic editing

The overall goal is to enable basic editing of a playlist. The following image shows what you may end up with at the end of this assignment. Click to open the image full-size in a new tab/window.

phase1-playlist-edit1

 

Study the image. It shows a list of existing tracks on the playlist on the right side of the page. On the left, it shows a list of ALL tracks, whether on the playlist or not. The browser user can use the checkboxes to edit the content of the playlist.

To render this view, it will need one select list object, and a collection:

  • The select list will be used to render the checkboxes
  • The collection will hold the track objects on the existing playlist

 

Create view models and mappers that cover the initial use cases

The most logical starting point for the app will be to display a list of playlist objects.

Therefore, you will need a PlaylistBase view model class.

Next, you will need another view model class to hold details, and the most important details is a collection of track objects.

This in turn implies that you will need a TrackBase class.

The “edit existing” task will need another two view model classes:

  1. A view model class named (maybe) PlaylistEditTracksForm, to hold the data that is needed to render the HTML Form
  2. A view model class named (maybe) PlaylistEditTracks, to hold the data submitted by the browser user

As noted in the previous section, the “…Form” view model class will yes, need a select list property (for multiple selection). It will also need another property, to hold the collection of tracks that are on the current playlist.

As you have learned, the “…Form” view model class needs identification information. The object identifier, for sure, and obviously. And text to display to the browser user.

Remember, you will also need mappers.

 

Add methods to the Manager class that handle the use cases

Methods to handle “get all” playlists, and “get one” playlist, are needed.

As you have seen with other associated-item scenarios, the “get one” method will fetch the associated object(s). Therefore, “get one” playlist must fetch its track objects.

In addition, the “edit existing” playlist method will be needed. It will use the standard pattern for editing a to-many association of objects, as seen in the AssocManyToMany code example, and in the recent class notes.

Now, stop for a moment, and think about the “edit playlist” task. Presumably, you will create a page that will show or identify the playlist-being-edited. To edit/select the tracks on the playlist, the page will also have to show a list of tracks, in an item-selection element.

Therefore, in the Manager class, you will also need a “get all” tracks method.

 

Add controller(s), with code to work with the manager object

Add a controller for the playlist entity.

 

For the playlist entity, implement the “get all”  and “get one” use cases;
including controller code, and views

In the playlist controller, add the standard methods for “get all” and “get one”.

Generate the “get all” view. It should look something like the following. Click the image to open it in a new tab/window.

phase1-playlist-list1

 

How did the middle column – Number of tracks on this playlist – get generated?

Two changes – one in the view model class, and one in the Manager class.

In the PlaylistBase class, add an int property named “TracksCount”. This name is important. It is a composed name. For a specific playlist object, which has a navigation property named “Tracks”, it will fetch/render the “Count” property of the “Tracks” object. Wait – there’s no property named “Count” in the design model class – where is that defined? Well, “Count” is a property of the collection.

Then, in the Manager class, edit the “get all” method, so that it includes the “Tracks” property in the fetch.

Finally, render this column in the view. If you want the number to show up as a Bootstrap badge, you can do that too.

 

Generate the “get one” view. It will need hand-editing, to render the collection of Track objects (wrapped in <p> or <span> elements, your choice). It should look something like the following. Click the image to open it in a new tab/window.

phase1-playlist-details1

 

For the playlist entity, implement the “edit existing” use case;
including controller code, and view

Now, you’re ready to implement the “edit existing” use case. If you wish, you can use the pair of method stubs in the controller that the scaffolder created for the edit task, to get started. Use the familiar pattern to code the rest of the methods.

You should know by now that the purpose of the GET method is to prepare and configure the “…Form” view model object, and send it to the view, so that an HTML Form can be created.

Create a “…Form” object. Configure it. In addition to identification property values, it will need:

  • A select list object, configured with 1) all possible tracks, and 2) the identifiers for the tracks that are currently associated with the playlist
  • A TrackBase collection, configured with the tracks that are currently associated with the playlist

 

Generate and edit the view

Generate the view. As you have learned, the scaffolder does not render collections or item-selection elements.

At the end of this task, the plan is to end up with a view that was first shown above. Here’s how. First, notice how the page is designed:

phase1-playlist-edit2

 

If you want the playlist name to appear as you see it above (with a light blue background), then surround it with a <span> element that uses one of the Bootstrap contextual backgrounds.

How do we get a two-column layout? With the Bootstrap .row and .col-xx-xx classes. Here’s how to make the container:

  1. Add a <div> element with class=row
  2. Inside this container, add two more <div> elements
  3. The left side will take two-thirds of the width, or 8/12 of the grid system layout, therefore, add class=col-md-8 to the first (left-side) container
  4. Then, add class=col-md-4 to the second (right-side) container

In the left-side container, add code for the checkbox group that displays all possible tracks. (The image is showing the result of standard <input type=checkbox… elements.)

How did we render the track name, composer, track time/length, and unit price? By adding a read-only property (which is a property that does not have a “set” accessor), and then using that in the select list object’s constructor. Here’s an example of how you can add a read-only property in a view model class:

// Composed read-only property
public string NameFull
{
  get
  {
    var ms = Math.Round((((double)Milliseconds / 1000) / 60), 1);

    var composer = string.IsNullOrEmpty(Composer) ? "" : ", composer " + Composer;
    var trackLength = (ms > 0) ? ", " + ms.ToString() + " minutes" : "";
    var unitPrice = (UnitPrice > 0) ? ", $ " + UnitPrice.ToString() : "";

    return string.Format("{0}{1}{2}{3}", Name, composer, trackLength, unitPrice);
  }
}

 

The right-side container will have code for the <p> elements that hold the track names now on the playlist.

If you want the right-side container to have a grey background with rounded corners, simply add one of the Bootstrap well classes.

 

Code the method that processes the data submitted by the browser user

The incoming data will include the playlist identifier, and an int collection, with the identifiers of the tracks that will be on the playlist. Pass them on to the manager method. A successful result will redirect to the “details” view.

 

Testing your work

In a browser, test your work, by doing tasks that fulfill the use cases in the specifications.

 

Reminder about academic honesty

You must comply with the College’s academic honesty policy. Although you may interact and collaborate with others, you must submit your own work.

 

Submitting your work

Here’s how to submit your work, before the due date and time:

1. Locate the folder that holds your solution files. In Solution Explorer, right-click the “Solution” item, and choose “Open Folder in File Explorer”. It has three  (or more) items: a Visual Studio Solution file, a folder that has your project’s source code, and a “packages” folder. Go UP one level.

2. Make a copy of the folder. This is the version that you will be uploading.

3. Remove the “packages” folder from the copied folder; also, remove the “bin” and “obj” folders.

4. Compress/zip the copied folder. The zip file SHOULD be about 2MB or less in size. If it isn’t, you haven’t followed the instructions properly.

5. Login to My.Seneca/Blackboard. Open the Web Programming on Windows course area. Click the “Assignments” link on the left-side navigator. Follow the link for this assignment. Submit/upload your zip file. The page will accept three submissions, so if you upload, then decide to fix something and upload again, you can do so.

 

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

%d bloggers like this: