Objectives

Introduce forms into a play application to enable the user to create playlists.

Exercise Solutions

Exercise 2: UX Enhancements

Introduce a 'Delete Playlist' button for each playlist, represented by a trash icon. E.g:

In addition, the view link is replace by a folder open icon.

Bind the delete playlist button to a new function to be implemented in the Dashboard controller, which should log the id of the playlist to be deleted.

Solution

First the new user interface:

app/views/dashboard.html

#{extends 'main.html' /}
#{set title:'Dashboard' /}

#{menu id:"dashboard"/}

#{list items:playlists, as:'playlist'}
  <section class="ui segment">
    <h2 class="ui header">
      ${playlist.title} 
    </h2>
      <p> Total Duration: ${playlist.duration} </p>
      <a href="/playlists/${playlist.id}" class="ui icon button">
        <i class="icon folder open"></i>
      </a>
      <a href="/dashboard/deleteplaylist/${playlist.id}" class="ui icon button">
        <i class="icon trash"></i>
      </a>
  </section>
#{/list}

Exercise 3: Delete Playlist Functionality

Now, make the button actually delete the denoted playlist.

Solution

conf/routes

GET     /dashboard/deleteplaylist/{id}          Dashboard.deletePlaylist

app/controllers/Dashboard.java

...
  public static void deletePlaylist (Long id)
  {
    Playlist playlist = Playlist.findById(id);
    Logger.info ("Removing" + playlist.title);
    playlist.delete();
    redirect ("/dashboard");
  }
...

Try this now - and make sure a playlist is being deleted.

Also - check to see if the songs in the playlist are also deleted?

Add Song Form

Introduce a new partial to provide a simple form to add songs to a playlist:

app/views/tags/addsong.html

<form class="ui stacked segment form" action="/playlists/${_playlist.id}/addsong" method="POST">
  <div class="two fields">
    <div class="field">
      <label>Title</label>
      <input placeholder="Title" type="text" name="title">
    </div>
    <div class="field">
      <label>Artist</label>
      <input placeholder="Artist" type="text" name="artist">
    </div>
    <div class="field">
      <label>Duration</label>
      <input placeholder="Duration" type="number" name="duration">
    </div>
  </div>
  <button class="ui blue submit button">Add Song</button>
</form>

app/views/playlist.html

#{extends 'main.html' /}
#{set title:'Playlist' /}

#{menu id:"dashboard"/}

<section class="ui segment">
  <h2 class="ui header">
    ${playlist.title}
  </h2>
  #{listsongs playlist:playlist /}
  #{addsong playlist:playlist /}
</section>

The playlists should now render like this:

Add Song Route + Action

To implement the feature - we need a new route:

conf/routes

...
POST    /playlists/{id}/addsong                  PlaylistCtrl.addSong
...

Finally, the actual implementation of the add the song:

app/controllers/PlaylistCtrl.java

...
  public static void addSong(Long id, String title, String artist, int duration)
  {
    Song song = new Song(title, artist, duration);
    Playlist playlist = Playlist.findById(id);
    playlist.songs.add(song);
    playlist.save();
    redirect ("/playlists/" + id);
  }
...

Restart the app now - and verify that you can add songs. Check in the database to verify that the new songs appear in the table.

Add Playlist Form

A new form to support adding new playlists:

app/views/tags/addplaylist.html

<form class="ui stacked segment form" action="/dashboard/addplaylist" method="POST">
  <div class="field">
    <label>Title</label>
    <input placeholder="Title" type="text" name="title">
  </div>
  <button class="ui blue submit button">Add Playlist</button>
</form>

Include this partial at the end of the dashboard view:

app/views/dashboard.html

...
...
#{addplaylist /}

The dashboard should look like this now:

Add Playlist Route + Action

To implement the feature - we need a new route:

conf/routes

...
POST    /dasghboard/addplaylist                 Dashboard.addPlaylist
...

Finally, the actual implementation of the add playlist logic:

app/controllers/Dashboard.java

...
  public static void addPlaylist (String title)
  {
    Playlist playlist = new Playlist (title, 0);
    Logger.info ("Adding a new playlist called " + title);
    playlist.save();
    redirect ("/dashboard");
  }
...

Restart the app now - and verify that you can add playlists. Check in the database to verify that the new playlists appear in the table. Also add some songs to the playlist.

Exercises

Exercise 1 : Download, Rename and Run the Sample Solution

Even if you have successfully completed this lab - do not skip this step, as it is important to be able to run the sample solutions occasionally, and also retain them for reference purposes.

A complete version of the app as it should be at the end of this lab:

Download and unzip the archive (select the zip version). Once unzipped, rename the folder to playlist-4. Make sure the unzipped and renamed folder looks exactly like this:

Now we need to rename the project. Open the following file:

conf/application.conf

# This is the main configuration file for the application.
# ~~
application.name=playlist
...

Change playlist above to playlist-4.

Next, from a shell inside the project folder run the play eclipsify command:

In eclipse - select File->Import ... and then select the following option:

Select Browse and locate the playlist-4 folder:

Press Finish - and the project will be imported:

You should be able to run app in the usual way:

Exercise 2: Import the sample solution into IntelliJ Idea

The last lab had install instruction for InteliJ Idea. Try to figure out how to import the project into this Idea.