Objectives

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

Exercise Solutions

If you have completed the Playlist labs to date, then you can continue to work in the Playlist project you should have created.

If you cannot locate this project, or it has become unusable - then you can start from the solution lab08b:

Download the archive, unzip and run play idealize - and then open in Idea.

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>

Now include this partial in the playlist view (at the end):

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:

We have a new form and an add song button

Add Song Route + Action

To implement the feature - we need a new route:

conf/routes

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

Put this below the existing playlist routes.

Finally, the actual implementation of the add the song - a new method in the Playlist Controler:

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

Create a new partial containig a 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, unzip,idealize the project. Then run it. You should be comfortable doing this now.