Changeset 420
- Timestamp:
- 12/16/12 20:07:35 (12 years ago)
- Location:
- Dev/branches/rest-dojo-ui
- Files:
-
- 20 added
- 1 deleted
- 18 edited
- 2 copied
- 6 moved
Legend:
- Unmodified
- Added
- Removed
-
Dev/branches/rest-dojo-ui/client/admin.html
r419 r420 8 8 <body class="dijitReset claro" id="rft"> 9 9 <script type="text/javascript" src="dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: false, isDebug: true"></script> 10 <script type="text/javascript" src="qed/ run.js"></script>10 <script type="text/javascript" src="qed/main-admin.js"></script> 11 11 <div id="content" class="page" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="region:'center'" style="width: 100%; height: 100%;"> 12 12 <div class="topbar" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'top'"> -
Dev/branches/rest-dojo-ui/client/index.html
r419 r420 7 7 </head> 8 8 <body class="dijitReset claro" id="rft"> 9 <script type="text/javascript" src="dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: false, isDebug: true"></script> 10 <script type="text/javascript" src="qed/run.js"></script> 11 <div id="content" class="page" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="region:'center'" style="width: 100%; height: 100%;"> 12 <div class="topbar" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'top'"> 13 <a href="#!/"><h1>QED</h1></a> 14 <div id="menu"></div> 15 </div> 9 <div class="topbar"> 10 <h1>QED</h1><br> 11 <p>Nothing is shown here.</p> 16 12 </div> 17 <div id="toaster" data-dojo-type="qed/app/Notifications"></div>18 13 </body> 19 14 </html> -
Dev/branches/rest-dojo-ui/client/qed/app/Notifications.js
r418 r420 3 3 return declare([Toaster],{ 4 4 positionDirection: "br-up", 5 duration: 10005 duration: 3000 6 6 }); 7 7 }); -
Dev/branches/rest-dojo-ui/client/qed/app/Router.js
r410 r420 2 2 'dojo/_base/declare', 3 3 'dojo/hash', 4 'dojo/io-query',5 4 'dojo/topic', 6 5 './Content', 7 './Page' 8 ],function(declare,hash,ioQuery,topic,Content,Page){ 6 './Page', 7 './Path' 8 ],function(declare,hash,topic,Content,Page,Path){ 9 9 10 10 var Router = declare(null,{ … … 12 12 _routes: null, 13 13 _previousHash: null, 14 15 _paramMatch: /:(\w[\w\d]*)/g,16 _paramReplace: "([^\\/!]+)",17 14 18 15 constructor: function() { … … 29 26 30 27 if ( hash() === "" ) { 31 hash( "#!/");28 hash(Path.getDefault()); 32 29 } 33 30 this._handlePathChange(hash()); … … 40 37 console.warn('Registering routes after startup() is called is discouraged.'); 41 38 } 39 var callback = this._normalizeCallback(route); 40 if ( callback ) { 41 if ( route.path ) { 42 route.callback = callback; 43 route.path = new Path(route.path); 44 this._routes.push(route); 45 } else { 46 this._defaultCallback = callback; 47 } 48 } else { 49 console.warn("Route "+(route.path||"default")+" has no action."); 50 } 51 }, 52 _normalizeCallback: function(route) { 42 53 var self = this; 43 var callback ;54 var callback = null; 44 55 if ( route.callback ) { 45 56 callback = function(params){ … … 55 66 }; 56 67 } 57 if ( callback ) { 58 if ( route.path ) { 59 this._routes.push(this._createRoute(route.path,callback)); 60 } else { 61 this._defaultCallback = callback; 62 } 63 } else { 64 console.warn("Route "+(route.path||"default")+" has no action."); 65 } 66 }, 67 _createRoute: function(path,callback) { 68 var match, route = {}; 69 route.callback = callback; 70 route.paramNames = []; 71 while((match = this._paramMatch.exec(path)) !== null){ 72 route.paramNames.push(match[1]); 73 } 74 path = path.replace(this._paramMatch, this._paramReplace); 75 route.regexp = new RegExp('^!'+path+'(!(.*))?$'); 76 return route; 68 return callback; 77 69 }, 78 70 _handlePathChange: function(newHash) { 79 71 if ( this._previousHash === newHash ) { return; } 80 72 this._previousHash = newHash; 81 82 73 for (var i = this._routes.length-1; i >= 0; i--) { 83 var result;84 74 var route = this._routes[i]; 85 86 if ((result = route.regexp.exec(newHash)) !== null) { 87 var numParams = route.paramNames.length; 88 89 var params = {}; 90 for (var j = 0; j < numParams; j++) { 91 params[route.paramNames[j]] = result[j+1]; 92 } 93 94 if ( result.length > numParams+1 && result[numParams+2] ) { 95 params.options = ioQuery.queryToObject(result[numParams+2]); 96 } 97 75 var params = null; 76 if ((params = route.path.match(newHash)) !== null) { 98 77 try { 99 78 route.callback(params); 100 79 } catch(err) { 101 console. warn("Page change failed.",err);80 console.error("Page change failed.",err); 102 81 } 103 82 return; 104 83 } 105 84 } 106 107 85 try { 108 86 this._defaultCallback(); 109 87 } catch(err) { 110 console. warn("Default page failed.",err);88 console.error("Default page failed.",err); 111 89 } 112 90 }, 113 91 go: function(path,args) { 114 92 if ( !this._started ) { return; } 115 var newHash = this._pathToHash(path,args);93 var newHash = Path.format(path,args); 116 94 this._handlePathChange(newHash); 117 95 hash(newHash); 118 96 }, 119 _pathToHash: function(path,args) {120 var hash = '!'+path;121 if ( args ) {122 hash += '!'+ioQuery.objectToQuery(args);123 }124 return hash;125 },126 97 _defaultCallback: function() { 127 98 Content.set(new Page({ 128 templateString: "<div>Requested page not found. Go <a href=\"# !/\">home</a>.</div>"99 templateString: "<div>Requested page not found. Go <a href=\"#"+Path.getDefault()+"\">home</a>.</div>" 129 100 })); 130 101 } -
Dev/branches/rest-dojo-ui/client/qed/css/main.css
r412 r420 1 1 /* Menu.css */ 2 2 @import "external.css"; 3 @import "hva-mods.css"; 3 4 DESCRIPTION { 4 5 /* -
Dev/branches/rest-dojo-ui/client/qed/lib/async.js
r415 r420 1 1 define([ 2 'dojo/Deferred', 3 ],function(Deferred){ 2 'dojo/_base/array', 3 'dojo/_base/lang', 4 'dojo/when', 5 'dojo/Deferred' 6 ],function(array,lang,when,Deferred){ 4 7 5 function seq(functions) { 8 /** Execute possible async functions in sequence 9 * Execute functions in order. When a function returns a Promise, 10 * the next function is only executed when the promise resolves. 11 * If the function returns a value, the next function is executed 12 * synchronously. The return value of every function is passed as argument 13 * to the next. 14 * Returns the return value of the last function in the chain. 15 */ 16 function seq(functions,ctx) { 6 17 var d = new Deferred(); 7 (function stepper(fs,arg) { 18 19 var cancelled = false; 20 var running = null; 21 function cancel(err) { 22 if ( cancelled ) return; 23 cancelled = true; 24 running && running.cancel && !running.isFulfilled() && running.cancel(); 25 d.reject(err); 26 } 27 28 function update(fs,arg) { 29 if ( cancelled ) return; 8 30 if ( fs.length > 0 ) { 9 31 try { 10 32 var f = fs.shift(); 11 var ret = f(arg); 12 if ( ret && ret.then ) { 13 ret.then(function(ret){ 14 stepper(fs,ret); 15 }); 16 } else { 17 stepper(fs,ret); 18 } 33 running = when(f.call(ctx,arg)) 34 .then(function(res){ 35 update(fs,res); 36 },function(err){ 37 cancel(err); 38 }); 19 39 } catch(err) { 20 d.reject(err);40 cancel(err); 21 41 } 22 42 } else { 23 d.resolve( );43 d.resolve(arg); 24 44 } 25 })(functions); 45 } 46 47 update(functions); 48 26 49 return d.promise; 27 50 } 28 51 52 /** Execute possible async functions in parallel 53 * Execute all functions in parallel, resolve only when all have resolved. 54 * NB. When a function is not async, it will fully complete before the next 55 * async function is started. If you mix async and non async functions, put 56 * the sync functions last to fully exploit the async ones. 57 * Return an array with all the return values of the functions. 58 */ 59 function par(functions,ctx) { 60 var d = new Deferred(cancel); 61 62 var cancelled = false; 63 var running = []; 64 function cancel(err) { 65 if (cancelled) return; 66 cancelled = true; 67 array.forEach(running,function(running){ 68 running && running.cancel && !running.isFulfilled() && running.cancel(); 69 }); 70 d.reject(err); 71 } 72 73 var results = []; 74 var left = functions.length; 75 function update(res,idx) { 76 if (cancelled) return; 77 results[idx] = res; 78 left -= 1; // Works because/as long as AJAX/JS is single-threaded. 79 if ( left === 0 ) { 80 d.resolve(results); 81 } 82 } 83 84 array.forEach(functions,function(f,idx){ 85 if (cancelled) return; 86 try { 87 running.push(when(f.call(ctx)).then(function(res){ 88 update(res,idx); 89 },function(err){ 90 cancel(err); 91 })); 92 } catch (err) { 93 cancel(); 94 } 95 }); 96 97 return d.promise; 98 } 99 100 /** Iterate over an array with async callback 101 * Execute the callback and if it's async, wait until it's finished before 102 * executing the next one. 103 */ 29 104 function forEach(list,callback,ctx) { 30 var d = new Deferred(); 31 (function stepper(list,idx){ 32 if ( list.length > 0 ) { 33 var el = list.shift(); 34 var ret = callback.call(ctx,el,idx); 35 if ( ret && ret.then ) { 36 ret.then(function(){ 37 stepper(list,idx+1); 38 }); 39 } else { 40 stepper(list,idx+1); 41 } 42 } else { 43 d.resolve(); 44 } 45 })(list,0); 46 return d.promise; 105 var fs = array.map(list,function(item,index,items){ 106 return lang.hitch(ctx,callback,item,index,items); 107 }); 108 return seq(fs); 109 } 110 111 /** Map a list, possible async 112 * Map every element of a list, returning a promise to the mapped list. 113 */ 114 function map(list,callback,ctx) { 115 var fs = array.map(list,function(item,index,items){ 116 return lang.hitch(ctx,callback,item,index,items); 117 }); 118 return par(fs); 47 119 } 48 120 49 121 return { 50 122 seq: seq, 51 forEach: forEach 123 par: par, 124 forEach: forEach, 125 map: map 52 126 }; 53 127 -
Dev/branches/rest-dojo-ui/client/qed/main-response.js
r419 r420 1 1 require([ 2 'dojo/date', 3 'dojo/date/locale', 2 4 'dojo/hash', 3 5 'dojo/parser', 6 'qed/store', 4 7 'qed/app/Content', 5 8 'qed/app/Page', 6 'qed/pages/viewSurvey', 9 'qed/app/Path', 10 'qed/lib/async', 11 'qed/model/classes/Response', 12 'qed/model/classes/SurveyRun', 13 'qed/pages/response', 7 14 'dojo/domReady!', 8 15 'qed/stddeps' 9 ],function( hash,parser,Content,Page,viewSurvey) {16 ],function(date,locale,hash,parser,store,Content,Page,Path,async,Response,SurveyRun,response) { 10 17 parser.parse(); 11 18 Content.startup(); 12 19 13 var match = /^!\/(\w+)$/g.exec(hash()); 14 if ( !match ) { 20 function error(msg) { 15 21 Content.set(new Page({ 16 templateString: "<div> Something is wrong with the URL, don't know what survey to show you. Sorry.</div>"22 templateString: "<div>"+msg+"</div>" 17 23 })); 24 } 25 26 var path = new Path('/:surveyRunId'); 27 var params = path.match(hash()); 28 params.options = params.options || {}; 29 30 if ( !params || !params.surveyRunId ) { 31 error("Something is wrong with the URL, don't know what survey to show you. Sorry."); 18 32 return; 19 33 } 20 var surveyId = match[1];21 34 22 // read options from hash/url 23 // 24 // authenticate 35 var surveyRunId = params.surveyRunId; 25 36 26 Content.set(new viewSurvey({ 27 surveyId: surveyId 28 })); 37 function checkDates(surveyRun) { 38 var now = new Date(); 39 var startDate = SurveyRun.StartDate.get(surveyRun); 40 var endDate = SurveyRun.EndDate.get(surveyRun); 41 if ( startDate && date.compare(startDate,now) > 0 ) { 42 error("This survey will start on "+locale.format(startDate,'date')); 43 throw false; 44 } 45 if ( endDate && date.compare(now,endDate) > 0 ) { 46 error("This survey ended on "+locale.format(endDate,'date')); 47 throw false; 48 } 49 } 50 51 store.get(surveyRunId) 52 .then(function(surveyRun){ 53 checkDates(surveyRun); 54 if ( params.options.id ) { 55 return params.options.id; 56 } else { 57 if ( surveyRun.mode === "open") { 58 var response = Response.create(); 59 response.surveyRunId = surveyRunId; 60 return store.put(response).then(function(res){ 61 return store.getIdentity(res); 62 }); 63 } else { 64 error("Cannot respond to closed survey without response id. Sorry."); 65 throw false; 66 } 67 } 68 return surveyRun; 69 },function(){ 70 error("No running survey found for the given id. Sorry."); 71 throw false; 72 }) 73 .then(function(responseId){ 74 hash(Path.format("/"+surveyRunId,{ id: responseId })); 75 Content.set(new response({ 76 surveyRunId: surveyRunId, 77 options: { 78 id: responseId 79 } 80 })); 81 }); 29 82 }); -
Dev/branches/rest-dojo-ui/client/qed/model/schema.js
r417 r420 74 74 // 75 75 76 var Respondent = dbobject('Respondent',{ 77 secret: nestring() 78 }); 79 80 var Question = dbobject('Question',{ 81 code:nestring(), 82 title: nestring(), 83 description: string(optional()), 84 topic: string(optional()), 85 categories: array(nestring(),optional()), 86 content: array([ 87 typedobject('Header',{ 88 content:string(optional()) 89 }), 90 typedobject('Text',{ 91 content:string(optional()) 92 }), 93 typedobject('Divider'), 94 typedobject('StringInput'), 95 typedobject('TextInput',{ 96 maxLength:integer() 97 }), 98 typedobject('IntegerInput',{ 99 min:integer(), 100 max:integer(), 101 step:integer() 102 }), 103 typedobject('MultipleChoiceInput',{ 104 multiple:boolean(), 105 items:array(nestring()) 106 }) 107 ],optional()), 108 publicationDate:datetime(optional()) 109 }); 110 111 var Survey = dbobject('Survey',{ 112 title: nestring(), 113 description: string(optional()), 114 questions: array(Question,optional()), 115 publicationDate:datetime(optional()) 116 }); 117 118 var SurveyRun = dbobject('SurveyRun',{ 119 description: string(optional()), 120 survey: Survey, 121 publicationDate:datetime(optional()), 122 startDate:datetime(optional()), 123 endDate:datetime(optional()), 124 mode:{type:'string',enum:['open','closed'],optional:true}, 125 metadata:string(optional()) 126 }); 127 128 var Response = dbobject('Response',{ 129 surveyRunId: nestring(), 130 answers:{type:'object',optional:true}, 131 publicationDate:datetime(optional()) 132 }); 133 134 var Session = dbobject('Session',{ 135 title: nestring(), 136 description: string(optional()), 137 publicationDate: datetime(optional()) 138 }); 139 140 var SessionTemplate = dbobject('SessionTemplate',{ 141 title: nestring(), 142 description: string(optional()), 143 publicationDate: datetime(optional()), 144 plannedDate: datetime(optional()) 145 }); 146 76 147 var schema = {type:[ 77 dbobject('Question',{ 78 code:nestring(), 79 title: nestring(), 80 description: string(optional()), 81 topic: string(optional()), 82 categories: array(nestring(),optional()), 83 content: array([ 84 typedobject('Header',{ 85 content:string(optional()) 86 }), 87 typedobject('Text',{ 88 content:string(optional()) 89 }), 90 typedobject('Divider'), 91 typedobject('StringInput'), 92 typedobject('TextInput',{ 93 maxLength:integer() 94 }), 95 typedobject('IntegerInput',{ 96 min:integer(), 97 max:integer(), 98 step:integer() 99 }), 100 typedobject('MultipleChoiceInput',{ 101 multiple:boolean(), 102 items:array(nestring()) 103 }) 104 ],optional()), 105 publicationDate:datetime(optional()) 106 }), 107 dbobject('Survey',{ 108 title: nestring(), 109 description: string(optional()), 110 questions: array(nestring(),optional()), 111 publicationDate:datetime(optional()) 112 }), 113 dbobject('SurveyRun',{ 114 description: string(optional()), 115 surveyId: nestring(), 116 publicationDate:datetime(optional()), 117 startDate:datetime(), 118 endDate:datetime(), 119 mode:{type:'string',enum:['open','closed']}, 120 respondents: array(nestring(),optional()), 121 metadata:{type:'object',optional:true} 122 }), 123 dbobject('Session',{ 124 title: nestring(), 125 description: string(optional()), 126 publicationDate: datetime(optional()) 127 }), 128 dbobject('SessionTemplate',{ 129 title: nestring(), 130 description: string(optional()), 131 publicationDate: datetime(optional()), 132 plannedDate: datetime(optional()) 133 }) 148 Question, 149 Survey, 150 SurveyRun, 151 Response, 152 Session, 153 SessionTemplate 134 154 ]}; 135 155 -
Dev/branches/rest-dojo-ui/client/qed/model/widgets/templates/SurveyRunFieldset.html
r419 r420 1 <fieldset class="${baseClass} ">1 <fieldset class="${baseClass} qedFieldset"> 2 2 3 <label for="mode" class="loginLabel">Description</label> 4 <textarea name="description" data-dojo-type="dijit/form/Textarea"></textarea> 5 <br> 3 <div> 4 <label for="mode" class="qedLabel">Description</label> 5 <textarea name="description" class="qedField" data-dojo-type="dijit/form/Textarea"></textarea> 6 </div> 6 7 7 <label for="startDate" class="loginLabel">Start date</label> 8 <input type="text" name="startDatetime" data-dojo-type="qed/widgets/DateTimeTextBox" /> 9 <br> 8 <div> 9 <label for="startDate" class="qedLabel">Start date</label> 10 <input type="text" name="startDate" class="qedField" data-dojo-type="dijit/form/DateTextBox" data-dojo-attach-point="startDateBox" /> 11 </div> 10 12 11 <label for="endDate" class="loginLabel">End date</label> 12 <input type="text" name="endDatetime" data-dojo-type="qed/widgets/DateTimeTextBox" /> 13 <br> 13 <div> 14 <label for="endDate" class="qedLabel">End date</label> 15 <input type="text" name="endDate" class="qedField" data-dojo-type="dijit/form/DateTextBox" data-dojo-attach-point="endDateBox" /> 16 </div> 14 17 15 <label for="mode" class="loginLabel">Mode</label> 16 <select name="mode" data-dojo-type="dijit/form/Select"> 18 <div> 19 <label for="mode" class="qedLabel">Mode</label> 20 <select name="mode" class="qedField" data-dojo-type="dijit/form/Select"> 17 21 <option value="open" selected="selected">Open</option> 18 22 <option value="closed">Closed</option> 19 23 </select> 20 < br>24 </div> 21 25 22 26 </fieldset> -
Dev/branches/rest-dojo-ui/client/qed/pages/previewSurvey.js
r418 r420 2 2 'dojo/_base/array', 3 3 'dojo/_base/declare', 4 'dojo/_base/Deferred',5 'dojo/_base/event',6 4 'dojo/_base/lang', 5 'dojo/when', 7 6 '../store', 8 7 '../app/Page', 9 '../model/widgets/QuestionWidgetFactory', 10 'dojo/text!./templates/viewSurvey.html' 11 ],function(array,declare,Deferred,event,lang,store,Page,QuestionWidgetFactory,template){ 8 'dojo/text!./templates/previewSurvey.html' 9 ],function(array,declare,lang,when,store,Page,template){ 12 10 return declare([Page],{ 13 11 templateString: template, 14 survey: null,15 surveyId: "",16 options: null,17 constructor: function(){18 this._dataMap = {};19 this.options = this.options || {};20 },21 12 startup: function() { 22 13 if ( this._started ) { return; } 23 14 this.inherited(arguments); 24 25 26 15 if ( this.surveyId ) { 27 Deferred.when(store.get(this.surveyId))16 when(store.get(this.surveyId)) 28 17 .then(lang.hitch(this,function(survey){ 29 if ( !survey.published ) { 30 this.options.preview = true; 31 } 32 if ( this.options.preview ) { 33 this.buttonsPane.destroyRecursive(); 34 } 35 this.titleNode.innerHTML = survey.title + 36 (this.options.preview?' [preview]':''); 37 var f = new QuestionWidgetFactory(); 38 this.survey = survey; 39 store.query(null,{keys:this.survey.questions,include_docs:true}) 40 .forEach(function(question){ 41 array.forEach(question.content || [],function(item){ 42 var w = f.createViewWidget(item,{ 43 name: question.code+'.'+item.code 44 }); 45 if ( w !== null ) { 46 w.placeAt(this.questionsAnchor,'before'); 47 } 48 },this); 49 },this); 18 this.titleNode.innerHTML = survey.title; 19 this.surveyWidget.set('survey',survey); 50 20 })); 51 21 } else { 52 22 throw new Error("No valid uid or survey passed!"); 53 23 } 54 },55 _onSubmit: function(evt) {56 if ( this.options.preview ) { return; }57 var value = this.questionsForm.get('value');58 this.questionsPane.set('content','<pre>'+JSON.stringify(value)+'</pre>');59 event.stop(evt);60 return false;61 },62 _onCancel: function(evt) {63 if ( this.options.preview ) { return; }64 event.stop(evt);65 return false;66 24 } 67 25 }); -
Dev/branches/rest-dojo-ui/client/qed/pages/question.js
r418 r420 1 1 define([ 2 2 'dojo/_base/declare', 3 'dojo/_base/Deferred',4 3 'dojo/_base/event', 5 4 'dojo/_base/lang', 5 'dojo/when', 6 6 '../store', 7 7 '../app/Content', 8 8 '../app/Router', 9 9 '../app/Page', 10 '../model/classes/Question', 10 11 '../model/widgets/QuestionEditorPreview', 11 12 '../model/widgets/QuestionEditorToolkit', 12 13 'dojo/text!./templates/question.html' 13 ],function(declare, Deferred, event, lang, store, Content, Router, Page, QuestionEditorPreview, QuestionEditorToolkit, template){14 ],function(declare, event, lang, when, store, Content, Router, Page, Question, QuestionEditorPreview, QuestionEditorToolkit, template){ 14 15 return declare([Page], { 15 16 templateString: template, … … 26 27 this._setupEditor(); 27 28 if (this.questionId === "new") { 28 this.question = { type: 'Question' };29 this.question = Question.create(); 29 30 this._refresh(); 30 31 } else { 31 Deferred.when(store.get(this.questionId))32 when(store.get(this.questionId)) 32 33 .then(lang.hitch(this, function(obj) { 33 34 this.question = obj; … … 40 41 }, 41 42 _refresh: function () { 42 this.titleNode.innerHTML = this.question.title || "";43 this.titleNode.innerHTML = Question.DisplayTitle.get(this.question); 43 44 this._toolkit.set('value',this.question); 44 this._preview.appendItems( this.question.content || []);45 this._preview.appendItems(Question.Content.get(this.question)); 45 46 }, 46 47 _onSave: function(evt) { 47 48 lang.mixin(this.question, this._toolkit.get('value')); 48 this.question.content = this._preview.getItems();49 Question.Content.set(this.question, this._preview.getItems()); 49 50 store.put(this.question) 50 51 .then(function() { -
Dev/branches/rest-dojo-ui/client/qed/pages/session.js
r418 r420 2 2 'dojo/_base/array', 3 3 'dojo/_base/declare', 4 'dojo/_base/Deferred',5 4 'dojo/_base/event', 6 5 'dojo/_base/lang', 6 'dojo/when', 7 7 '../search', 8 8 '../store', … … 10 10 '../app/Router', 11 11 '../widgets/ThresholdFilteringSelect', 12 '../model/classes/SessionTemplate', 12 13 '../model/widgets/AccountListView', 13 14 'dojo/text!./templates/session.html' 14 ],function(array,declare, Deferred,event,lang,search,store,Page,Router,ThresholdFilteringSelect,AccountListView,template){15 ],function(array,declare,event,lang,when,search,store,Page,Router,ThresholdFilteringSelect,SessionTemplate,AccountListView,template){ 15 16 return declare([Page],{ 16 17 templateString: template, … … 30 31 _loadSession: function() { 31 32 if ( this.sessionId === "new" ) { 32 this.session = { 33 type: 'SessionTemplate' 34 }; 33 this.session = SessionTemplate.create(); 35 34 } else { 36 Deferred.when(store.get(this.sessionId))35 when(store.get(this.sessionId)) 37 36 .then(lang.hitch(this,function(obj){ 38 37 this.session = obj; … … 43 42 }, 44 43 _refresh: function() { 45 this.titleNode.innerHTML = this.session.title || '';44 this.titleNode.innerHTML = SessionTemplate.DisplayTitle.get(this.session); 46 45 this.propertiesForm.set('value',this.session); 47 46 }, -
Dev/branches/rest-dojo-ui/client/qed/pages/survey.js
r418 r420 2 2 'dojo/_base/array', 3 3 'dojo/_base/declare', 4 'dojo/_base/Deferred',5 4 'dojo/_base/event', 6 5 'dojo/_base/lang', 6 'dojo/when', 7 7 '../app/Router', 8 8 '../store', 9 9 '../app/Page', 10 '../model/classes/Survey', 10 11 '../model/widgets/QuestionListView', 11 12 '../model/widgets/TabbedQuestionBrowser', 12 13 'dojo/text!./templates/survey.html' 13 ],function(array,declare, Deferred,event,lang,Router,store,Page,14 ],function(array,declare,event,lang,when,Router,store,Page,Survey, 14 15 QuestionListView,TabbedQuestionBrowser,template){ 15 16 return declare([Page],{ … … 17 18 survey: null, 18 19 questionList: null, 19 _dataMap: null,20 constructor: function(){21 this._dataMap = {};22 },23 20 startup: function() { 24 21 if ( this._started ) { return; } … … 62 59 _loadSurvey: function() { 63 60 if ( this.surveyId === "new" ) { 64 this.survey = { 65 type: 'Survey' 66 }; 61 this.survey = Survey.create(); 67 62 this.refresh(); 68 63 } else { 69 Deferred.when(store.get(this.surveyId))64 when(store.get(this.surveyId)) 70 65 .then(lang.hitch(this,function(survey){ 71 66 this.survey = survey; 72 store.query(null,{keys:this.survey.questions || [], include_docs: true})73 .forEach(lang.hitch(this.questionList,'appendItem'));67 array.forEach(Survey.Questions.get(this.survey), 68 lang.hitch(this.questionList,'appendItem')); 74 69 this.refresh(); 75 70 })); … … 80 75 }, 81 76 refresh: function() { 82 this.titleNode.innerHTML = this.survey.title|| "(set title in properties)";77 this.titleNode.innerHTML = Survey.DisplayTitle.get(this.survey) || "(set title in properties)"; 83 78 this.propertiesDialog.set('value',this.survey); 84 79 }, … … 100 95 }, 101 96 _onSave: function(evt) { 102 this.survey.questions = array.map(this.questionList.getItems(),function(item){ 103 return store.getIdentity(item); 104 }); 97 this.survey.questions = this.questionList.getItems(); 105 98 store.put(this.survey) 106 99 .then(function() { … … 114 107 }, 115 108 _onShowPreview: function() { 116 Router.go('/ viewSurvey/'+store.getIdentity(this.survey),{109 Router.go('/previewSurvey/'+store.getIdentity(this.survey),{ 117 110 preview: true 118 111 }); -
Dev/branches/rest-dojo-ui/client/qed/pages/surveyRun.js
r418 r420 1 1 define([ 2 'dojo/_base/array',3 2 'dojo/_base/declare', 4 'dojo/_base/Deferred',5 3 'dojo/_base/event', 6 4 'dojo/_base/lang', 5 'dojo/when', 6 '../app/Content', 7 7 '../app/Router', 8 '../lib/func', 8 9 '../store', 9 10 '../app/Page', 10 '../model/widgets/QuestionListView', 11 '../model/widgets/TabbedQuestionBrowser', 12 'dojo/text!./templates/survey.html' 13 ],function(array,declare,Deferred,event,lang,Router,store,Page, 14 QuestionListView,TabbedQuestionBrowser,template){ 11 '../model/classes/SurveyRun', 12 'dojo/text!./templates/surveyRun.html' 13 ],function(declare,event,lang,when,Content,Router,func,store,Page,SurveyRun,template){ 15 14 return declare([Page],{ 16 15 templateString: template, 17 survey: null, 18 questionList: null, 19 _dataMap: null, 20 constructor: function(){ 21 this._dataMap = {}; 22 }, 16 surveyRun: null, 23 17 startup: function() { 24 18 if ( this._started ) { return; } 25 19 this.inherited(arguments); 26 if ( this.surveyId ) { 27 this._setupQuestionBrowser(); 28 this._setupListView(); 29 this._loadSurvey(); 20 this.propertiesForm.on("blur",lang.hitch(this,'_onPropChange')); 21 if ( this.surveyRunId ) { 22 this._loadSurveyRun(); 30 23 } else { 31 24 throw "No valid uid or survey passed!"; 32 25 } 33 26 }, 34 _setupQuestionBrowser: function() { 35 this.questionBrowser = new TabbedQuestionBrowser({ 36 region: 'center', 37 'class': 'blue', 38 include: 'published', 39 selectedActions: { 40 "Include": { 41 callback: lang.hitch(this,this._includeQuestion), 42 icon: "Accept", 43 description: "Include in survey" 44 } 45 }, 46 itemActions: { 47 "Info": { 48 callback: function(item){ item.description && alert(item.description); }, 49 icon: "Inspect", 50 description: "Show item description" 51 } 52 } 53 },this.questionBrowser); 54 this.questionBrowser.startup(); 27 _loadSurveyRun: function() { 28 when(store.get(this.surveyRunId)) 29 .then(lang.hitch(this,function(surveyRun){ 30 this.surveyRun = surveyRun; 31 this.refresh(); 32 })); 55 33 }, 56 _setupListView: function() {57 this. questionList = new QuestionListView({58 region: 'center'59 },this.surveyListViewNode);60 this. questionList.startup();34 refresh: function() { 35 this.titleNode.innerHTML = SurveyRun.DisplayTitle.get(this.surveyRun); 36 this.surveyNode.set('value',SurveyRun.Survey.get(this.surveyRun)); 37 this.propertiesForm.set('value',this.surveyRun); 38 this._onPropChange(); 61 39 }, 62 _loadSurvey: function() { 63 if ( this.surveyId === "new" ) { 64 this.survey = { 65 type: 'Survey' 66 }; 67 this.refresh(); 40 _onPropChange: function(e) { 41 var surveyRun = this.propertiesForm.get('value'); 42 if ( surveyRun.mode === "open" ) { 43 var url = 'response.html#!/'+store.getIdentity(this.surveyRun); 44 this.runURLNode.innerHTML = '<a target="_black" href="'+url+'">'+url+'</a>'; 68 45 } else { 69 Deferred.when(store.get(this.surveyId)) 70 .then(lang.hitch(this,function(survey){ 71 this.survey = survey; 72 store.query(null,{keys:this.survey.questions || [], include_docs: true}) 73 .forEach(lang.hitch(this.questionList,'appendItem')); 74 this.refresh(); 75 })); 46 this.runURLNode.innerHTML = "No general URL. Add individual respondents below."; 76 47 } 77 48 }, 78 _includeQuestion: function(question) {79 this.questionList.insertItem(question);80 },81 refresh: function() {82 this.titleNode.innerHTML = this.survey.title || "(set title in properties)";83 this.propertiesDialog.set('value',this.survey);84 },85 _onShowProperties: function(evt) {86 this.propertiesDialog.show();87 },88 _onPropertiesOk: function(evt) {89 this.propertiesDialog.hide();90 lang.mixin(this.survey, this.propertiesDialog.get('value'));91 this.refresh();92 event.stop(evt);93 return false;94 },95 _onPropertiesCancel: function(evt) {96 this.propertiesDialog.hide();97 this.propertiesDialog.reset('value',this.survey);98 event.stop(evt);99 return false;100 },101 49 _onSave: function(evt) { 102 this.survey.questions = array.map(this.questionList.getItems(),function(item){ 103 return store.getIdentity(item); 104 }); 105 store.put(this.survey) 50 lang.mixin(this.surveyRun,this.propertiesForm.get('value')); 51 var not = function(p){ return !p; }; 52 func.modPropIf(this.surveyRun,"startDate",not.compose(lang.isString),store.formatDate); 53 func.modPropIf(this.surveyRun,"endDate",not.compose(lang.isString),store.formatDate); 54 store.put(this.surveyRun) 106 55 .then(function() { 107 56 Router.go('/surveys'); 57 },function(err){ 58 Content.notify(err); 108 59 }); 109 60 event.stop(evt); … … 112 63 _onDiscard: function(evt) { 113 64 Router.go('/surveys'); 114 },115 _onShowPreview: function() {116 Router.go('/viewSurvey/'+store.getIdentity(this.survey),{117 preview: true118 });119 65 } 120 66 }); -
Dev/branches/rest-dojo-ui/client/qed/pages/surveys.js
r418 r420 9 9 '../app/Page', 10 10 '../app/Router', 11 '../model/classes/Survey', 12 '../model/classes/SurveyRun', 11 13 '../widgets/LineWithActionsWidget', 12 14 'dojo/text!./templates/surveys.html' 13 ],function(array,declare,lang,when,Rx,store,Content,Page,Router, LineWithActionsWidget,template){15 ],function(array,declare,lang,when,Rx,store,Content,Page,Router,Survey,SurveyRun,LineWithActionsWidget,template){ 14 16 return declare([Page],{ 15 17 templateString: template, … … 45 47 }, 46 48 _onPreviewSurvey:function(survey){ 47 Router.go('/ viewSurvey/'+store.getIdentity(survey),{preview:true});49 Router.go('/previewSurvey/'+store.getIdentity(survey)); 48 50 }, 49 51 _onRunSurvey:function(survey){ 50 this.surveyRun = { 51 type: 'SurveyRun', 52 surveyId: store.getIdentity(survey), 53 publicationDate: store.timestamp() 54 }; 55 this.surveyRunDialog.set('value',this.surveyRun); 56 this.surveyRunDialog.show(); 57 }, 58 _onSurveyRunOk: function() { 59 var surveyRun = lang.mixin(lang.clone(this.surveyRun),this.surveyRunDialog.get('value')); 52 var surveyRun = SurveyRun.create(); 53 SurveyRun.Survey.set(surveyRun,survey); 60 54 store.put(surveyRun) 61 .then(lang.hitch(this,function(){ 62 this.surveyRunDialog.hide(); 63 this.refreshRuns(); 55 .then(lang.hitch(this,function(surveyRun){ 56 this._onRunDetails(surveyRun); 64 57 }),function(err){ 65 58 Content.notify(err); 66 59 }); 67 60 }, 68 _on SurveyRunCancel: function() {69 this.surveyRunDialog.hide();61 _onRunDetails: function(surveyRun) { 62 Router.go('/surveyRun/'+store.getIdentity(surveyRun)); 70 63 }, 71 64 refresh: function() { … … 81 74 array.forEach(surveys,function(survey){ 82 75 var w = new LineWithActionsWidget({ 83 title: survey.title|| '(unnamed)',76 title: Survey.DisplayTitle.get(survey) || '(unnamed)', 84 77 actions: [{ 85 78 callback: lang.hitch(this,'_onPublishSurvey',survey), … … 123 116 array.forEach(surveys,function(survey){ 124 117 var w = new LineWithActionsWidget({ 125 title: survey.title,118 title: Survey.DisplayTitle.get(survey), 126 119 actions:[{ 127 120 callback: lang.hitch(this,'_onPreviewSurvey',survey), … … 151 144 array.forEach(surveyRuns,function(surveyRun){ 152 145 var w = new LineWithActionsWidget({ 153 title: surveyRun.title+" (from "+surveyRun.startDate+" to "+surveyRun.endDate+")",146 title: SurveyRun.DisplayTitle.get(surveyRun), 154 147 actions:[{ 155 callback: lang.hitch(this,'_on CloseRun',surveyRun),148 callback: lang.hitch(this,'_onRunDetails',surveyRun), 156 149 properties: { 157 label: ' Close',158 tooltip: ' Close survey',159 icon: ' Close'150 label: 'Details', 151 tooltip: 'Show details for this run', 152 icon: 'Details' 160 153 } 161 154 }] -
Dev/branches/rest-dojo-ui/client/qed/pages/templates/previewSurvey.html
r418 r420 9 9 10 10 <div data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'center'" data-dojo-attach-point="questionsPane"> 11 <form data-dojo-type="dijit/form/Form" data-dojo-attach-point="questionsForm" 12 data-dojo-attach-event="onSubmit:_onSubmit" 13 style="overflow: auto"> 14 <div data-dojo-attach-point="questionsAnchor"></div> 11 <form data-dojo-type="dijit/form/Form" data-dojo-attach-point="questionsForm" style="overflow: auto"> 12 <div data-dojo-type="qed/model/widgets/SurveyWidget" data-dojo-attach-point="surveyWidget"></div> 15 13 </form> 16 14 </div> 17 15 18 <div data-dojo-attach-point="buttonsPane" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'bottom'">19 <button data-dojo-type="dijit/form/Button"20 type="submit"21 data-dojo-attach-event="onClick:_onSubmit">22 Submit</button>23 <button data-dojo-type="dijit/form/Button"24 type="button"25 data-dojo-attach-event="onClick:_onCancel">26 Cancel</button>27 </div>28 29 16 </div> -
Dev/branches/rest-dojo-ui/client/qed/pages/templates/surveys.html
r419 r420 36 36 </div> 37 37 38 <div data-dojo-type="dijit/Dialog"39 title="SurveyRun properties"40 data-dojo-attach-point="surveyRunDialog">41 <fieldset data-dojo-type="qed/model/widgets/SurveyRunFieldset"></fieldset>42 <button data-dojo-type="dijit/form/Button" data-dojo-attach-event="onClick:_onSurveyRunOk">OK</button>43 <button data-dojo-type="dijit/form/Button" data-dojo-attach-event="onClick:_onSurveyRunCancel">Cancel</button>44 </div>45 46 38 </div> -
Dev/branches/rest-dojo-ui/client/qed/routes.js
r407 r420 5 5 './pages/surveys', 6 6 './pages/survey', 7 './pages/surveyRun', 7 8 './pages/sessions', 8 9 './pages/session', 9 './pages/ viewSurvey'10 ],function(index,questions,question,surveys,survey,s essions,session,viewSurvey){10 './pages/previewSurvey' 11 ],function(index,questions,question,surveys,survey,surveyRun,sessions,session,previewSurvey){ 11 12 12 13 return [ … … 17 18 { path: "/surveys", constructor: surveys }, 18 19 { path: "/survey/:surveyId", constructor: survey }, 19 { path: "/sessions", constructor: sessions }, 20 { path: "/session/:sessionId", constructor: session }, 21 { path: "/viewSurvey/:surveyId", constructor: viewSurvey } 20 { path: "/surveyRun/:surveyRunId", constructor: surveyRun }, 21 //{ path: "/sessions", constructor: sessions }, 22 //{ path: "/session/:sessionId", constructor: session }, 23 { path: "/previewSurvey/:surveyId", constructor: previewSurvey } 22 24 ]; 23 25 -
Dev/branches/rest-dojo-ui/client/qed/stddeps.js
r419 r420 27 27 'qed/app/Notifications', 28 28 29 'qed/model/widgets/AccountListView', 30 'qed/model/widgets/QuestionWidget', 29 31 'qed/model/widgets/SurveyFieldset', 30 32 'qed/model/widgets/SurveyRunFieldset', 31 'qed/model/widgets/ QuestionWidget',32 'qed/model/widgets/ AccountListView',33 'qed/model/widgets/SurveySummary', 34 'qed/model/widgets/SurveyWidget', 33 35 34 36 'qed/ui/MainMenu', … … 40 42 'qed/widgets/Selector', 41 43 'qed/widgets/TitleGroup', 42 'qed/widgets/DateTimeTextBox',43 44 'qed/widgets/list/List', 44 45 'qed/widgets/list/OrderedList' -
Dev/branches/rest-dojo-ui/client/qed/store.js
r418 r420 20 20 } 21 21 }); 22 var memoryStore = new Memory(); 23 var cacheStore = new Cache(couchStore,memoryStore,{}); 22 var memoryStore = new Memory({ 23 idProperty: couchStore.idProperty 24 }); 25 var cacheStore = new Cache(couchStore,memoryStore,{ 26 isLoaded: function(object) { 27 // Unfortunately we cannot determine of the full documents were 28 // loaded or not. Therefore never cache query results. 29 return false; 30 } 31 }); 24 32 25 33 var store = cacheStore; -
Dev/branches/rest-dojo-ui/client/qed/widgets/list/List.js
r407 r420 63 63 64 64 getItems: function() { 65 return this.source.getAllNodes() 66 .map(function(node){ 67 return this.source.getItem(node.id).data; 65 var items = []; 66 this.source.getAllNodes() 67 .forEach(function(node){ 68 items.push(this.source.getItem(node.id).data); 68 69 },this); 70 return items; 69 71 }, 70 72 -
Dev/branches/rest-dojo-ui/client/response.html
r419 r420 6 6 <link rel="stylesheet" type="text/css" href="qed/css/main.css" /> 7 7 </head> 8 <body class="dijitReset claro">8 <body id="rft" class="dijitReset claro"> 9 9 <script type="text/javascript" src="dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: false, isDebug: true"></script> 10 <script type="text/javascript" src="qed/ view.js"></script>10 <script type="text/javascript" src="qed/main-response.js"></script> 11 11 <div id="content" class="page" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="region:'center'" style="width: 100%; height: 100%;"> 12 <div class="topbar" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'top'">13 <h1>Survey</h1>14 </div>15 12 </div> 16 13 <div id="toaster" data-dojo-type="qed/app/Notifications"> -
Dev/branches/rest-dojo-ui/server/couchdb-admin/bootstrap.js
r415 r420 5 5 'dijit', 6 6 'dojox', 7 ' rft'7 'qed' 8 8 ], 9 9 '.':[ -
Dev/branches/rest-dojo-ui/server/couchdb-admin/config/check.js
r415 r420 1 1 define([ 2 2 'dojo/_base/array', 3 'dojo/_base/lang', 3 4 'dojox/json/schema', 4 ' ./util/async',5 'qed/lib/async', 5 6 './util/db', 6 ' rft/schema'7 ],function(array, jsonSchema,async,db,schema){7 'qed/model/schema' 8 ],function(array,lang,jsonSchema,async,db,schema){ 8 9 9 10 async.seq([ … … 23 24 function(docs){ 24 25 console.log("Validating documents."); 25 return async. forEach(docs,function(doc){26 return async.map(docs,function(doc){ 26 27 var id = doc.id; 27 28 return db.req('get','qed/'+id) … … 31 32 }); 32 33 }); 33 },function(){34 console.log("Done!");35 34 } 36 ]); 35 ]).then(function() { 36 console.log("Done!"); 37 },function(err){ 38 console.log("Fail!",err.stack); 39 }); 37 40 38 41 -
Dev/branches/rest-dojo-ui/server/couchdb-admin/config/config.js
r415 r420 3 3 'dojo/_base/lang', 4 4 'dojox/lang/functional', 5 ' ./util/async',5 'qed/lib/async', 6 6 './util/db', 7 7 './data/design-docs'
Note: See TracChangeset
for help on using the changeset viewer.