- Timestamp:
- Feb 2, 2010, 10:31:25 AM (11 years ago)
- Location:
- trunk
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/grails-app/controllers/dbnp/studycapturing/WizardController.groovy
r145 r157 44 44 // start the flow 45 45 onStart { 46 println "wizard started"47 48 46 // define flow variables 49 47 flow.page = 0 … … 73 71 render(view: "_study") 74 72 onRender { 75 println "render page one"76 73 flow.page = 1 77 74 } … … 93 90 // validate study 94 91 if (flow.study.validate()) { 95 println "ok"96 92 success() 97 93 } else { … … 115 111 } 116 112 on ("add") { 113 // fetch species by name (as posted by the form) 117 114 def speciesTerm = Term.findByName(params.addSpecies) 118 115 … … 158 155 render(view: "_three") 159 156 onRender { 160 println "render page three"161 157 flow.page = 3 162 158 } 163 159 on("previous") { 164 println "previous page!"160 // TODO 165 161 }.to "subjects" 166 162 } -
trunk/grails-app/domain/dbnp/data/Ontology.groovy
r106 r157 4 4 * This class describes an existing ontology, of which terms can be stored (actually 'cached' would be a better description) 5 5 * in the (global) Term store. 6 * 7 * Revision information: 8 * $Rev$ 9 * $Author$ 10 * $Date$ 6 11 */ 7 class Ontology { 8 12 class Ontology implements Serializable { 9 13 String name 10 14 String shortName 11 15 String url 12 13 16 } -
trunk/grails-app/taglib/dbnp/studycapturing/WizardTagLib.groovy
r145 r157 289 289 // fetch all species 290 290 attrs.from = Term.findAll() // for now, all terms, should be refactored to be species ontology only! 291 def speciesOntology = Ontology.findAllByName('NCBI Taxonomy') 292 293 println speciesOntology 294 //println Term.findAllByOntology(speciesOntology) 291 295 292 296 // got a name? … … 328 332 } 329 333 330 def templateColumnHeaders = { attrs, body -> 331 TemplateSubjectField.findAll().each() { 332 out << '<div class="column">' + it + '</div>' 333 } 334 } 335 334 /** 335 * render table headers for all subjectFields in a template 336 * @param Map attributes 337 */ 338 def templateColumnHeaders = { attrs -> 339 def template = attrs.remove('template') 340 341 // output table headers for template fields 342 template.subjectFields.each() { 343 out << '<div class="' + attrs.get('class') + '">' + it + '</div>' 344 } 345 } 346 347 /** 348 * render table input elements for all subjectFields in a template 349 * @param Map attributes 350 */ 336 351 def templateColumns = { attrs, body -> 337 352 def subjectId = attrs.remove('id') 338 339 // for now, fetch them all 340 // also, this should probably be cached to reduce database load... 341 TemplateSubjectField.findAll().each() { 342 out << '<div class="column">' 343 out << '<input type="text">' 353 def template = attrs.remove('template') 354 355 // output columns for these subjectFields 356 template.subjectFields.each() { 357 println it.type 358 out << '<div class="' + attrs.get('class') + '">' 359 360 switch (it.type) { 361 case 'STRINGLIST': 362 // render stringlist subjectfield 363 out << '<select><option>TODO</option></select>' 364 break; 365 case 'INTEGER': 366 // render integer subjectfield 367 out << '<input type="text" value="TODO">' 368 break; 369 default: 370 // unsupported field type 371 out << '<b>!! ' + it.type + '</b>' 372 break; 373 } 344 374 out << '</div>' 345 375 } -
trunk/grails-app/views/wizard/pages/_groups.gsp
r145 r157 24 24 25 25 <div class="groups"> 26 <div class="ui-widget-header droppable"> 27 <h1>Group 1<h1> 28 <p>drop here...</p> 26 <div class="ui-widget-content group"> 27 <h4 class="ui-widget-header">Group 1</h4> 28 </div> 29 30 <div class="ui-widget-content group"> 31 <h4 class="ui-widget-header">Group 2</h4> 29 32 </div> 30 33 </div> -
trunk/grails-app/views/wizard/pages/_study.gsp
r145 r157 25 25 The research question 26 26 </wizard:textFieldElement> 27 <wizard:textFieldElement name="description" description="Description" error="description" value="${study?.description}" /> 28 <wizard:textFieldElement name="ecCode" description="Ethical Committee Code" error="ecCode" value="${study?.ecCode}" /> 27 <wizard:textFieldElement name="description" description="Description" error="description" value="${study?.description}"> 28 A short description summarizing your study 29 </wizard:textFieldElement> 30 <wizard:textFieldElement name="ecCode" description="Ethical Committee Code" error="ecCode" value="${study?.ecCode}"> 31 If you study has been approved by the Ethical Committee, here is where you will enter that partical reference code 32 </wizard:textFieldElement> 29 33 <wizard:dateElement name="startDate" description="Start date" error="startDate" value="${study?.startDate}"> 30 34 The start date of the study -
trunk/grails-app/views/wizard/pages/_subjects.gsp
r145 r157 26 26 <div class="column">name</div> 27 27 <div class="column">species</div> 28 <wizard:templateColumnHeaders/>28 <wizard:templateColumnHeaders template="${study.template}" class="column" /> 29 29 </div> 30 30 <g:each var="subject" status="i" in="${subjects}"> … … 35 35 <wizard:speciesSelect value="${subject.species}" name="subject_${i}_species" /> 36 36 </div> 37 <wizard:templateColumns id="${i}" />37 <wizard:templateColumns id="${i}" template="${study.template}" class="column" /> 38 38 </div> 39 39 </g:each> 40 40 </div> 41 <div class="sliderContainer"> 42 <div class="slider"/> 43 </div> 41 44 </g:if> 42 45 </wizard:pageContent> -
trunk/web-app/css/wizard.css
r145 r157 11 11 } 12 12 13 .wizard .sliderContainer { 14 display: block; 15 padding-top: 10px; 16 width: 150px; 17 } 18 13 19 .wizard .tabs { 14 20 display: block; … … 19 25 20 26 .wizard .tabs .element { 21 background-color: #EEEEEE;22 border-bottom: 4px solid #006DBA;23 border-right: 1px solid #006DBA;24 color: #006DBA;25 cursor: default;26 display: inline;27 font-size: 10px;28 height: 20px;29 margin: 0px 0px 0px 0px;30 padding: 20px 15px 0px 15px;31 text-align: center;32 text-decoration: none;27 background-color: #EEEEEE; 28 border-bottom: 4px solid #006DBA; 29 border-right: 1px solid #006DBA; 30 color: #006DBA; 31 cursor: default; 32 display: inline; 33 font-size: 10px; 34 height: 20px; 35 margin: 0px 0px 0px 0px; 36 padding: 20px 15px 0px 15px; 37 text-align: center; 38 text-decoration: none; 33 39 } 34 40 … … 47 53 color: #666666; 48 54 font-size: 10px; 55 padding-top: 10px; 49 56 } 50 57 … … 63 70 } 64 71 65 66 72 .wizard .error { 67 73 display: block; … … 123 129 display: none; 124 130 } 131 125 132 /** END :: HELP **/ 126 133 … … 132 139 margin-top: 10px; 133 140 font-size: 11px; 134 overflow: hidden; 141 overflow: hidden; 142 } 143 144 .wizard .table .header { 145 display: block; 146 background-color: #006DBA; 147 color: #fff; 148 font-weight: bold; 149 width: auto; 135 150 } 136 151 … … 144 159 display: inline-block; 145 160 padding: 2px 4px; 146 width: 40px; 147 } 148 149 .wizard .table .header { 150 display: block; 151 background-color: #006DBA; 152 color: #fff; 153 font-weight: bold; 154 width: 2000px; 155 } 156 157 .wizard .table .header .column .first { 158 width: 40px; 161 width: 20px; 159 162 } 160 163 161 164 .wizard .table .row { 162 165 display: block; 163 width: 2000px;164 166 height: 28px; 165 167 border-top: 1px solid #8e908f; 168 width: auto; 166 169 } 167 170 … … 178 181 color: #fff; 179 182 } 183 184 .wizard .table .highlight input, .wizard .table .highlight select { 185 background-color: #6e99d4; 186 color: #fff; 187 } 188 180 189 /* END :: TABLE */ 181 190 182 183 .selectable .ui-selecting { background: #FECA40; } 184 .selectable .ui-selected { background: #F39814; color: white; } 185 .selectable { list-style-type: none; margin: 0; padding: 0; width: 200px; } 186 .selectable li { margin: 3px; padding: 0.4em; font-size: 1em; height: 18px; } 191 .selectable .ui-selecting { 192 background: #add9ef; 193 } 194 195 .selectable .ui-selected { 196 background: #006dbd; 197 color: white; 198 } 199 200 .selectable { 201 list-style-type: none; 202 margin: 0; 203 padding: 0; 204 width: 200px; 205 } 206 207 .selectable li { 208 margin: 3px; 209 padding: 0.4em; 210 font-size: 1em; 211 height: 18px; 212 } 187 213 188 214 .wizard .grouping { 189 215 display: block; 216 height: auto; 217 vertical-align: top; 190 218 } 191 219 192 220 .wizard .subjects { 193 221 display: inline-block; 222 vertical-align: top; 194 223 } 195 224 196 225 .wizard .groups { 197 226 display: inline-block; 198 height: 100% 199 } 200 201 .droppable { width: 300px; } 202 203 227 height: 100%; 228 vertical-align: top; 229 } 230 231 .wizard .groups .groupbla { 232 margin: 3px; 233 padding: 0.4em; 234 font-size: 1em; 235 } 236 237 .droppable { 238 width: 300px; 239 } 240 241 .wizard .groups .group { 242 display: inline-block; 243 float: right; 244 width: 250px; 245 min-height: 18em; 246 margin: 3px; 247 padding: 0.4em; 248 249 } * html #trash { 250 height: 18em; 251 } /* IE6 */ 252 253 .wizard .groups .group h4 { 254 line-height: 16px; 255 margin: 0 0 0.4em; 256 } 257 /* 258 .wizard .groups .group .gallery { float: left; width: 65%; min-height: 12em; } * html #gallery { height: 12em; } /* IE6 */ 259 .wizard .groups .group .gallery.custom-state-active { background: #eee; } 260 .wizard .groups .group .gallery li { float: left; width: 96px; padding: 0.4em; margin: 0 0.4em 0.4em 0; text-align: center; } 261 .wizard .groups .group .gallery li h5 { margin: 0 0 0.4em; cursor: move; } 262 .wizard .groups .group .gallery li a { float: right; } 263 .wizard .groups .group .gallery li a.ui-icon-zoomin { float: left; } 264 .wizard .groups .group .gallery li img { width: 100%; cursor: move; } 265 */ 266 .wizard .groups .group .gallery { 267 display: block; 268 float: left; 269 } 270 271 .wizard .groups .group .gallery li { 272 display: inline-block; 273 } 274 275 276 -
trunk/web-app/js/wizard.js
r145 r157 36 36 attachTableEvents(); 37 37 attachGroupingEvents(); 38 39 resizeWizardTable(); 40 attachSubjectSlider(); 38 41 } 39 42 … … 49 52 if (specialContent) { 50 53 // replace content by calling a helper function 51 eval(specialContent[1] +"('"+specialContent[2]+"',helpContent)");54 eval(specialContent[1] + "('" + specialContent[2] + "',helpContent)"); 52 55 } 53 56 … … 87 90 88 91 // insert a youtube player in a certain element 89 function youtube(video, element) {92 function youtube(video, element) { 90 93 // insert a div we will replace with a youtube player 91 element.html("<div id='" +video+"'></div>")94 element.html("<div id='" + video + "'></div>") 92 95 93 96 // insert youtube player 94 97 var params = { allowScriptAccess: "always" }; 95 var atts = { id: 'myytplayer_' +video };96 swfobject.embedSWF("http://www.youtube.com/v/" +video+"?enablejsapi=1&playerapiid=ytplayer_"+video,97 98 var atts = { id: 'myytplayer_' + video }; 99 swfobject.embedSWF("http://www.youtube.com/v/" + video + "?enablejsapi=1&playerapiid=ytplayer_" + video, 100 video, "200", "150", "8", null, null, params, atts) 98 101 } 99 102 100 103 // when a youtube player is ready, play the video 101 104 function onYouTubePlayerReady(playerId) { 102 ytplayer = document.getElementById("my" +playerId);105 ytplayer = document.getElementById("my" + playerId); 103 106 ytplayer.playVideo(); 104 107 } … … 119 122 $('div#wizard').find('div.row').each(function() { 120 123 $(this).hover( 121 function() {122 $(this).addClass('highlight');123 },124 function() {125 $(this).removeClass('highlight');126 }124 function() { 125 $(this).addClass('highlight'); 126 }, 127 function() { 128 $(this).removeClass('highlight'); 129 } 127 130 ) 128 131 }); 129 132 } 130 133 134 // if the wizard page contains a table, the width of 135 // the header and the rows is automatically scaled to 136 // the cummalative width of the columns in the header 137 function resizeWizardTable() { 138 var wizardTable = $("div#wizard").find('div.table'); 139 140 if (wizardTable) { 141 var header = wizardTable.find('div.header') 142 // calculate total width of elements in header 143 var width = 20; 144 header.children().each(function() { 145 // calculate width per column 146 var c = $(this); 147 var columnWidth = c.width(); 148 columnWidth += parseInt(c.css("padding-left"), 10) + parseInt(c.css("padding-right"), 10); // padding width 149 columnWidth += parseInt(c.css("margin-left"), 10) + parseInt(c.css("margin-right"), 10); // margin width 150 columnWidth += parseInt(c.css("borderLeftWidth"), 10) + parseInt(c.css("borderRightWidth"), 10); // border width 151 width += columnWidth; 152 }); 153 154 // resize the header 155 header.css({ width: width + 'px' }); 156 157 // set table row width and assume column widths are 158 // identical to those in the header (css!) 159 wizardTable.find('div.row').each(function() { 160 $(this).css({ width: width + 'px' }); 161 }); 162 } 163 } 164 165 // if we have a table and a slider, make the slider 166 // slide the contents of the table if the content of 167 // the table is wider than the table itself 168 function attachSubjectSlider() { 169 var slider = $("div#wizard").find('div.slider'); 170 var header = $("div#wizard").find('div.header'); 171 var table = $("div#wizard").find('div.table'); 172 173 if (slider && table && header) { 174 // do we really need a slider? 175 if (header.width() < table.width()) { 176 // no, so hide it 177 slider.css({ 'display': 'none '}); 178 } else { 179 slider.slider({ 180 value : 1, 181 min : 1, 182 max : header.width() - table.width(), 183 step : 1, 184 slide: function(event, ui) { 185 $("div#wizard").find('div.header, div.row').css({ 'margin-left': ( 1 - ui.value ) + 'px' }); 186 } 187 }); 188 } 189 } 190 } 191 192 // handle selecting and grouping of subjects 131 193 function attachGroupingEvents() { 132 194 console.log('attach drag and drop events') 133 195 134 $(".groups").find('div.droppable').droppable({ 135 drop: function(event, ui) { 136 $(this).addClass('ui-state-highlight').find('p').html('Dropped!'); 137 } 138 }); 139 140 141 $(".subjects").find(".selectable").selectable({ 196 $(".groups").find('div.group').droppable({ 197 accept: '.subjects > ol > li', 198 drop: function(event, ui) { 199 /* 200 $(this).addClass('ui-state-highlight').find('p').html('Dropped!'); 201 deleteImage(ui.draggable); 202 function deleteImage($item) { 203 $item.fadeOut(function() { 204 var $list = $('ul',$trash).length ? $('ul',$trash) : $('<ul class="gallery ui-helper-reset"/>').appendTo($trash); 205 206 $item.find('a.ui-icon-trash').remove(); 207 $item.append(recycle_icon).appendTo($list).fadeIn(function() { 208 $item.animate({ width: '48px' }).find('img').animate({ height: '36px' }); 209 }); 210 }); 211 } 212 */ 213 214 //console.log($(this)) 215 //console.log(ui.draggable) 216 var group = $(this) 217 var list = $('ul',group).length ? $('ul',group) : $('<ul class="gallery ui-helper-reset"/>').appendTo(group); 218 219 // append selected subjects to this group 220 $(".subjects").find(".ui-selected").each(function() { 221 // append to group 222 $(this).appendTo(list); 223 224 // make undraggable 225 /* 226 $(this).draggable('destroy'); 227 228 //$(this).css({ 'position': 'absolute' }); 229 230 // make all visible 231 $(this).animate( 232 {opacity: 100}, 233 200 234 ); 235 */ 236 }); 237 238 239 240 } 241 }); 242 243 244 //$(".subjects").find(".selectable").selectable({ 245 $(".selectable").selectable({ 142 246 stop: function() { 143 247 // remove draggable from unselected items 144 248 $('.ui-selectee:not(.ui-selected)', this).each(function() { 145 $(this).draggable('destroy') 249 $(this).draggable('destroy') 146 250 }) 147 251 … … 156 260 D.draggable({ 157 261 revert: 'invalid', 262 containment: '.grouping', 263 corsor: 'move', 158 264 start: function(event, ui) { 159 265 // change dragged item's content to summarize selected items … … 164 270 if (this != d) { 165 271 $(this).animate( 166 { 167 opacity: 0 168 }, 272 { opacity: 0 }, 169 273 200 170 274 ); 171 275 } 172 276 }); 173 }, 277 }, 174 278 stop: function(event, ui) { 175 279 // restore original content … … 180 284 if (this != d) { 181 285 $(this).animate( 182 { 183 opacity: 100 184 }, 286 {opacity: 100}, 185 287 200 186 288 );
Note: See TracChangeset
for help on using the changeset viewer.