diff --git a/server/djrandom/frontend/api_views.py b/server/djrandom/frontend/api_views.py
index f9aac546438db65d3800087ce58ae9c6f965ea89..7bee1f9b786de7e8be8ad98b455127842035a63a 100644
--- a/server/djrandom/frontend/api_views.py
+++ b/server/djrandom/frontend/api_views.py
@@ -124,19 +124,19 @@ def playlist_info_json(uuid):
     return jsonify(playlist.to_dict())
 
 
-@app.route('/json/playlist/by_title/<uuid>/<title>')
+@app.route('/json/playlist/by_title/<userid>/<title>')
 @require_auth
-def playlist_info_by_title_json(uuid, title):
-    playlist = Playlist.get_by_title(uuid, title)
+def playlist_info_by_title_json(userid, title):
+    playlist = Playlist.get_by_title(userid, title)
     if not playlist:
         abort(404)
     return jsonify(playlist.to_dict())
 
 
-@app.route('/json/playlist/list/<uuid>')
+@app.route('/json/playlist/list/<userid>')
 @require_auth
-def playlist_list_by_uuid_json(uuid):
-    playlists = [x.to_dict() for x in Playlist.get_all_by_user(uuid)]
+def playlist_list_by_uuid_json(userid):
+    playlists = [x.to_dict() for x in Playlist.get_all_by_user(userid)]
     return jsonify(results=playlists)
 
 
diff --git a/server/djrandom/frontend/static/js/djr/backend.js b/server/djrandom/frontend/static/js/djr/backend.js
index 425b8968c3df7d38ba6f4654d250d1bf9cd94e12..74674ae03498237b9241dc7d64f38cbbcd468ae7 100644
--- a/server/djrandom/frontend/static/js/djr/backend.js
+++ b/server/djrandom/frontend/static/js/djr/backend.js
@@ -104,12 +104,12 @@ djr.Backend.prototype.autocomplete = function(request, callback) {
  * It will invoke callback(songs) where 'playlist' is an array of uuid
  * song hashes.
  *
- * @param {string} uuid Playlist identifier.
+ * @param {string} userid User id.
  * @param {function} callback Callback function.
  * @param {Object} ctx Callback context.
  */
-djr.Backend.prototype.getPlList = function(uid, callback, ctx) {
-  $.ajax({url: '/json/playlist/list/' + uid,
+djr.Backend.prototype.getPlList = function(userid, callback, ctx) {
+  $.ajax({url: '/json/playlist/list/' + userid,
           dataType: 'json',
           type: 'GET',
           context: ctx || this,
diff --git a/server/djrandom/frontend/static/js/djr/djr.js b/server/djrandom/frontend/static/js/djr/djr.js
index feef3870c69649c6d1a59e1a7163b6afed10e54c..06944194ca32cf6f3b83c116877c25ff8c34f8a4 100644
--- a/server/djrandom/frontend/static/js/djr/djr.js
+++ b/server/djrandom/frontend/static/js/djr/djr.js
@@ -8,13 +8,15 @@ djr = {};
 
 // Global state (with Player instance).
 djr.state = {
+  userid: null,
   backend: null,
   player: null,
   loadingCount: 0
 };
 
 // Initialize the Player and add all our onclick handlers.
-djr.init = function () {
+djr.init = function (userid) {
+  djr.state.userid = userid;
   djr.state.backend = new djr.Backend();
   djr.state.player = new djr.Player(djr.state.backend, '#djr_player');
 
@@ -75,13 +77,15 @@ djr.init = function () {
       $('#saveForm').show('fast');
     } else {
       $('#savetext').val('');
-      $('#saveForm').hide('fast');
+      $('#saveForm').hide();
     }
   });
   $('#playlistSaveBtn').click(function() {
-    if ( $('#savetext').val() != '' ) {
-      djr.player.saveNewPlaylist($('#savetext').val());
+    var pltitle = $('#savetext').val();
+    if (pltitle != '') {
+      djr.state.player.savePlaylistWithTitle(pltitle);
     }
+    $('#saveForm').hide();
   });
   $('#wikibtn').click(function () {
     var stitle = $('#song_' + djr.state.player.cur_song + ' .artist').text();
@@ -125,24 +129,24 @@ djr.init = function () {
     }
   });
   $('#pllistbtn').click(function () {
-    if ( $('#pllist').is(':visible') == false ) {
+    if ($('#pllist').is(':visible') == false) {
       $('#pllist').show('slow');
-      this.backend.getPlList(uid, function(results) {
+      this.backend.getPlList(djr.state.userid, function(results) {
         var pllist = results;
         if (pllist.length == 0) {
          djr.debug('No results found.');
          return;
         }
         var output = "<ul>";
-        for (var i; i < pllist.lenght; i++) {
-          output += "<il><a id='" + pllist[i].uuid + "' onclick='djm.player.showPlaylist(\"" + pllist[i].uuid + "\"' >" + pllist[i].title + "</a></il>";
-          //output += "<il><a id='" + pllist[i].uuid + "' onclick='djr.Playlist.saveNewPlaylist();djr.player.createChunk(djr.Playlist.getPlaylist(\"" + pllist[i].uuid + "\"), \"" + pllist[i].title + "\");' >" + pllist[i].title + "</a></il>";
-            }
+        for (var i; i < pllist.length; i++) {
+          output += "<li><a onclick='djm.player.loadPlaylist(\"" + pllist[i].uuid + "\")' >"  + pllist[i].title + "</a></li>";
+
+        }
         output += "</ul>";
         $('#pllist').html(output);
       });
     } else {
-        $('#pllist').hide('slow')
+      $('#pllist').hide('slow')
     }
   });
 
diff --git a/server/djrandom/frontend/static/js/djr/player.js b/server/djrandom/frontend/static/js/djr/player.js
index cc6a7a6bba520c5157d55d112c1b2a3d63da2714..8badcb08b4c7fb887dbe8e6d4e2a734b598389a7 100644
--- a/server/djrandom/frontend/static/js/djr/player.js
+++ b/server/djrandom/frontend/static/js/djr/player.js
@@ -31,8 +31,12 @@ djr.Player.prototype.hideAllChunks = function() {
 // Callback for removechunk click.
 djr.Player.prototype.removeChunk = function(chunk_id) {
   this.playlist.removeChunk(chunk_id);
-  this.savePlaylist();
   $('#chunk_' + chunk_id).remove();
+  this.savePlaylist();
+  // If the playlist is now empty, switch to a new uuid.
+  if (this.playlist.isEmpty()) {
+    this.clearPlaylist();
+  }
 };
 
 // Remove a single song.
@@ -51,8 +55,10 @@ djr.Player.prototype.savePlaylist = function() {
 };
 
 // Save the current playlist.
-djr.Player.prototype.saveNewPlaylist = function(title) {
+djr.Player.prototype.savePlaylistWithTitle = function(title) {
   this.backend.savePlaylist(djr.generateRandomId(), title, this.playlist.allSongs());
+  // Merge all existing chunks into one, named as the playlist.
+  this.mergePlaylistChunks('playlist: ' + title);
 };
 
 // Completely clear out the current playlist, and replace it with 
@@ -60,12 +66,13 @@ djr.Player.prototype.saveNewPlaylist = function(title) {
 djr.Player.prototype.clearPlaylist = function() {
   this.playlist = new djr.Playlist();
   $('#playlistDiv').empty();
+  djr.debug('new playlist: ' + this.playlist.uuid);
 };
 
 // Merge all chunks into a single one.
-djr.Player.prototype.mergePlaylistChunks = function() {
+djr.Player.prototype.mergePlaylistChunks = function(title) {
   // Reduce the playlist to a single chunk.
-  this.playlist = this.playlist.merge();
+  this.playlist = this.playlist.merge(title);
 
   // Shuffle the HTML data around (so we don't have to necessarily
   // fetch it again from the server). This is done in a few steps:
@@ -150,7 +157,6 @@ djr.Player.prototype.neverPlayedPlaylist = function(num) {
 
 };
 
-
 djr.Player.prototype.mostPlayedPlaylist = function(num) {
   var player = this;
   var title = "" + num + " Most Played Songs";
@@ -169,6 +175,20 @@ djr.Player.prototype.mostPlayedPlaylist = function(num) {
 
 };
 
+djr.Player.prototype.loadPlaylist = function(uuid) {
+  var player = this;
+  this.backend.getPlaylist(uuid, function(plist) {
+    var chunk_title;
+    if (!plist.title) {
+      chunk_title = 'playlist: ' + plist.uuid;
+    } else {
+      chunk_title = 'playlist: ' + plist.title;
+    }
+    player.clearPlaylist();
+    player.createChunk(plist.songs, chunk_title);
+  });
+};
+
 // Extend the current playlist with suggestions.
 djr.Player.prototype.extendCurrentPlaylist = function() {
   var player = this;
diff --git a/server/djrandom/frontend/static/js/djr/playlist.js b/server/djrandom/frontend/static/js/djr/playlist.js
index 96b029f5b1d582a16600006bf522ede91aa52332..52d88ac8fa8e3e438b67ebd4f9117891fc955667 100644
--- a/server/djrandom/frontend/static/js/djr/playlist.js
+++ b/server/djrandom/frontend/static/js/djr/playlist.js
@@ -78,6 +78,13 @@ djr.Playlist = function(uuid) {
   this.next_chunk_id = 0;
 };
 
+/**
+ * Return true if the playlist is empty.
+ */
+djr.Playlist.prototype.isEmpty = function() {
+  return (this.chunks.length == 0);
+};
+
 /**
  * Return an array with all songs in the playlist.
  *
@@ -200,14 +207,18 @@ djr.Playlist.prototype.removeSong = function(song) {
  *
  * The UUID of the new playlist will be the same as the current one.
  *
+ * @param {string} title Title for the new chunk (optional).
  * @return {Playlist} The new playlist.
  */
-djr.Playlist.prototype.merge = function() {
+djr.Playlist.prototype.merge = function(title) {
   var new_title_parts = [], i;
   for (i = 0; i < this.chunks.length; i++) {
     new_title_parts.push(this.chunk_map[this.chunks[i]].title);
   }
-  var new_title = new_title_parts.join(' + ');
+  var new_title = title;
+  if (!new_title) {
+    new_title = new_title_parts.join(' + ');
+  }
   var new_playlist = new djr.Playlist();
   new_playlist.uuid = this.uuid;
   new_playlist.addChunk(
diff --git a/server/djrandom/frontend/templates/index.html b/server/djrandom/frontend/templates/index.html
index 44502e4861f04e6732a3733d82c9ab2bc63318dd..1834413225dcb76fe868db805f767ed757ea47e4 100644
--- a/server/djrandom/frontend/templates/index.html
+++ b/server/djrandom/frontend/templates/index.html
@@ -43,7 +43,7 @@
     <script type="text/javascript">
 $(document).ready(function() {
   // Initialize DJR.
-  djr.init();
+  djr.init('{{ user.id }}');
 });
     </script>
   </head>