diff --git a/cms/static/js/spec/views/textbook_spec.js b/cms/static/js/spec/views/textbook_spec.js
index 5a842a763f2b880c01f6f4ebfee856b0259333f1..1a0332f90f0c8366a79be21ee8afea697dd57f6d 100644
--- a/cms/static/js/spec/views/textbook_spec.js
+++ b/cms/static/js/spec/views/textbook_spec.js
@@ -168,6 +168,12 @@ define(["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js
                     expect(this.model.save).not.toHaveBeenCalled();
                 });
 
+                it("does not re-render on cancel", function() {
+                    this.view.render();
+                    this.view.$(".action-cancel").click();
+                    expect(this.view.render.calls.count()).toEqual(1);
+                });
+
                 it("should be possible to correct validation errors", function() {
                     this.view.render();
                     this.view.$("input[name=textbook-name]").val("");
@@ -248,6 +254,23 @@ define(["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js
                 //           expect($inputEl.find(':focus').length).toEqual(1)
                 expect(jQuery.fn.focus).toHaveBeenCalledOnJQueryObject($inputEl);
             });
+
+            it("should re-render when new textbook added", function() {
+                spyOn(this.view, 'render').and.callThrough();
+                this.view.$(".new-button").click();
+                expect(this.view.render.calls.count()).toEqual(1);
+            });
+
+            it("should remove textbook html section on model.destroy", function() {
+                    this.model = new Textbook({name: "Life Sciences", id: "0life-sciences"});
+                    this.collection.add(this.model);
+                    this.view.render();
+                    CMS.URL.TEXTBOOKS = "/textbooks"; // for AJAX
+                    expect(this.view.$el.find('section').length).toEqual(1);
+                    this.model.destroy();
+                    expect(this.view.$el.find('section').length).toEqual(0);
+                    delete CMS.URL.TEXTBOOKS;
+            });
         });
 
         //    describe "ListTextbooks", ->
diff --git a/cms/static/js/views/edit_textbook.js b/cms/static/js/views/edit_textbook.js
index 53030273f6e3831efa6d06e8f97d0acb8788d1eb..86a73c067cfbcd0834b2750fc9718af80a242929 100644
--- a/cms/static/js/views/edit_textbook.js
+++ b/cms/static/js/views/edit_textbook.js
@@ -7,12 +7,11 @@ define(['js/views/baseview', 'underscore', 'jquery', 'js/views/edit_chapter', 'c
                     var chapters = this.model.get('chapters');
                     this.listenTo(chapters, 'add', this.addOne);
                     this.listenTo(chapters, 'reset', this.addAll);
-                    this.listenTo(chapters, 'all', this.render);
                 },
                 tagName: 'section',
                 className: 'textbook',
                 render: function() {
-                    this.$el.html(this.template({
+                    this.$el.html(this.template({ // xss-lint: disable=javascript-jquery-html
                         name: this.model.get('name'),
                         error: this.model.validationError
                     }));
diff --git a/cms/static/js/views/list_textbooks.js b/cms/static/js/views/list_textbooks.js
index c9da63fe25a3d420aa3386da1ad31e98457ce99a..adaee81c332ea67724b6b4b95216840772d831d3 100644
--- a/cms/static/js/views/list_textbooks.js
+++ b/cms/static/js/views/list_textbooks.js
@@ -3,7 +3,7 @@ define(['js/views/baseview', 'jquery', 'js/views/edit_textbook', 'js/views/show_
             var ListTextbooks = BaseView.extend({
                 initialize: function() {
                     this.emptyTemplate = this.loadTemplate('no-textbooks');
-                    this.listenTo(this.collection, 'all', this.render);
+                    this.listenTo(this.collection, 'change:editing', this.render);
                     this.listenTo(this.collection, 'destroy', this.handleDestroy);
                 },
                 tagName: 'div',
@@ -11,7 +11,7 @@ define(['js/views/baseview', 'jquery', 'js/views/edit_textbook', 'js/views/show_
                 render: function() {
                     var textbooks = this.collection;
                     if (textbooks.length === 0) {
-                        this.$el.html(this.emptyTemplate());
+                        this.$el.html(this.emptyTemplate()); // xss-lint: disable=javascript-jquery-html
                     } else {
                         this.$el.empty();
                         var that = this;
@@ -34,6 +34,7 @@ define(['js/views/baseview', 'jquery', 'js/views/edit_textbook', 'js/views/show_
                     var $sectionEl, $inputEl;
                     if (e && e.preventDefault) { e.preventDefault(); }
                     this.collection.add([{editing: true}]); // (render() call triggered here)
+                    this.render();
             // find the outer 'section' tag for the newly added textbook
                     $sectionEl = this.$el.find('section:last');
             // scroll to put this at top of viewport
diff --git a/cms/static/js/views/show_textbook.js b/cms/static/js/views/show_textbook.js
index b3e25a983865aadb3fd0a96e8eb11bb2b1faaa9e..1a6ee943bb3c841e8f38994ad6ed1b9cc1bc62f4 100644
--- a/cms/static/js/views/show_textbook.js
+++ b/cms/static/js/views/show_textbook.js
@@ -5,6 +5,7 @@ define(['js/views/baseview', 'underscore', 'gettext', 'common/js/components/view
                 initialize: function() {
                     this.template = _.template($('#show-textbook-tpl').text());
                     this.listenTo(this.model, 'change', this.render);
+                    this.listenTo(this.model, 'destroy', this.remove);
                 },
                 tagName: 'section',
                 className: 'textbook',
@@ -18,7 +19,7 @@ define(['js/views/baseview', 'underscore', 'gettext', 'common/js/components/view
                     var attrs = $.extend({}, this.model.attributes);
                     attrs.bookindex = this.model.collection.indexOf(this.model);
                     attrs.course = window.course.attributes;
-                    this.$el.html(this.template(attrs));
+                    this.$el.html(this.template(attrs)); // xss-lint: disable=javascript-jquery-html
                     return this;
                 },
                 editTextbook: function(e) {
@@ -29,7 +30,7 @@ define(['js/views/baseview', 'underscore', 'gettext', 'common/js/components/view
                     if (e && e.preventDefault) { e.preventDefault(); }
                     var textbook = this.model;
                     new PromptView.Warning({
-                        title: _.template(gettext('Delete “<%= name %>”?'))(
+                        title: _.template(gettext('Delete “<%- name %>”?'))(
                     {name: textbook.get('name')}
                 ),
                         message: gettext("Deleting a textbook cannot be undone and once deleted any reference to it in your courseware's navigation will also be removed."),