Index: Dev/trunk/src/client/qed-client/model/widgets/QuestionEditorPreviewItem.js
===================================================================
--- Dev/trunk/src/client/qed-client/model/widgets/QuestionEditorPreviewItem.js	(revision 511)
+++ Dev/trunk/src/client/qed-client/model/widgets/QuestionEditorPreviewItem.js	(revision 512)
@@ -149,5 +149,5 @@
             if ( this.innerWidget !== null ) {
                 if ( this._editing === true ) {
-                    this._onChange();
+                    this.triggerOnChange();
                 }
                 this.removeChild(this.innerWidget);
Index: Dev/trunk/src/client/qed-client/model/widgets/SurveyRunWidget.js
===================================================================
--- Dev/trunk/src/client/qed-client/model/widgets/SurveyRunWidget.js	(revision 511)
+++ Dev/trunk/src/client/qed-client/model/widgets/SurveyRunWidget.js	(revision 512)
@@ -8,8 +8,12 @@
         templateString: template,
         postCreate: function() {
+            this.inherited(arguments);
             var endDateBox = this.endDateBox;
             this.own(this.startDateBox.on('change', function(value){
                 endDateBox.constraints.min  = value;
             }));
+        },
+        startup: function() {
+            this.inherited(arguments);
         },
         _getValueAttr: function() {
Index: Dev/trunk/src/client/qed-client/model/widgets/SurveySummary.js
===================================================================
--- Dev/trunk/src/client/qed-client/model/widgets/SurveySummary.js	(revision 511)
+++ Dev/trunk/src/client/qed-client/model/widgets/SurveySummary.js	(revision 512)
@@ -18,5 +18,6 @@
         _setValueAttr: function(survey) {
             this.titleNode.innerHTML = survey.title || "";
-            domAttr.set(this.titleNode, "href", survey && surveys.getObjectPath(survey));
+            domAttr.set(this.titleNode, "href",
+                        survey && ('#!'+surveys.getObjectPath(survey)));
             this.descriptionNode.innerHTML = survey.description || "";
             this.questionsNode.innerHTML = survey.questions.length;
Index: Dev/trunk/src/client/qed-client/model/widgets/templates/SurveyWidget.html
===================================================================
--- Dev/trunk/src/client/qed-client/model/widgets/templates/SurveyWidget.html	(revision 511)
+++ Dev/trunk/src/client/qed-client/model/widgets/templates/SurveyWidget.html	(revision 512)
@@ -1,5 +1,7 @@
 <form class="${baseClass}">
     <label for="title">Title</label>
-    <input data-dojo-type="dijit/form/TextBox" name="title"/><br/>
+    <input data-dojo-type="dijit/form/ValidationTextBox"
+           data-dojo-props="required: true"
+           name="title"/><br/>
     <label for="description">Description</label>
     <textarea data-dojo-type="dijit/form/Textarea" name="description"></textarea><br/>
Index: Dev/trunk/src/client/qed-client/pages/survey.js
===================================================================
--- Dev/trunk/src/client/qed-client/pages/survey.js	(revision 511)
+++ Dev/trunk/src/client/qed-client/pages/survey.js	(revision 512)
@@ -5,4 +5,5 @@
     "../model/widgets/TabbedQuestionBrowser",
     "./_ObjectPage",
+    "dojo/Deferred",
     "dojo/_base/array",
     "dojo/_base/declare",
@@ -12,5 +13,5 @@
     "require",
     "dojo/text!./templates/survey.html"
-], function(Router, surveys, QuestionListView, TabbedQuestionBrowser, _ObjectPage, array, declare, event, lang, when, require, template) {
+], function(Router, surveys, QuestionListView, TabbedQuestionBrowser, _ObjectPage, Deferred, array, declare, event, lang, when, require, template) {
     return declare([_ObjectPage],{
         contextRequire: require,
@@ -77,13 +78,19 @@
         },
         _handleQuestionsChange: function() {
-            this.object.questions = this.questionList.get('value');
+            this._updateObject();
             this.markDirty();
             this._refresh();
         },
         _handlePropertiesChange: function() {
-            lang.mixin(this.object, this.propertiesForm.get('value').survey);
+            this._updateObject();
             this.markDirty();
             this._refresh();
             this.layout();
+        },
+        _updateObject: function() {
+            this._isValid = this.propertiesForm.validate();
+            lang.mixin(this.object, this.propertiesForm.get('value').survey);
+            this.object.questions = this.questionList.get('value');
+            return this._isValid;
         },
         _onSave: function(evt) {
@@ -109,7 +116,14 @@
             });
         },
+        _save: function() {
+            if ( this._updateObject ) {
+                return this.inherited(arguments);
+            } else {
+                return new Deferred().reject({error:"Please correct invalid values."});
+            }
+        },
         markDirty: function() {
-            this.saveBtn.set('disabled',false);
-            this.saveAndCloseBtn.set('disabled',false);
+            this.saveBtn.set('disabled',!this._isValid);
+            this.saveAndCloseBtn.set('disabled',!this._isValid);
             this.discardBtn.set('label','Discard & Close');
             this.inherited(arguments);
Index: Dev/trunk/src/client/qed-client/widgets/_ComplexValueMixin.js
===================================================================
--- Dev/trunk/src/client/qed-client/widgets/_ComplexValueMixin.js	(revision 511)
+++ Dev/trunk/src/client/qed-client/widgets/_ComplexValueMixin.js	(revision 512)
@@ -46,10 +46,10 @@
             });
         },
-        // Yuk, this function is taken directly from _FromMixin only
-        // to add the priorityChange parameter
         _getValueAttr: function() {
             this.value = this.inherited(arguments);
             return this.value;
         },
+        // Yuk, _setValueAttr is taken directly from _FromMixin only
+        // to add the priorityChange parameter
 		_setValueAttr: function(obj, priorityChange) {
             this.value = obj;
@@ -99,5 +99,5 @@
         _handleChange: function(evt) {
             if ( evt.target !== this.domNode ) {
-                this._onChange();
+                this.triggerOnChange();
                 if ( evt ) { event.stop(evt); }
                 return false;
@@ -120,5 +120,5 @@
             return false;
         },
-        _onChange: function() {
+        triggerOnChange: function() {
             if ( this._onChangeActive &&
                  !(this.readOnly || this.disabled) ) {
