Changeset 490
- Timestamp:
- 03/08/14 22:51:23 (11 years ago)
- Location:
- Dev/trunk/src
- Files:
-
- 32 edited
Legend:
- Unmodified
- Added
- Removed
-
Dev/trunk/src/client/qed-client/app/Content.js
r443 r490 8 8 _container: null, 9 9 _previousContent: null, 10 _dirty: false, 10 11 startup: function() { 11 12 if ( this._started ) { return; } … … 32 33 } 33 34 widget.region = 'center'; 35 this._previousContent = widget; 34 36 this._container.addChild(widget); 35 this._previousContent = widget;36 37 }, 37 38 notify: function(text,type) { … … 40 41 } 41 42 this._toaster.setContent(text,type || 'message'); 43 }, 44 markDirty: function() { 45 this._dirty = true; 46 }, 47 markClean:function() { 48 this._dirty = false; 49 }, 50 isDirty: function() { 51 return this._dirty; 42 52 } 43 53 }); -
Dev/trunk/src/client/qed-client/app/Page.js
r443 r490 1 1 define([ 2 'dojo/_base/declare', 3 'dijit/_TemplatedMixin', 4 'dijit/_WidgetsInTemplateMixin', 5 'dijit/layout/BorderContainer' 6 ],function(declare,_TemplatedMixin,_WidgetsInTemplateMixin,BorderContainer){ 7 return declare([BorderContainer,_TemplatedMixin,_WidgetsInTemplateMixin],{ 8 templateString: '<div>Empty page.</div>' 2 "./Content", 3 "./Path", 4 "dijit/_TemplatedMixin", 5 "dijit/_WidgetsInTemplateMixin", 6 "dijit/layout/BorderContainer", 7 "dojo/_base/declare", 8 "dojo/_base/lang", 9 "dojo/hash" 10 ], function(Content, Path, _TemplatedMixin, _WidgetsInTemplateMixin, BorderContainer, declare, lang, hash) { 11 var Page = declare([BorderContainer,_TemplatedMixin,_WidgetsInTemplateMixin],{ 12 templateString: '<div>Empty page.</div>', 13 die: function(msg) { 14 Content.set(new Page({templateString:'<div>Error: '+msg+'</div>'})); 15 }, 16 notify: lang.hitch(Content,'notify'), 17 setURL: function(url,opts,addToHistory) { 18 hash(Path.format(url,opts),addToHistory !== true); 19 }, 20 markDirty: lang.hitch(Content,'markDirty'), 21 markClean: lang.hitch(Content,'markClean') 9 22 }); 23 return Page; 10 24 }); -
Dev/trunk/src/client/qed-client/app/Router.js
r487 r490 1 1 define([ 2 'dojo/_base/declare', 3 'dojo/hash', 4 'dojo/topic', 5 './Content', 6 './Page', 7 './Path' 8 ],function(declare,hash,topic,Content,Page,Path){ 2 "./Content", 3 "./Page", 4 "./Path", 5 "dojo/_base/declare", 6 "dojo/_base/event", 7 "dojo/_base/lang", 8 "dojo/_base/window", 9 "dojo/hash", 10 "dojo/on", 11 "dojo/topic" 12 ], function(Content, Page, Path, declare, event, lang, window, hash, on, topic) { 9 13 10 14 var Router = declare(null,{ … … 12 16 _routes: null, 13 17 _previousHash: null, 18 _beforePreviousHash: null, 14 19 15 20 constructor: function() { … … 18 23 startup: function() { 19 24 if ( this._started ) { return; } 20 if ( !Content._started ) { 21 Content.startup(); 22 } 25 Content.startup(); 23 26 this._started = true; 24 25 var self = this;26 27 27 if ( hash() === "" ) { 28 28 hash(Path.getDefault()); 29 29 } 30 this._handlePathChange(hash()); 31 topic.subscribe("/dojo/hashchange", function(){ 32 self._handlePathChange.apply(self,arguments); 33 }); 30 this._handleHashChange(hash()); 31 window.onbeforeunload = function() { 32 return Content.isDirty() && "Unsaved changes, leave anyway?"; 33 }; 34 topic.subscribe("/dojo/hashchange", 35 lang.hitch(this,'_handleHashChange')); 34 36 }, 35 37 register: function(route) { … … 68 70 return callback; 69 71 }, 70 _handlePathChange: function(newHash) { 71 if ( this._previousHash === newHash ) { return; } 72 _handleHashChange: function(newHash) { 73 if ( this._previousHash === newHash ) { 74 return false; 75 } 76 if ( Content.isDirty() ) { 77 if ( !confirm("Unsaved changes, leave anyway?") ) { 78 var probablyBack = this._beforePreviousHash === newHash; 79 // if we think we go backwards, we re-add the history 80 // entry, otherwise we reset the current one, 81 // resulting in minor annoyance of double back 82 // behaviour. 83 hash(this._previousHash,!probablyBack); 84 return false; 85 } else { 86 Content.markClean(); 87 } 88 } 89 this._beforePreviousHash = this._previousHash; 72 90 this._previousHash = newHash; 73 91 for (var i = this._routes.length-1; i >= 0; i--) { … … 78 96 route.callback(params); 79 97 } catch(err) { 80 console.error("Page change failed with",err,err. toString());98 console.error("Page change failed with",err,err.stack,err.toString()); 81 99 } 82 return ;100 return true; 83 101 } 84 102 } … … 88 106 console.error("Default page failed.",err); 89 107 } 108 return true; 90 109 }, 91 110 go: function(path,args) { 92 111 if ( !this._started ) { return; } 93 112 var newHash = Path.format(path,args); 94 this._handlePathChange(newHash);95 113 hash(newHash); 96 114 }, -
Dev/trunk/src/client/qed-client/css/dijit/overrides.less
r447 r490 122 122 background-color: #333333; 123 123 } 124 125 .claro .dijitSelect { 126 color: #000000; 127 } -
Dev/trunk/src/client/qed-client/model/classes/_Class.js
r487 r490 27 27 }, 28 28 load: function(id) { 29 return this._store.get(id).then(lang.hitch(this,'_doDeserialize')); 29 return this._store.get(id) 30 .then(lang.hitch(this,'_doDeserialize'), 31 lang.hitch(this,'_deserializeError')); 30 32 }, 31 33 save: function(obj) { 32 return this._store.put(this._doSerialize(obj)); 34 return this._store.put(this._doSerialize(obj)) 35 .otherwise(lang.hitch(this,'_deserializeError')); 33 36 }, 34 37 remove: function(objOrId,rev) { … … 40 43 rev = this.getRev(objOrId); 41 44 } 42 return this._store.remove(id,{headers:{'If-Match':'"'+rev+'"'}}); 45 return this._store.remove(id,{headers:{'If-Match':'"'+rev+'"'}}) 46 .otherwise(lang.hitch(this,'_deserializeError')); 43 47 }, 44 48 getRev: function(obj) { 45 49 return obj._rev; 50 }, 51 getName: function() { 52 return this._type; 53 }, 54 getObjectPath: function(idOrObj) { 55 return '/'+this._collection+'/'+(typeof idOrObj === "string" ? 56 idOrObj : 57 this.getId(idOrObj)); 46 58 } 47 59 }); -
Dev/trunk/src/client/qed-client/model/classes/_View.js
r487 r490 1 1 define([ 2 2 "../../store/JsonRest", 3 "dojo/Deferred", 3 4 "dojo/_base/declare", 5 "dojo/_base/json", 4 6 "dojo/_base/lang", 5 7 "dojo/store/util/QueryResults" 6 ], function(JsonRest, declare, lang, queryResults) {8 ], function(JsonRest, Deferred, declare, json, lang, queryResults) { 7 9 8 10 var _View = declare([],{ … … 18 20 }); 19 21 }, 22 _deserializeError: function(err) { 23 return new Deferred().reject(json.fromJson(err.responseText)); 24 }, 20 25 _doDeserialize: function(obj) { 21 26 obj = lang.clone(obj); … … 30 35 getId: function(obj) { 31 36 return obj._id; 37 }, 38 getCollectionPath: function() { 39 return '/'+this._collection; 32 40 } 33 41 }); -
Dev/trunk/src/client/qed-client/model/classes/responses.js
r487 r490 43 43 handleAs: 'json', 44 44 contentType: false 45 }).then(lang.hitch(this,'_doDeserialize'),function(err){ 46 return new Deferred().reject(json.fromJson(err.responseText)); 47 }); 45 }).then(lang.hitch(this,'_doDeserialize'), 46 lang.hitch(this,'_deserializeError')); 48 47 }, 49 48 postWithSecret: function(response,secret) { … … 55 54 contentType: 'application/json', 56 55 rawBody: body 57 }).then(lang.hitch(this,'_doDeserialize'),function(err){ 58 return new Deferred().reject(json.fromJson(err.responseText)); 59 }); 56 }).then(lang.hitch(this,'_doDeserialize'), 57 lang.hitch(this,'_deserializeError')); 60 58 }, 61 59 putWithSecret: function(response,secret) { … … 67 65 contentType: 'application/json', 68 66 rawBody: body 69 }).then(lang.hitch(this,'_doDeserialize'),function(err){ 70 return new Deferred().reject(json.fromJson(err.responseText)); 71 }); 67 }).then(lang.hitch(this,'_doDeserialize'), 68 lang.hitch(this,'_deserializeError')); 72 69 }, 73 70 removeWithSecret: function(response,secret) { … … 85 82 contentType: 'application/json', 86 83 rawBody: body 87 }) ;84 }).otherwise(lang.hitch(this,'_deserializeError')); 88 85 } 89 86 }); -
Dev/trunk/src/client/qed-client/model/classes/surveys.js
r487 r490 26 26 obj.publicationDate = stamp.toISOString(obj.publicationDate); 27 27 } 28 }, 29 getPreviewPath: function(idOrObj) { 30 return '/previewSurvey/'+(typeof idOrObj === "string"? 31 idOrObj : 32 this.getId(idOrObj)); 28 33 } 29 34 }); -
Dev/trunk/src/client/qed-client/model/widgets/AccountListView.js
r443 r490 23 23 actions: { 24 24 "Remove" : { 25 callback: lang.hitch(this, 'removeItem', item ),25 callback: lang.hitch(this, 'removeItem', item, true), 26 26 properties: { 27 27 blockButton: false, -
Dev/trunk/src/client/qed-client/model/widgets/CategoryListView.js
r443 r490 25 25 actions: { 26 26 "Remove" : { 27 callback: lang.hitch(this, 'removeItem', id ),27 callback: lang.hitch(this, 'removeItem', id, true), 28 28 properties: { 29 29 blockButton: false, -
Dev/trunk/src/client/qed-client/model/widgets/QuestionEditorPreview.js
r443 r490 24 24 }); 25 25 this.own(previewItem.on('destroy', 26 lang.hitch(this,'removeItem',id )));26 lang.hitch(this,'removeItem',id,true))); 27 27 previewItem.startup(); 28 28 return previewItem; -
Dev/trunk/src/client/qed-client/model/widgets/QuestionListView.js
r443 r490 23 23 actions: { 24 24 "Remove" : { 25 callback: lang.hitch(this, 'removeItem', id ),25 callback: lang.hitch(this, 'removeItem', id, true), 26 26 properties: { 27 27 blockButton: false, -
Dev/trunk/src/client/qed-client/model/widgets/SurveySummary.js
r487 r490 1 1 define([ 2 "../classes/surveys", 2 3 "dijit/_TemplatedMixin", 3 4 "dijit/_WidgetBase", … … 5 6 "dojo/dom-attr", 6 7 "dojo/text!./templates/SurveySummary.html" 7 ], function( _TemplatedMixin, _WidgetBase, declare, domAttr, template) {8 ], function(surveys, _TemplatedMixin, _WidgetBase, declare, domAttr, template) { 8 9 return declare([_WidgetBase,_TemplatedMixin],{ 9 10 templateString: template, … … 17 18 _setValueAttr: function(survey) { 18 19 this.titleNode.innerHTML = survey.title || ""; 19 domAttr.set(this.titleNode, "href", survey ._id && ("#!/survey/"+survey._id));20 domAttr.set(this.titleNode, "href", survey && surveys.getObjectPath(survey)); 20 21 this.descriptionNode.innerHTML = survey.description; 21 22 this.questionsNode.innerHTML = survey.questions.length; -
Dev/trunk/src/client/qed-client/model/widgets/TabbedQuestionBrowser.js
r487 r490 24 24 this.inherited(arguments); 25 25 this._dataMap = {}; 26 },27 postCreate: function() {28 this.inherited(arguments);29 this._query = '_design/questions/_view/'+this.include;30 26 }, 31 27 startup: function() { -
Dev/trunk/src/client/qed-client/model/widgets/questions/MultipleChoiceInputConfigWidget.js
r443 r490 37 37 value: item, 38 38 onDestroy: lang.hitch(this,function(evt){ 39 this.itemsWidget.removeItem(id );40 event.stop(evt);39 this.itemsWidget.removeItem(id,true); 40 if ( evt ) { event.stop(evt); } 41 41 return false; 42 42 }) … … 61 61 }, 62 62 onAddItem: function(evt) { 63 this.itemsWidget.appendItem({} );64 event.stop(evt);63 this.itemsWidget.appendItem({},true); 64 if ( evt ) { event.stop(evt); } 65 65 return false; 66 66 } -
Dev/trunk/src/client/qed-client/model/widgets/questions/ScaleInputConfigWidget.js
r443 r490 61 61 id: id, 62 62 onDestroy: lang.hitch(this,function(evt){ 63 this.itemsWidget.removeItem(id );64 event.stop(evt);63 this.itemsWidget.removeItem(id,true); 64 if ( evt ) { event.stop(evt); } 65 65 return false; 66 66 }) … … 75 75 }, 76 76 onAddNewItem: function(e) { 77 this.itemsWidget.appendItem({} );78 event.stop(e);77 this.itemsWidget.appendItem({},true); 78 if ( e ) { event.stop(e); } 79 79 return false; 80 80 }, -
Dev/trunk/src/client/qed-client/pages/index.js
r443 r490 1 1 define([ 2 'dojo/_base/declare', 3 '../app/Router', 4 '../app/Page', 5 'dojo/text!./templates/index.html' 6 ],function(declare,Router,Page,template){ 2 "../app/Page", 3 "../app/Router", 4 "../model/classes/questions", 5 "../model/classes/surveys", 6 "dojo/_base/declare", 7 "dojo/text!./templates/index.html" 8 ], function(Page, Router, questions, surveys, declare, template) { 7 9 return declare([Page],{ 8 10 templateString: template, … … 11 13 if ( this._started ) { return; } 12 14 this.inherited(arguments); 13 this.btnContentCreate.on("click",function(){ Router.go("/sessions"); }); 14 this.btnContentFacilitate.on("click",function(){ Router.go("/run"); }); 15 this.btnSurveys.on("click",function(){ Router.go("/surveys"); }); 16 this.btnQuestions.on("click",function(){ Router.go("/questions"); }); 17 this.btnApplications.on("click",function(){ Router.go("/applications"); }); 18 this.btnDashboards.on("click",function(){ Router.go("/dashboards"); }); 19 this.btnResults.on("click",function(){ Router.go("/results"); }); 15 //this.btnContentCreate.on("click",function(){ Router.go("/sessions"); }); 16 //this.btnContentFacilitate.on("click",function(){ Router.go("/run"); }); 17 this.btnSurveys.on("click",function(){ 18 Router.go(surveys.getCollectionPath()); 19 }); 20 this.btnQuestions.on("click",function(){ 21 Router.go(questions.getCollectionPath()); 22 }); 23 //this.btnApplications.on("click",function(){Router.go("/applications");}); 24 //this.btnDashboards.on("click",function(){ Router.go("/dashboards"); }); 25 //this.btnResults.on("click",function(){ Router.go("/results"); }); 20 26 } 21 27 }); -
Dev/trunk/src/client/qed-client/pages/question.js
r487 r490 1 1 define([ 2 "../app/Content",3 "../app/Page",4 2 "../app/Router", 5 3 "../model/classes/questions", 6 "../model/widgets/QuestionEditorPreview", 7 "../model/widgets/QuestionEditorToolkit", 8 "../widgets/_ComplexValueMixin", 4 "./_ObjectPage", 5 "dojo/Deferred", 9 6 "dojo/_base/declare", 10 7 "dojo/_base/event", 11 8 "dojo/_base/lang", 12 " dojo/when",9 "require", 13 10 "dojo/text!./templates/question.html" 14 ], function(Content, Page, Router, questions, QuestionEditorPreview, QuestionEditorToolkit, _ComplexValueMixin, declare, event, lang, when, template) { 15 return declare([Page,_ComplexValueMixin], { 11 ], function(Router, questions, _ObjectPage, Deferred, declare, event, lang, require, template) { 12 return declare([_ObjectPage], { 13 contextRequire: require, 16 14 templateString: template, 17 15 _toolkit: null, 18 16 _preview: null, 19 value: null, 20 21 buildRendering: function() { 22 this.inherited(arguments); 23 24 this._toolkit = new QuestionEditorToolkit({ 25 },this.QuestionEditorToolkitNode); 26 this._toolkit.on('submit',lang.hitch(this,"_onSave")); 27 this._toolkit.startup(); 28 29 this._preview = new QuestionEditorPreview({ 30 name: 'content', 31 delay: 5, 32 region: 'center' 33 }); 34 this._preview.startup(); 35 this.addChild(this._preview); 36 }, 17 classStore: questions, 37 18 startup: function() { 38 19 if ( this._started ) { return; } 39 20 this.inherited(arguments); 40 if ( !this.questionId ) { 41 throw new Error("Error: no reference to object set!"); 21 this.propertiesForm.on('change',lang.hitch(this,'_handlePropertiesChange')); 22 this.contentList.on('change',lang.hitch(this,'_handleContentChange')); 23 this._load(); 24 }, 25 _refresh: function() { 26 this.titleNode.innerHTML = this.object.title || ""; 27 this.propertiesForm.set('value',this.object); 28 this.contentList.set('value',this.object.content); 29 }, 30 _handlePropertiesChange: function() { 31 if ( this.propertiesForm.validate() ) { 32 lang.mixin(this.object,this.propertiesForm.get('value')); 42 33 } 43 if (this.questionId === "new") { 44 this.set('value', questions.create()); 34 this.markDirty(); 35 }, 36 _handleContentChange: function() { 37 if ( this.contentList.validate() ) { 38 this.object.content = this.contentList.get('value'); 39 } 40 this.markDirty(); 41 }, 42 _save: function() { 43 if ( this.propertiesForm.validate() && this.contentList.validate() ) { 44 lang.mixin(this.object,this.propertiesForm.get('value')); 45 this.object.content = this.contentList.get('value'); 46 return this.inherited(arguments); 45 47 } else { 46 when(questions.load(this.questionId)) 47 .then(lang.hitch(this, function(value) { 48 this.set('value', value); 49 })); 48 return new Deferred().reject(); 50 49 } 51 50 }, 52 _setValueAttr: function(value) {53 this.value = value;54 this.inherited(arguments);55 this.titleNode.innerHTML = value.title || "";56 },57 _getValueAttr: function() {58 var value = this.inherited(arguments);59 lang.mixin(this.value, value);60 return this.value;61 },62 51 _onSave: function(evt) { 63 if ( this.validate() ) { 64 questions.save(this.get('value')) 65 .then(function() { 66 Router.go('/questions'); 67 },function(err){ 68 Content.notify(err,'error'); 69 }); 70 } 52 this._save(); 71 53 if ( evt ) { event.stop( evt ); } 72 54 return false; 73 55 }, 74 _onDiscard: function() { 75 Router.go('/questions'); 76 return true; 56 _onSaveAndClose: function(evt) { 57 this._save() 58 .then(function(){ 59 Router.go(questions.getCollectionPath()); 60 }); 61 if ( evt ) { event.stop( evt ); } 62 return false; 63 }, 64 _onDiscard: function(evt) { 65 this.markClean(); 66 Router.go(questions.getCollectionPath()); 67 if ( evt ) { event.stop( evt ); } 68 return false; 69 }, 70 _ignore: function(evt) { 71 if ( evt ) { event.stop( evt ); } 72 return false; 77 73 } 78 74 }); -
Dev/trunk/src/client/qed-client/pages/questions.js
r487 r490 1 1 define([ 2 "../app/Content",3 2 "../app/Page", 4 3 "../app/Router", … … 10 9 "dojo/_base/lang", 11 10 "dojo/text!./templates/questions.html" 12 ], function( Content,Page, Router, questions, TabbedQuestionBrowser, Deferred, declare, event, lang, template) {11 ], function(Page, Router, questions, TabbedQuestionBrowser, Deferred, declare, event, lang, template) { 13 12 return declare([Page],{ 14 13 templateString: template, … … 41 40 }, 42 41 onNewQuestion: function() { 43 Router.go( "/question/new");42 Router.go(questions.getObjectPath('new')); 44 43 }, 45 44 onDeleteQuestion: function(question) { 46 45 questions.remove(question) 47 .then( function(){48 Content.notify("Question deleted.");49 } ,function(err){50 Content.notify(err,'error');51 }) ;46 .then(lang.hitch(this,function(){ 47 this.notify("Question deleted."); 48 }),lang.hitch(this,function(err){ 49 this.notify(err.error,'error'); 50 })); 52 51 }, 53 52 onEditQuestion: function(question) { 54 Router.go( "/question/"+question._id);53 Router.go(questions.getObjectPath(question)); 55 54 }, 56 55 onPublishQuestion: function(question) { 57 56 question.publicationDate = new Date(); 58 57 questions.save(question) 59 .then( function(){60 Content.notify("Question published.");61 } ,function(err){62 Content.notify(err,'error');63 }) ;58 .then(lang.hitch(this,function(){ 59 this.notify("Question published."); 60 }),lang.hitch(this,function(err){ 61 this.notify(err.error,'error'); 62 })); 64 63 } 65 64 }); -
Dev/trunk/src/client/qed-client/pages/response.js
r487 r490 1 1 define([ 2 "../app/Content",3 2 "../app/Page", 4 "../lib/async",5 3 "../model/classes/responses", 6 4 "dojo/_base/declare", … … 13 11 "require", 14 12 "dojo/text!./templates/response.html" 15 ], function( Content, Page, async, responses, declare, event, json, lang, all, request, when, require, template) {13 ], function(Page, responses, declare, event, json, lang, all, request, when, require, template) { 16 14 return declare([Page],{ 17 15 contextRequire: require, … … 60 58 .then(lang.hitch(this,function(response){ 61 59 this.response = response; 62 Content.notify("Your response is saved.");63 }), function(err){64 Content.notify(err,'error');65 }) ;60 this.notify("Your response is saved."); 61 }), lang.hitch(this,function(err){ 62 this.notify(err.error,'error'); 63 })); 66 64 }, 67 65 _onSubmit: function(e) { … … 89 87 .then(lang.hitch(this,function(res){ 90 88 this._showInfo("<div>Your response has been deleted, no answers have been saved.</div>"); 91 Content.notify("Your response is deleted.");92 }), function(err){93 Content.notify(err,'error');94 }) ;89 this.notify("Your response is deleted."); 90 }), lang.hitch(this,function(err){ 91 this.notify(err.error,'error'); 92 })); 95 93 if ( e ) { event.stop(e); } 96 94 return false; -
Dev/trunk/src/client/qed-client/pages/survey.js
r487 r490 1 1 define([ 2 "../app/Page",3 2 "../app/Router", 4 3 "../model/classes/surveys", 5 4 "../model/widgets/QuestionListView", 6 5 "../model/widgets/TabbedQuestionBrowser", 6 "./_ObjectPage", 7 7 "dojo/_base/array", 8 8 "dojo/_base/declare", … … 12 12 "require", 13 13 "dojo/text!./templates/survey.html" 14 ], function( Page, Router, surveys, QuestionListView, TabbedQuestionBrowser, array, declare, event, lang, when, require, template) {15 return declare([ Page],{14 ], function(Router, surveys, QuestionListView, TabbedQuestionBrowser, _ObjectPage, array, declare, event, lang, when, require, template) { 15 return declare([_ObjectPage],{ 16 16 contextRequire: require, 17 17 templateString: template, 18 survey: null,18 classStore: surveys, 19 19 questionList: null, 20 20 startup: function() { 21 21 if ( this._started ) { return; } 22 22 this.inherited(arguments); 23 if ( this.surveyId ) { 24 this._setupQuestionBrowser(); 25 this._setupListView(); 26 this._loadSurvey(); 27 } else { 28 throw "No valid uid or survey passed!"; 29 } 23 this._setupQuestionBrowser(); 24 this._setupListView(); 25 this._load(); 30 26 }, 31 27 _setupQuestionBrowser: function() { … … 60 56 this.questionList.startup(); 61 57 }, 62 _loadSurvey: function() { 63 if ( this.surveyId === "new" ) { 64 this.survey = surveys.create(); 65 this.refresh(); 66 } else { 67 when(surveys.load(this.surveyId)) 68 .then(lang.hitch(this,function(survey){ 69 this.survey = survey; 70 this.questionList.set('value', 71 this.survey.questions); 72 this.refresh(); 73 })); 74 } 58 _refresh: function() { 59 this.titleNode.innerHTML = this.object.title || "(set title in properties)"; 60 this.propertiesDialog.set('value',this.object); 61 this.questionList.set('value', 62 this.object.questions); 63 }, 64 _save: function() { 65 this.object.questions = this.questionList.get('value'); 66 return this.inherited(arguments); 75 67 }, 76 68 _includeQuestion: function(question) { 77 69 this.questionList.appendItem(question); 78 70 }, 79 refresh: function() {80 this.titleNode.innerHTML = this.survey.title || "(set title in properties)";81 this.propertiesDialog.set('value',this.survey);82 },83 71 _onShowProperties: function(evt) { 84 72 this.propertiesDialog.show(); 73 if ( evt ) { event.stop(evt); } 74 return false; 85 75 }, 86 76 _onPropertiesOk: function(evt) { 87 77 this.propertiesDialog.hide(); 88 lang.mixin(this.survey, this.propertiesDialog.get('value')); 89 this.refresh(); 90 event.stop(evt); 78 lang.mixin(this.object, this.propertiesDialog.get('value')); 79 this.markDirty(); 80 this._refresh(); 81 if ( evt ) { event.stop(evt); } 91 82 return false; 92 83 }, 93 84 _onPropertiesCancel: function(evt) { 94 85 this.propertiesDialog.hide(); 95 this.propertiesDialog. reset('value',this.survey);96 event.stop(evt);86 this.propertiesDialog.set('value',this.object); 87 if ( evt ) { event.stop(evt); } 97 88 return false; 98 89 }, 99 90 _onSave: function(evt) { 100 this.survey.questions = this.questionList.get('value'); 101 surveys.save(this.survey) 91 this._save(); 92 if ( evt ) { event.stop(evt); } 93 return false; 94 }, 95 _onSaveAndClose: function(evt) { 96 this._save() 102 97 .then(function() { 103 Router.go( '/surveys');98 Router.go(surveys.getCollectionPath()); 104 99 }); 105 100 event.stop(evt); 106 101 return false; 107 102 }, 108 _onDiscard: function(evt) { 109 Router.go('/surveys'); 103 _onDiscardAndClose: function(evt) { 104 this.markClean(); 105 Router.go(surveys.getCollectionPath()); 110 106 }, 111 107 _onShowPreview: function() { 112 Router.go( '/previewSurvey/'+this.survey._id,{108 Router.go(surveys.getPreviewPath(this.object),{ 113 109 preview: true 114 110 }); -
Dev/trunk/src/client/qed-client/pages/surveyRun.js
r487 r490 1 1 define([ 2 2 "../app/Content", 3 "../app/Pa ge",3 "../app/Path", 4 4 "../app/Router", 5 5 "../lib/func", 6 6 "../model/classes/responses", 7 7 "../model/classes/surveyRuns", 8 "../model/classes/surveys", 8 9 "../widgets/LineWithActionsWidget", 10 "./_ObjectPage", 11 "dojo/Deferred", 9 12 "dojo/_base/array", 10 13 "dojo/_base/declare", … … 14 17 "require", 15 18 "dojo/text!./templates/surveyRun.html" 16 ], function(Content, Pa ge, Router, func, responses, surveyRuns, LineWithActionsWidget, array, declare, event, lang, when, require, template) {17 return declare([ Page],{19 ], function(Content, Path, Router, func, responses, surveyRuns, surveys, LineWithActionsWidget, _ObjectPage, Deferred, array, declare, event, lang, when, require, template) { 20 return declare([_ObjectPage],{ 18 21 contextRequire: require, 19 22 templateString: template, 20 surveyRun: null,23 classStore: surveyRuns, 21 24 startup: function() { 22 25 if ( this._started ) { return; } 23 26 this.inherited(arguments); 24 this.surveyRunWidget.on("blur",lang.hitch(this,'_onPropChange')); 25 if ( this.surveyRunId ) { 26 this._loadSurveyRun(); 27 this.surveyRunWidget.on("change",lang.hitch(this,'_onPropChange')); 28 this._load(); 29 }, 30 _refresh: function() { 31 this.titleNode.innerHTML = this.object.title || ""; 32 this.surveySummaryWidget.set('value',this.object.survey); 33 this.surveyRunWidget.set('value',this.object); 34 this._refreshURL(); 35 this._loadResponses(); 36 }, 37 _refreshURL: function() { 38 if ( this.object.mode === "open" ) { 39 this.runURLNode.innerHTML = 40 this._link(this._buildGeneralURL(this.object)); 27 41 } else { 28 throw "No valid uid or survey passed!"; 42 this.runURLNode.innerHTML = 43 "No general URL. Add individual respondents below."; 29 44 } 30 45 }, 31 _loadSurveyRun: function() {32 when(surveyRuns.load(this.surveyRunId))33 .then(lang.hitch(this,function(surveyRun){34 this.surveyRun = surveyRun;35 this.refreshSurveyRun();36 this._loadResponses();37 }));38 },39 refreshSurveyRun: function() {40 this.titleNode.innerHTML = this.surveyRun.title || "";41 this.surveySummaryWidget.set('value',this.surveyRun.survey);42 this.surveyRunWidget.set('value',this.surveyRun);43 this._onPropChange();44 },45 46 _loadResponses: function() { 46 responses.query({surveyRunId:surveyRuns.getId(this. surveyRun)})47 responses.query({surveyRunId:surveyRuns.getId(this.object)}) 47 48 .then(lang.hitch(this,function(allResponses){ 48 49 array.forEach(allResponses, function(response){ … … 73 74 }, 74 75 _onPropChange: function(e) { 75 var surveyRun = this.surveyRunWidget.get('value'); 76 if ( surveyRun.mode === "open" ) { 77 this.runURLNode.innerHTML = 78 this._link(this._buildGeneralURL(this.surveyRun)); 79 } else { 80 this.runURLNode.innerHTML = 81 "No general URL. Add individual respondents below."; 76 if ( this.surveyRunWidget.validate() ) { 77 lang.mixin(this.object,this.surveyRunWidget.get('value')); 78 this._refreshURL(); 82 79 } 80 this.markDirty(); 83 81 }, 84 82 _buildGeneralURL: function(surveyRun) { 85 return 'response.html# !/surveyRuns/'+surveyRuns.getId(surveyRun)+'!secret='+surveyRun.secret;83 return 'response.html#'+Path.format(surveyRuns.getObjectPath(surveyRun),{secret:surveyRun.secret}); 86 84 }, 87 85 _buildResponseURL: function(response) { 88 return 'response.html# !/responses/'+responses.getId(response)+'!secret='+response.secret;86 return 'response.html#'+Path.format(responses.getObjectPath(response),{secret:response.secret}); 89 87 }, 90 88 _link: function(url,label) { 91 89 return '<a target="_blank" href="'+url+'">'+(label || url)+'</a>'; 92 90 }, 91 _save: function() { 92 if ( this.surveyRunWidget.validate() ) { 93 lang.mixin(this.object,this.surveyRunWidget.get('value')); 94 return this.inherited(arguments); 95 } else { 96 return new Deferred.reject(); 97 } 98 }, 93 99 _onSave: function(evt) { 94 if ( this.surveyRunWidget.validate() ) { 95 lang.mixin(this.surveyRun,this.surveyRunWidget.get('value')); 96 97 surveyRuns.save(this.surveyRun) 98 .then(function() { 99 Router.go('/surveys'); 100 },function(err){ 101 Content.notify(err); 102 }); 103 } 100 this._save(); 101 if ( evt ) { event.stop(evt); } 102 return false; 103 }, 104 _onSaveAndClose: function(evt) { 105 this._save() 106 .then(function() { 107 Router.go(surveys.getCollectionPath()); 108 }); 104 109 if ( evt ) { event.stop(evt); } 105 110 return false; 106 111 }, 107 112 _onDiscard: function(evt) { 108 Router.go('/surveys'); 113 this.markClean(); 114 Router.go(surveys.getCollectionPath()); 109 115 if ( evt ) { event.stop(evt); } 110 116 return false; -
Dev/trunk/src/client/qed-client/pages/surveys.js
r487 r490 1 1 define([ 2 "../app/Content",3 2 "../app/Page", 4 3 "../app/Router", 4 "../model/classes/surveyRuns", 5 5 "../model/classes/surveys", 6 "../model/classes/surveyRuns",7 6 "../widgets/LineWithActionsWidget", 8 7 "dojo/_base/array", … … 11 10 "dojo/when", 12 11 "dojo/text!./templates/surveys.html" 13 ], function( Content, Page, Router, surveys, surveyRuns, LineWithActionsWidget, array, declare, lang, when, template) {12 ], function(Page, Router, surveyRuns, surveys, LineWithActionsWidget, array, declare, lang, when, template) { 14 13 return declare([Page],{ 15 14 templateString: template, … … 20 19 }, 21 20 _onNewSurvey: function(){ 22 Router.go( '/survey/new');21 Router.go(surveys.getObjectPath('new')); 23 22 }, 24 23 _onPublishSurvey:function(survey){ … … 29 28 self.refreshDrafts(); 30 29 self.refreshPublished(); 31 }, function(err){32 Content.notify(err,'error');33 }) ;30 },lang.hitch(this,function(err){ 31 this.notify(err.error,'error'); 32 })); 34 33 }, 35 34 _onDeleteSurvey:function(survey){ … … 38 37 .then(function(){ 39 38 self.refreshDrafts(); 40 }, function(err){41 Content.notify(err,'error');42 }) ;39 },lang.hitch(this,function(err){ 40 this.notify(err.error,'error'); 41 })); 43 42 }, 44 43 _onEditSurvey:function(survey){ 45 Router.go( '/survey/'+survey._id);44 Router.go(surveys.getObjectPath(survey)); 46 45 }, 47 46 _onPreviewSurvey:function(survey){ 48 Router.go( '/previewSurvey/'+survey._id);47 Router.go(surveys.getPreviewPath(survey)); 49 48 }, 50 49 _onRunSurvey:function(survey){ … … 54 53 .then(lang.hitch(this,function(surveyRun){ 55 54 this._onRunDetails(surveyRun); 56 }), function(err){57 Content.notify(err);58 }) ;55 }),lang.hitch(this,function(err){ 56 this.notify(err.error,'error'); 57 })); 59 58 }, 60 59 _onRunDetails: function(surveyRun) { 61 Router.go( '/surveyRun/'+surveyRun._id);60 Router.go(surveyRuns.getObjectPath(surveyRun)); 62 61 }, 63 62 refresh: function() { -
Dev/trunk/src/client/qed-client/pages/templates/question.html
r466 r490 1 < formclass="orange">1 <div class="orange"> 2 2 <div data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'top'"> 3 3 <h2> … … 6 6 </h2> 7 7 </div> 8 <div data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="region:'left', design:'headline'" style="width: 300px;"> 9 <div data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'center'"> 10 <div data-dojo-attach-point="QuestionEditorToolkitNode"></div> 8 <form data-dojo-type="dijit/form/Form" 9 data-dojo-props="region:'left'" 10 data-dojo-attach-point="propertiesForm" 11 data-dojo-attach-event="onSubmit:_ignore"> 12 <div data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="design:'headline'" style="width: 300px;"> 13 <div data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'center'"> 14 <div data-dojo-type="../model/widgets/QuestionEditorToolkit" 15 data-dojo-attach-point="QuestionEditorToolkitNode"></div> 16 </div> 17 <div data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'top'"> 18 <button data-dojo-type="dijit/form/Button" 19 data-dojo-props="baseClass: 'rftLargeButton', iconClass: 'rftIcon rftIconAccept'" 20 data-dojo-attach-event="onClick:_onSave"> 21 Save</button> 22 <button data-dojo-type="dijit/form/Button" 23 data-dojo-props="baseClass: 'rftLargeButton', iconClass: 'rftIcon rftIconAccept'" 24 data-dojo-attach-event="onClick:_onSaveAndClose"> 25 Save & Close</button> 26 <button data-dojo-type="dijit/form/Button" 27 data-dojo-props="baseClass: 'rftLargeButton', iconClass: 'rftIcon rftIconCancel'" 28 data-dojo-attach-event="onClick:_onDiscard"> 29 Discard & Close</button> 30 </div> 11 31 </div> 12 <div data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'top'"> 13 <button data-dojo-type="dijit/form/Button" data-dojo-props="baseClass: 'rftLargeButton', iconClass: 'rftIcon rftIconCancel'" data-dojo-attach-event="onClick:_onDiscard">Discard</button> 14 <button data-dojo-type="dijit/form/Button" data-dojo-props="baseClass: 'rftLargeButton', iconClass: 'rftIcon rftIconAccept'" data-dojo-attach-event="onClick:_onSave">Save and exit</button> 15 </div> 16 </div> 17 </form> 32 </form> 33 <div data-dojo-type="../model/widgets/QuestionEditorPreview" 34 data-dojo-attach-point="contentList" 35 data-dojo-props="name:'content',delay:5,region:'center'"></div> 36 </div> -
Dev/trunk/src/client/qed-client/pages/templates/survey.html
r457 r490 24 24 data-dojo-attach-event="onClick:_onSave" 25 25 data-dojo-props="baseClass: 'rftLargeButton', iconClass: 'rftIcon rftIconAccept'"> 26 Save Changes</button>26 Save</button> 27 27 <button data-dojo-type="dijit/form/Button" 28 data-dojo-attach-event="onClick:_onDiscard" 28 data-dojo-attach-event="onClick:_onSaveAndClose" 29 data-dojo-props="baseClass: 'rftLargeButton', iconClass: 'rftIcon rftIconAccept'"> 30 Save & Close</button> 31 <button data-dojo-type="dijit/form/Button" 32 data-dojo-attach-event="onClick:_onDiscardAndClose" 29 33 data-dojo-props="baseClass: 'rftLargeButton', iconClass: 'rftIcon rftIconCancel'"> 30 Discard changes</button>34 Discard & Close</button> 31 35 <button data-dojo-type="dijit/form/Button" 32 36 data-dojo-attach-event="onClick:_onShowPreview" -
Dev/trunk/src/client/qed-client/pages/templates/surveyRun.html
r467 r490 45 45 <div> 46 46 <div class="qedLabel">Export results</div> 47 <a target="_blank" href="/api/surveyRuns/${ surveyRunId}/responses.csv" class="qedField">To CSV</a>47 <a target="_blank" href="/api/surveyRuns/${objectId}/responses.csv" class="qedField">To CSV</a> 48 48 </div> 49 49 </fieldset> … … 55 55 class="blue" 56 56 data-dojo-props="baseClass: 'rftBlockButton', iconClass: 'rftIcon rftIconSave'" 57 data-dojo-attach-event="onClick:_onSave">Save & Close</button> 57 data-dojo-attach-event="onClick:_onSave">Save</button> 58 <button data-dojo-type="dijit/form/Button" 59 class="blue" 60 data-dojo-props="baseClass: 'rftBlockButton', iconClass: 'rftIcon rftIconSave'" 61 data-dojo-attach-event="onClick:_onSaveAndClose">Save & Close</button> 58 62 <button data-dojo-type="dijit/form/Button" 59 63 class="blue" -
Dev/trunk/src/client/qed-client/response.js
r487 r490 42 42 43 43 function setContent(response) { 44 hash(Path.format( "/responses/"+responses.getId(response),44 hash(Path.format(responses.getObjectPath(response), 45 45 {secret:response.secret})); 46 46 Content.set(new ResponsePage({ -
Dev/trunk/src/client/qed-client/routes.js
r487 r490 1 1 define([ 2 "./model/classes/questions", 3 "./model/classes/surveyRuns", 4 "./model/classes/surveys", 2 5 "./pages/index", 3 6 "./pages/previewSurvey", … … 7 10 "./pages/surveyRun", 8 11 "./pages/surveys" 9 ], function( index, previewSurvey, question, questions, survey, surveyRun, surveys) {12 ], function(questionsClass, surveyRunsClass, surveysClass, index, previewSurvey, question, questions, survey, surveyRun, surveys) { 10 13 11 14 return [ 12 15 { path: "/", redirect: "/index" }, 13 16 { path: "/index", constructor: index }, 14 { path: "/questions", constructor: questions },15 { path: "/question/:questionId", constructor: question },16 { path: "/surveys", constructor: surveys },17 { path: "/survey/:surveyId", constructor: survey },18 { path: "/surveyRun/:surveyRunId", constructor: surveyRun },17 { path: questionsClass.getCollectionPath(), constructor: questions }, 18 { path: questionsClass.getObjectPath(':objectId'), constructor: question }, 19 { path: surveysClass.getCollectionPath(), constructor: surveys }, 20 { path: surveysClass.getObjectPath(':objectId'), constructor: survey }, 21 { path: surveyRunsClass.getObjectPath(':objectId'), constructor: surveyRun }, 19 22 //{ path: "/sessions", constructor: sessions }, 20 23 //{ path: "/session/:sessionId", constructor: session }, 21 { path: "/previewSurvey/:surveyId", constructor: previewSurvey }24 { path: surveysClass.getPreviewPath(':surveyId'), constructor: previewSurvey } 22 25 ]; 23 26 -
Dev/trunk/src/client/qed-client/stddeps.js
r487 r490 28 28 './app/Notifications', 29 29 30 './model/widgets/QuestionEditorPreview', 31 './model/widgets/QuestionEditorToolkit', 32 './model/widgets/AccountListView', 30 33 './model/widgets/AccountListView', 31 34 './model/widgets/SurveyRenderWidget', -
Dev/trunk/src/client/qed-client/widgets/LineWithActionsWidget.js
r472 r490 44 44 onClick: lang.hitch(this, function(action, e){ 45 45 if ( action.callback ) { action.callback(e); } 46 event.stop(e);46 if ( e ) { event.stop(e); } 47 47 return false; 48 48 }, this.actions[action]) … … 58 58 onClick: lang.hitch(this, function(action, e){ 59 59 if ( action.callback ) { action.callback(e); } 60 event.stop(e);60 if ( e ) { event.stop(e); } 61 61 return false; 62 62 }, this.actions[action]) … … 73 73 var preventDefault = this.onClick(e) === false; 74 74 if (preventDefault) { 75 event.stop(e);75 if ( e ) { event.stop(e); } 76 76 } 77 77 return !preventDefault; -
Dev/trunk/src/client/qed-client/widgets/ListWidget.js
r443 r490 8 8 "dojo/dnd/Source", 9 9 "dojo/dnd/common", 10 "dojo/dom-construct" 11 ], function(_Container, _WidgetBase, registry, array, declare, lang, Source, dnd, domConstruct) { 10 "dojo/dom-construct", 11 "dojo/on" 12 ], function(_Container, _WidgetBase, registry, array, declare, lang, Source, dnd, domConstruct, on) { 12 13 return declare([_WidgetBase,_Container],{ 13 14 name: "", … … 49 50 }); 50 51 this.source = new this.container(this.domNode,sourceParams); 52 this.source.on('Drop',lang.hitch(this,'_handleChange')); 51 53 }, 52 54 creator: function(item, hint) { … … 66 68 } 67 69 } 70 on(nodeOrWidget,'change',lang.hitch(this,'_handleChange')); 68 71 var node = nodeOrWidget.domNode ? nodeOrWidget.domNode : nodeOrWidget; 69 72 if ( hint !== "avatar" && node.id !== id ) { … … 79 82 createListElement: null, /* function(id,item){},*/ 80 83 _getValueAttr: function() { 81 returnarray.map(this.source.getAllNodes(),function(node){84 this.value = array.map(this.source.getAllNodes(),function(node){ 82 85 var widget = registry.byNode(node); 83 86 if ( widget && "value" in widget ) { … … 87 90 } 88 91 },this); 92 return this.value; 89 93 }, 90 94 _setValueAttr: function(value) { … … 110 114 } 111 115 }, 112 appendItems: function(items ) {116 appendItems: function(items,forceEvent) { 113 117 this.source.insertNodes(false,items); 118 if ( forceEvent ) { this._handleChange(); } 114 119 }, 115 appendItem: function(item ) {120 appendItem: function(item,forceEvent) { 116 121 this.source.insertNodes(false,[item]); 122 if ( forceEvent ) { this._handleChange(); } 117 123 }, 118 removeItem: function(key ) {124 removeItem: function(key,forceEvent) { 119 125 array.forEach(array.filter(this.source.getAllNodes(), function(node){ 120 126 return node.id === key; 121 127 }), lang.hitch(this, "_destroyNodeOrWidget")); 122 128 this.source.delItem(key); 129 if ( forceEvent ) { this._handleChange(); } 123 130 }, 124 131 getChildren: function() { … … 127 134 }),function(widget){ return widget !== null; }); 128 135 }, 129 clear: function( ) {136 clear: function(forceEvent) { 130 137 array.forEach(this.source.getAllNodes(), 131 138 lang.hitch(this, "_destroyNodeOrWidget")); 132 139 this.source.clearItems(); 140 if ( forceEvent ) { this._handleChange(); } 133 141 }, 134 142 _destroyNodeOrWidget: function(node) { … … 149 157 this.source.destroy(); 150 158 this.inherited(arguments); 151 } 159 }, 160 _handleChange: function() { 161 this.value = this._getValueAttr(); 162 this.onChange(this.value); 163 }, 164 onChange: function(value) {} 152 165 }); 153 166 }); -
Dev/trunk/src/server/app.js
r487 r490 149 149 function identity(obj) { return obj; } 150 150 function handleUnknownResponse(status,error){ 151 return new HTTPResult(500,{error: "Unexpected database response", 152 innerStatus: status, innerResponse: error}); 151 return new HTTPResult(500,{error: error.reason}); 153 152 } 154 153 function handleUnknownError(error){ … … 393 392 .handle({ 394 393 200: function(others) { 395 if ( others.length > 0 ) {394 if ( others.length > 0 && _.some(others,function(other){ return other._id !== id; }) ) { 396 395 return new HTTPResult(403,{error:"Other question with this code already exists."}); 397 396 } else {
Note: See TracChangeset
for help on using the changeset viewer.