- Timestamp:
- 03/20/13 16:56:28 (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/experiment.view.js
r9305 r9324 1 // ================ VIEWS ======================= 2 var ExperimentTreeView = Backbone.View.extend({ 3 renderTree: function (model) { 4 var jsonModel = model.toJSON(); 5 var self = this; 6 this.tree = $('<div />').dynatree({ 7 children: [jsonModel], 8 autoExpandMS: 750, 9 onActivate: function (node) { 10 // if we are able to remove this node from the tree, enable the remove button. 11 if (node && node.parent.parent != null) { 12 $('.remove-button', this.$el).removeAttr("disabled"); 13 } else if (node) { 14 $('.remove-button', this.$el).attr("disabled", "disabled"); 15 } 16 17 var modelNode = ExperimentNode.lookup(node.data.key); 18 if (modelNode && !modelNode.get('isExperiment')) { 19 $('.variate-button', this.$el).removeAttr("disabled"); 20 } else { 21 $('.variate-button', this.$el).attr("disabled", "disabled"); 22 } 23 }, 24 dnd: { 25 onDragStart: function (node) { 26 return node.parent.parent != null; 1 var OAAS_VIEW = (function (my, Backbone, _, $, OAAS_MODEL) { 2 // ================ VIEWS ======================= 3 my.ExperimentTreeView = Backbone.View.extend({ 4 renderTree: function (model) { 5 var jsonModel = model.toJSON(); 6 var self = this; 7 this.tree = $('<div />').dynatree({ 8 children: [jsonModel], 9 autoExpandMS: 750, 10 onActivate: function (node) { 11 // if we are able to remove this node from the tree, enable the remove button. 12 if (node && node.parent.parent != null) { 13 $('.remove-button', this.$el).removeAttr("disabled"); 14 } else if (node) { 15 $('.remove-button', this.$el).attr("disabled", "disabled"); 16 } 17 18 var modelNode = OAAS_MODEL.ExperimentNode.lookup(node.data.key); 19 if (modelNode && !modelNode.get('isExperiment')) { 20 $('.variate-button', this.$el).removeAttr("disabled"); 21 } else { 22 $('.variate-button', this.$el).attr("disabled", "disabled"); 23 } 27 24 }, 28 onDragEnter: function (node, sourceNode) { 29 return true; 25 dnd: { 26 onDragStart: function (node) { 27 return node.parent.parent != null; 28 }, 29 onDragEnter: function (node, sourceNode) { 30 return true; 31 }, 32 onDragOver: function (node, sourceNode, hitMode) { 33 return node.data.title !== "Experiment" || hitMode === "over"; 34 }, 35 onDrop: function (node, sourceNode, hitMode, ui, draggable) { 36 if (hitMode !== 'over') 37 return; 38 var modelNode = OAAS_MODEL.ExperimentNode.lookup(node.data.key); 39 if (sourceNode) { 40 var sourceModelNode = OAAS_MODEL.ExperimentNode.lookup(sourceNode.data.key); 41 sourceNode.move(node, hitMode); 42 // move node into the modelNode 43 sourceModelNode.moveNode(modelNode); 44 } 45 else { 46 var elem = $(draggable.element[0]); 47 var newNode = { nodeId: elem.attr('id'), isExperiment: elem.attr('data-isExperiment') === 'true', title: elem.attr('data-name'), key: OAAS_MODEL.ExperimentNode.nextGlobalKey() }; 48 if (hitMode == "over") { 49 node.addChild(newNode); 50 node.expand(true); 51 // update the data model 52 newNode = modelNode.addNode(newNode); 53 self.trigger('node-added', newNode); 54 } 55 } 56 self.trigger('structure-changed', modelNode); 57 } 58 } 59 }); 60 this.tree.dynatree("getRoot").visit(function (node) { 61 node.expand(true); 62 }); 63 }, 64 initialize: function (spec) { 65 this.renderTree(spec.model); 66 }, 67 events: { 68 'click .remove-button': 'doRemove', 69 'click .variate-button': 'doVariate' 70 }, 71 render: function () { 72 this.$el.empty(); 73 this.renderTree(this.model); 74 var content = $(_.template($('#stepwizard_template').html(), {})); 75 this.tree.appendTo(this.$el); 76 content.appendTo(this.$el); 77 }, 78 doRemove: function () { 79 var node = this.tree.dynatree('getActiveNode'); 80 if (node && node.parent.parent != null) { 81 var nxt = node.getNextSibling(); 82 if (nxt == null) 83 nxt = node.getPrevSibling(); 84 if (nxt == null) 85 nxt = node.getParent(); 86 node.remove(); 87 OAAS_MODEL.ExperimentNode.lookup(node.data.key).remove(); 88 if (nxt) { 89 this.tree.dynatree("getTree").activateKey(nxt.data.key); 90 } 91 } 92 this.trigger('structure-changed', node); 93 }, 94 doVariate: function () { 95 var node = this.tree.dynatree('getActiveNode'); 96 var modelNode = OAAS_MODEL.ExperimentNode.lookup(node.data.key); 97 this.trigger('variation-request', { 98 parentNode: node.parent, 99 model: modelNode 100 }); 101 } 102 }); 103 104 my.ExperimentDetailsTreeView = Backbone.View.extend({ 105 render: function () { 106 var jsonModel = this.model.toJSON(); 107 var self = this; 108 var tree = $('<div />').dynatree({ 109 children: [jsonModel], 110 autoExpandMS: 750, 111 onActivate: function (node) { 112 // if we click a node, simply open a dialog to enter it's parameters 113 self.trigger('node-clicked', node); 114 } 115 }); 116 117 this.$el.empty(); 118 tree.appendTo(this.$el); 119 tree.dynatree("getRoot").visit(function (node) { 120 node.expand(true); 121 }); 122 } 123 }); 124 125 my.DraggableGroup = Backbone.View.extend({ 126 initialize: function () { 127 this.collection.bind('remove', this.render, this); 128 this.collection.bind('add', this.render, this); 129 }, 130 render: function () { 131 var self = this; 132 var div = $('<div />'); 133 if (this.collection.length == 0) { 134 $('<p></p>').text("No items found!").appendTo(div); 135 } 136 for (var i = 0; i < this.collection.length; i++) { 137 new my.DraggableView({ model: this.collection.models[i], el: div }).render(); 138 } 139 140 this.$el.empty(); 141 div.appendTo(this.$el); 142 } 143 }); 144 145 146 my.DraggableView = Backbone.View.extend({ 147 render: function () { 148 var late = _.template($("#draggable_template").html(), this.model.attributes); 149 $(late).draggable({ 150 revert: true, 151 connectToDynatree: true, 152 cursorAt: { top: -5, left: -5 }, 153 helper: "clone" 154 }).appendTo(this.$el); 155 } 156 }); 157 158 my.SelectableGroup = Backbone.View.extend({ 159 initialize: function () { 160 this.collection.bind('remove', this.render, this); 161 this.collection.bind('add', this.render, this); 162 this.collection.bind('change', this.render, this); 163 }, 164 render: function () { 165 var self = this; 166 var div = $('<div />'); 167 if (this.collection.length == 0) { 168 $('<p></p>').text("No experiments found!").appendTo(div); 169 } 170 171 for (var i = 0; i < this.collection.length; i++) { 172 new my.SelectableView({ model: this.collection.models[i], el: div }).render(); 173 } 174 this.$el.empty(); 175 div.selectable({ 176 filter: 'div', 177 selected: function (event, ui) { 178 self.selected(event, ui); 179 } 180 }).appendTo(this.$el); 181 }, 182 selected: function (event, ui) { 183 var nodeId = $(ui.selected).attr('id'); 184 this.trigger('node-selected', nodeId); 185 } 186 }); 187 188 my.SelectableView = Backbone.View.extend({ 189 render: function () { 190 var late = _.template($("#draggable_template").html(), this.model.attributes); 191 $(late).appendTo(this.$el); 192 } 193 }); 194 195 my.StepWizardView = Backbone.View.extend({ 196 render: function () { 197 var self = this; 198 this.$el.smartWizard({ 199 onLeaveStep: function (step) { 200 var stepNum = parseInt(step.attr("rel")); 201 return self.validateStep(stepNum); 30 202 }, 31 onDragOver: function (node, sourceNode, hitMode) { 32 return node.data.title !== "Experiment" || hitMode === "over"; 203 onShowStep: function (step) { 204 var stepNum = parseInt(step.attr("rel")); 205 return self.showStep(stepNum); 33 206 }, 34 onDrop: function (node, sourceNode, hitMode, ui, draggable) { 35 if (hitMode !== 'over') 36 return; 37 var modelNode = ExperimentNode.lookup(node.data.key); 38 if (sourceNode) { 39 var sourceModelNode = ExperimentNode.lookup(sourceNode.data.key); 40 sourceNode.move(node, hitMode); 41 // move node into the modelNode 42 sourceModelNode.moveNode(modelNode); 43 } 44 else { 45 var elem = $(draggable.element[0]); 46 var newNode = { nodeId: elem.attr('id'), isExperiment: elem.attr('data-isExperiment') === 'true', title: elem.attr('data-name'), key: ExperimentNode.nextGlobalKey() }; 47 if (hitMode == "over") { 48 node.addChild(newNode); 49 node.expand(true); 50 // update the data model 51 newNode = modelNode.addNode(newNode); 52 self.trigger('node-added', newNode); 53 } 54 } 55 self.trigger('structure-changed', modelNode); 56 } 57 } 58 }); 59 this.tree.dynatree("getRoot").visit(function (node) { 60 node.expand(true); 61 }); 62 }, 63 initialize: function (spec) { 64 this.renderTree(spec.model); 65 }, 66 events: { 67 'click .remove-button': 'doRemove', 68 'click .variate-button': 'doVariate' 69 }, 70 render: function () { 71 this.$el.empty(); 72 this.renderTree(this.model); 73 var content = $(_.template($('#stepwizard_template').html(), {})); 74 this.tree.appendTo(this.$el); 75 content.appendTo(this.$el); 76 }, 77 doRemove: function () { 78 var node = this.tree.dynatree('getActiveNode'); 79 if (node && node.parent.parent != null) { 80 var nxt = node.getNextSibling(); 81 if (nxt == null) 82 nxt = node.getPrevSibling(); 83 if (nxt == null) 84 nxt = node.getParent(); 85 node.remove(); 86 ExperimentNode.lookup(node.data.key).remove(); 87 if (nxt) { 88 this.tree.dynatree("getTree").activateKey(nxt.data.key); 89 } 90 } 91 this.trigger('structure-changed', node); 92 }, 93 doVariate: function () { 94 var node = this.tree.dynatree('getActiveNode'); 95 var modelNode = ExperimentNode.lookup(node.data.key); 96 this.trigger('variation-request', { 97 parentNode: node.parent, 98 model: modelNode 99 }); 100 } 101 }); 102 103 var ExperimentDetailsTreeView = Backbone.View.extend({ 104 render: function () { 105 var jsonModel = this.model.toJSON(); 106 var self = this; 107 var tree = $('<div />').dynatree({ 108 children: [jsonModel], 109 autoExpandMS: 750, 110 onActivate: function (node) { 111 // if we click a node, simply open a dialog to enter it's parameters 112 self.trigger('node-clicked', node); 113 } 114 }); 115 116 this.$el.empty(); 117 tree.appendTo(this.$el); 118 tree.dynatree("getRoot").visit(function (node) { 119 node.expand(true); 120 }); 121 } 122 }); 123 124 var DraggableGroup = Backbone.View.extend({ 125 render: function () { 126 var self = this; 127 var div = $('<div />'); 128 129 for (var i = 0; i < this.model.length; i++) { 130 new DraggableView({ model: this.model.models[i], el: div }).render(); 131 } 132 133 this.$el.empty(); 134 div.appendTo(this.$el); 135 } 136 }); 137 138 139 var DraggableView = Backbone.View.extend({ 140 render: function () { 141 var late = _.template($("#draggable_template").html(), this.model.attributes); 142 $(late).draggable({ 143 revert: true, 144 connectToDynatree: true, 145 cursorAt: { top: -5, left: -5 }, 146 helper: "clone" 147 }).appendTo(this.$el); 148 } 149 }); 150 151 var SelectableGroup = Backbone.View.extend({ 152 render: function () { 153 var self = this; 154 var div = $('<div />'); 155 for (var i = 0; i < this.model.length; i++) { 156 new SelectableView({ model: this.model.models[i], el: div }).render(); 157 } 158 this.$el.empty(); 159 div.selectable({ 160 filter: 'div', 161 selected: function (event, ui) { 162 self.selected(event, ui); 163 } 164 }).appendTo(this.$el); 165 }, 166 selected: function (event, ui) { 167 var nodeId = $(ui.selected).attr('id'); 168 this.trigger('node-selected', nodeId); 169 } 170 }); 171 172 var SelectableView = Backbone.View.extend({ 173 render: function () { 174 var late = _.template($("#draggable_template").html(), this.model.attributes); 175 $(late).appendTo(this.$el); 176 } 177 }); 178 179 var StepWizardView = Backbone.View.extend({ 180 render: function () { 181 var self = this; 182 this.$el.smartWizard({ 183 onLeaveStep: function (step) { 184 var stepNum = parseInt(step.attr("rel")); 185 return self.validateStep(stepNum); 186 }, 187 onShowStep: function (step) { 188 var stepNum = parseInt(step.attr("rel")); 189 return self.showStep(stepNum); 190 }, 191 onFinish: function () { 192 self.trigger('experiment-finished'); 193 } 194 }); 195 }, 196 validateStep: function (stepNumber) { 197 var validationModel = { 198 stepNumber: stepNumber, 199 succeeded: true 200 }; 201 this.trigger('step-validated', validationModel); 202 return validationModel.succeeded; 203 }, 204 showStep: function (stepNumber) { 205 this.trigger('step-shown', stepNumber); 206 return true; 207 } 208 }); 209 210 var ParameterWizard = Backbone.View.extend({ 211 createWizard: function (steps) { 212 // use template instead of jquery?! 213 var newWizard = $('<div />').addClass('wizard swMain'); 214 var stepMenu = $('<ul />'); 215 var prefix = name + '_'; 216 for (var i = 0; i < steps.length; i++) { 217 var step = steps[i]; 218 var a = $('<a></a>', { href: '#' + prefix + (i + 1) }); 219 $('<label />').addClass("stepNumber").text((i + 1)).appendTo(a); 220 $('<span />').addClass("stepDesc").html(step.heading + '<br /><small>' + step.description + '</small>').appendTo(a); 221 var li = $('<li />').append(a); 222 li.appendTo(stepMenu); 223 } 224 stepMenu.appendTo(newWizard); 225 for (var i = 0; i < steps.length; i++) { 226 var div = $('<div />', { id: prefix + (i + 1) }); 227 if (steps[i].content && steps[i].content != null) 228 div.append(steps[i].content); 229 div.appendTo(newWizard); 230 } 231 return newWizard; 232 }, 233 render: function () { 234 var self = this; 235 this.$el.empty(); 236 var data = this.model.get('data'); 237 238 var hasProblemParameters = typeof data.ProblemParameters !== 'undefined'; 239 var dialog = $('<div />'); 240 var algoDiv = $('<div />'); 241 var problemDiv = $('<div />'); 242 243 for (var i = 0; i < data.AlgorithmParameters.length; i++) { 244 var parameterView = new ParameterEditableView({ model: data.AlgorithmParameters[i] }); 245 // render to dialog 246 parameterView.render(); 247 parameterView.$el.appendTo(algoDiv); 248 } 249 250 if (hasProblemParameters) { 251 var problemParameters = data.ProblemParameters; 252 for (var i = 0; i < problemParameters.length; i++) { 253 var parameterView = new ParameterEditableView({ model: problemParameters[i] }); 254 // render to dialog 255 parameterView.render(); 256 parameterView.$el.appendTo(problemDiv); 257 } 258 } 259 260 var newWizard = 261 hasProblemParameters ? 262 this.createWizard([ 263 { heading: "Algorithm Parameters", description: "Adjust algorithm parameters", content: algoDiv }, 264 { heading: "Problem Parameters", description: "Adjust problem parameters", content: problemDiv } 265 ]) : 266 this.createWizard([ 267 { heading: "Algorithm Parameters", description: "Adjust algorithm parameters", content: algoDiv } 268 ]); 269 270 newWizard.appendTo(this.$el); 271 newWizard.smartWizard({ 272 onFinish: function () { 273 self.trigger('parameters-finished'); 274 } 275 }); 276 } 277 }); 278 279 var ParameterEditableView = Backbone.View.extend({ 280 events: { 207 onFinish: function () { 208 self.trigger('experiment-finished'); 209 } 210 }); 211 }, 212 validateStep: function (stepNumber) { 213 var validationModel = { 214 stepNumber: stepNumber, 215 succeeded: true 216 }; 217 this.trigger('step-validated', validationModel); 218 return validationModel.succeeded; 219 }, 220 showStep: function (stepNumber) { 221 this.trigger('step-shown', stepNumber); 222 return true; 223 } 224 }); 225 226 my.ParameterWizard = Backbone.View.extend({ 227 createWizard: function (steps) { 228 // use template instead of jquery?! 229 var newWizard = $('<div />').addClass('wizard swMain'); 230 var stepMenu = $('<ul />'); 231 var prefix = name + '_'; 232 for (var i = 0; i < steps.length; i++) { 233 var step = steps[i]; 234 var a = $('<a></a>', { href: '#' + prefix + (i + 1) }); 235 $('<label />').addClass("stepNumber").text((i + 1)).appendTo(a); 236 $('<span />').addClass("stepDesc").html(step.heading + '<br /><small>' + step.description + '</small>').appendTo(a); 237 var li = $('<li />').append(a); 238 li.appendTo(stepMenu); 239 } 240 stepMenu.appendTo(newWizard); 241 for (var i = 0; i < steps.length; i++) { 242 var div = $('<div />', { id: prefix + (i + 1) }); 243 if (steps[i].content && steps[i].content != null) 244 div.append(steps[i].content); 245 div.appendTo(newWizard); 246 } 247 return newWizard; 248 }, 249 render: function () { 250 var self = this; 251 this.$el.empty(); 252 var data = this.model.get('data'); 253 254 var hasProblemParameters = typeof data.ProblemParameters !== 'undefined'; 255 var dialog = $('<div />'); 256 var algoDiv = $('<div />'); 257 var problemDiv = $('<div />'); 258 259 for (var i = 0; i < data.AlgorithmParameters.length; i++) { 260 var parameterView = new my.ParameterEditableView({ model: data.AlgorithmParameters[i] }); 261 // render to dialog 262 parameterView.render(); 263 parameterView.$el.appendTo(algoDiv); 264 } 265 266 if (hasProblemParameters) { 267 var problemParameters = data.ProblemParameters; 268 for (var i = 0; i < problemParameters.length; i++) { 269 var parameterView = new my.ParameterEditableView({ model: problemParameters[i] }); 270 // render to dialog 271 parameterView.render(); 272 parameterView.$el.appendTo(problemDiv); 273 } 274 } 275 276 var newWizard = 277 hasProblemParameters ? 278 this.createWizard([ 279 { heading: "Algorithm Parameters", description: "Adjust algorithm parameters", content: algoDiv }, 280 { heading: "Problem Parameters", description: "Adjust problem parameters", content: problemDiv } 281 ]) : 282 this.createWizard([ 283 { heading: "Algorithm Parameters", description: "Adjust algorithm parameters", content: algoDiv } 284 ]); 285 286 newWizard.appendTo(this.$el); 287 newWizard.smartWizard({ 288 onFinish: function () { 289 self.trigger('parameters-finished'); 290 } 291 }); 292 } 293 }); 294 295 my.ParameterEditableView = Backbone.View.extend({ 296 /*events: { 281 297 'change': 'valueChanged' 282 }, 283 render: function () { 284 var mapper = new DatatypeMapper(); 285 var content = $(_.template($('#parameter_template').html(), this.model)); 286 mapper.mapHtml(this.model).appendTo($('.rightEntry', content)); 287 content.appendTo(this.$el); 288 }, 289 valueChanged: function (param) { 290 var value = $(param.target).val(); 291 if (!isNaN(value)) 292 value = parseFloat(value); 293 var name = $(param.target).attr("name"); 294 // normally a controller would do this, just for once, let the view update the model 295 var splitted = name.split("_"); 296 if (splitted.length == 1) { 297 this.model.Value = value; 298 } else if (splitted.length == 2) { 299 this.model.Value[parseInt(splitted[1])] = value; 300 } else if (splitted.length == 3) { 301 this.model.Value[parseInt(splitted[1])][parseInt(splitted[2])] = value; 302 } 303 } 304 }); 305 306 307 var LoadingDialog = Backbone.View.extend({ 308 initialize: function () { 309 this.reset(); 310 }, 311 render: function () { 312 var self = this; 313 this.$el.empty(); 314 var dialog = $('<div />'); 315 this.content.appendTo(dialog); 316 dialog.appendTo(this.$el); 317 this.$el.dialog({ 318 autoOpen: true 319 }); 320 }, 321 text: function (txt) { 322 $('p', this.$el).text(txt); 323 }, 324 setLoading: function(isLoading) { 325 if (isLoading) 326 $('img', this.$el).show(); 327 else 328 $('img', this.$el).hide(); 329 }, 330 reset: function () { 331 this.content = $(_.template($('#loading_template').html(), {})); 332 }, 333 setContent: function (el) { 334 this.content = el; 335 }, 336 close: function () { 337 this.$el.dialog("close"); 338 } 339 }); 340 341 342 var ParameterDialog = Backbone.View.extend({ 343 render: function () { 344 var self = this; 345 346 this.$el.empty(); 347 var data = this.model.get('data'); 348 349 var hasProblemParameters = typeof data.ProblemParameters !== 'undefined'; 350 var dialog = $('<div />'); 351 352 var parameterWizard = new ParameterWizard({ model: this.model, el: dialog }); 353 parameterWizard.render(); 354 this.listenTo(parameterWizard, 'parameters-finished', function () { 355 self.trigger('parameters-finished'); 356 }); 357 dialog.appendTo(this.$el); 358 this.$el.dialog({ 359 autoOpen: true, 360 width: 1024, 361 height: 768 362 }); 363 }, 364 close: function () { 365 this.$el.dialog("close"); 366 } 367 }); 368 369 var ExperimentDetailsView = Backbone.View.extend({ 370 events: { 371 'change': 'valueChanged' 372 }, 373 valueChanged: function (param) { 374 var value = $(param.target).val(); 375 if (!isNaN(value)) 376 value = parseFloat(value); 377 var name = $(param.target).attr("name"); 378 if (name == 'Name') 379 this.model.set({ title: value }); 380 else if (name == 'RunImmediately') 381 this.model.set({ run: $(param.target).is(':checked') }); 382 else if (name == 'Repititions') 383 this.model.set({ repititions: value }); 384 else if (name == 'Group') 385 this.model.set({ group: value }); 386 387 if (this.model.get('run')) { 388 $('input[name="Repititions"]', this.$el).removeAttr('disabled'); 389 $('input[name="Group"]', this.$el).removeAttr('disabled'); 390 } else { 391 $('input[name="Repititions"]', this.$el).attr('disabled', 'disabled'); 392 $('input[name="Group"]', this.$el).attr('disabled', 'disabled'); 393 } 394 }, 395 render: function () { 396 $('input[name="Name"]', this.$el).val(this.model.get('title')); 397 $('input[name="RunImmediately"]', this.$el).attr('checked', this.model.get('run')); 398 $('input[name="Repititions"]', this.$el).val(this.model.get('repititions')); 399 $('input[name="Group"]', this.$el).val(this.model.get('group')); 400 } 401 }); 402 403 var ValidationHintsView = Backbone.View.extend({ 404 render: function () { 405 var template = _.template($('#validationhints_template').html(), this.model); 406 $(template).dialog({ 407 resizable: false, 408 modal: true, 409 buttons: { 410 "OK": function () { 411 $(this).dialog("close"); 412 } 413 } 414 }); 415 } 416 }); 417 418 // ========== Variation Dialog Views ============ 419 420 var VariationDialog = Backbone.View.extend({ 421 initialize: function (spec) { 422 423 }, 424 events: { 425 'change': 'entrySelected' 426 }, 427 render: function () { 428 var self = this; 429 var dialog = $(_.template($('#variationdialog_template').html(), {})); 430 431 var content = $('select[class="variationDialogContent"]', dialog); 432 var data = this.model.get('data'); 433 for (var i = 0; i < data.AlgorithmParameters.length; i++) { 434 data.AlgorithmParameters[i].Index = i; 435 var entry = new VariationEntryView({ model: data.AlgorithmParameters[i], el: content }); 436 entry.render(); 437 } 438 439 this.details = $('div[class="variationDetails"]', dialog); 440 this.activateButton = $('input[name="active"]', dialog); 441 this.activateButton.change(function (evt) { 442 var checked = $(evt.target).is(':checked'); 443 if (self.selectedModel && self.selectedModel != null) { 444 self.selectedModel.Active = checked; 445 } 446 }); 447 dialog.dialog({ 448 height: 300, 449 buttons: { 450 "Abort": function () { 451 $(this).dialog("close"); 452 }, 453 "OK": function () { 454 self.generateVariations(); 455 $(this).dialog("close"); 456 } 457 } 458 }); 459 460 content.change(function (evt) { 461 var optionSelected = $("option:selected", this); 462 var model = self.model.get('data').AlgorithmParameters[parseInt($(optionSelected).attr('data-index'))] 463 self.entrySelected(model); 464 }); 465 466 this.variationDetails = new VariationContentView({ el: this.details }); 467 var model = this.model.get('data').AlgorithmParameters[0]; 468 this.entrySelected(model); 469 }, 470 entrySelected: function (model) { 471 this.selectedModel = model; 472 if (model.Active) 473 this.activateButton.attr('checked', 'checked'); 474 else 475 this.activateButton.removeAttr('checked'); 476 this.variationDetails.model = model; 477 this.details.empty(); 478 this.variationDetails.render(); 479 }, 480 generateVariations: function () { 481 this.solutions = []; 482 this.exhaust(0, []); 483 this.trigger('variations-generated', this.solutions); 484 }, 485 exhaust: function (index, element) { 486 if (index == this.model.get('data').AlgorithmParameters.length) { 487 // we found a solution! store it by creating a deep copy 488 this.solutions.push($.extend(true, [], element)); 489 return; 490 } 491 492 var currentParameter = this.model.get('data').AlgorithmParameters[index]; 493 if (currentParameter.Active && currentParameter.Generated) { 494 for (var i = 0; i < currentParameter.Generated.length; i++) { 298 },*/ 299 render: function () { 300 var mapper = new my.DatatypeMapper(); 301 var content = $(_.template($('#parameter_template').html(), this.model)); 302 mapper.mapHtml(this.model, $('.rightEntry', content)); 303 content.appendTo(this.$el); 304 } /*, 305 valueChanged: function (param) { 306 var value = $(param.target).val(); 307 if (!isNaN(value)) 308 value = parseFloat(value); 309 var name = $(param.target).attr("name"); 310 // normally a controller would do this, just for once, let the view update the model 311 var splitted = name.split("_"); 312 if (splitted.length == 1) { 313 this.model.Value = value; 314 } else if (splitted.length == 2) { 315 this.model.Value[parseInt(splitted[1])] = value; 316 } else if (splitted.length == 3) { 317 this.model.Value[parseInt(splitted[1])][parseInt(splitted[2])] = value; 318 } 319 }*/ 320 }); 321 322 323 my.LoadingDialog = Backbone.View.extend({ 324 initialize: function () { 325 this.reset(); 326 }, 327 render: function () { 328 var self = this; 329 this.$el.empty(); 330 var dialog = $('<div />'); 331 this.content.appendTo(dialog); 332 dialog.appendTo(this.$el); 333 this.$el.dialog({ 334 autoOpen: true 335 }); 336 }, 337 text: function (txt) { 338 $('p', this.$el).text(txt); 339 }, 340 setLoading: function (isLoading) { 341 if (isLoading) 342 $('img', this.$el).show(); 343 else 344 $('img', this.$el).hide(); 345 }, 346 reset: function () { 347 this.content = $(_.template($('#loading_template').html(), {})); 348 }, 349 setContent: function (el) { 350 this.content = el; 351 }, 352 close: function () { 353 this.$el.dialog("close"); 354 } 355 }); 356 357 358 my.ParameterDialog = Backbone.View.extend({ 359 render: function () { 360 var self = this; 361 362 this.$el.empty(); 363 var data = this.model.get('data'); 364 365 var hasProblemParameters = typeof data.ProblemParameters !== 'undefined'; 366 var dialog = $('<div />'); 367 368 var parameterWizard = new my.ParameterWizard({ model: this.model, el: dialog }); 369 parameterWizard.render(); 370 this.listenTo(parameterWizard, 'parameters-finished', function () { 371 self.trigger('parameters-finished'); 372 }); 373 dialog.appendTo(this.$el); 374 this.$el.dialog({ 375 autoOpen: true, 376 width: 1024, 377 height: 768 378 }); 379 }, 380 close: function () { 381 this.$el.dialog("close"); 382 } 383 }); 384 385 my.ExperimentDetailsView = Backbone.View.extend({ 386 events: { 387 'change': 'valueChanged' 388 }, 389 valueChanged: function (param) { 390 var value = $(param.target).val(); 391 if (!isNaN(value)) 392 value = parseFloat(value); 393 var name = $(param.target).attr("name"); 394 if (name == 'Name') 395 this.model.set({ title: value }); 396 else if (name == 'RunImmediately') 397 this.model.set({ run: $(param.target).is(':checked') }); 398 else if (name == 'Repititions') 399 this.model.set({ repititions: value }); 400 else if (name == 'Group') 401 this.model.set({ group: value }); 402 403 if (this.model.get('run')) { 404 $('input[name="Repititions"]', this.$el).removeAttr('disabled'); 405 $('input[name="Group"]', this.$el).removeAttr('disabled'); 406 } else { 407 $('input[name="Repititions"]', this.$el).attr('disabled', 'disabled'); 408 $('input[name="Group"]', this.$el).attr('disabled', 'disabled'); 409 } 410 }, 411 render: function () { 412 $('input[name="Name"]', this.$el).val(this.model.get('title')); 413 $('input[name="RunImmediately"]', this.$el).attr('checked', this.model.get('run')); 414 $('input[name="Repititions"]', this.$el).val(this.model.get('repititions')); 415 $('input[name="Group"]', this.$el).val(this.model.get('group')); 416 } 417 }); 418 419 my.ValidationHintsView = Backbone.View.extend({ 420 render: function () { 421 var template = _.template($('#validationhints_template').html(), this.model); 422 $(template).dialog({ 423 resizable: false, 424 modal: true, 425 buttons: { 426 "OK": function () { 427 $(this).dialog("close"); 428 } 429 } 430 }); 431 } 432 }); 433 434 // ========== Variation Dialog Views ============ 435 436 my.VariationDialog = Backbone.View.extend({ 437 initialize: function (spec) { 438 439 }, 440 events: { 441 'change': 'entrySelected' 442 }, 443 render: function () { 444 var self = this; 445 var dialog = $(_.template($('#variationdialog_template').html(), {})); 446 447 var content = $('select[class="variationDialogContent"]', dialog); 448 var data = this.model.get('data'); 449 for (var i = 0; i < data.AlgorithmParameters.length; i++) { 450 data.AlgorithmParameters[i].Index = i; 451 var entry = new my.VariationEntryView({ model: data.AlgorithmParameters[i], el: content }); 452 entry.render(); 453 } 454 455 this.details = $('div[class="variationDetails"]', dialog); 456 this.activateButton = $('input[name="active"]', dialog); 457 this.activateButton.change(function (evt) { 458 var checked = $(evt.target).is(':checked'); 459 if (self.selectedModel && self.selectedModel != null) { 460 self.selectedModel.Active = checked; 461 } 462 463 if (self.selectedModel.Active) { 464 $('*', self.details).removeAttr('disabled'); 465 } 466 else { 467 //$('input,button,select', self.details).attr('disabled', 'disabled'); 468 $('*', self.details).attr('disabled', 'disabled'); 469 } 470 }); 471 dialog.dialog({ 472 height: 300, 473 buttons: { 474 "Abort": function () { 475 $(this).dialog("close"); 476 }, 477 "OK": function () { 478 self.generateVariations(); 479 $(this).dialog("close"); 480 } 481 } 482 }); 483 484 content.change(function (evt) { 485 var optionSelected = $("option:selected", this); 486 var model = self.model.get('data').AlgorithmParameters[parseInt($(optionSelected).attr('data-index'))] 487 self.entrySelected(model); 488 }); 489 490 this.variationDetails = new my.VariationContentView({ el: this.details }); 491 var model = this.model.get('data').AlgorithmParameters[0]; 492 this.entrySelected(model); 493 }, 494 entrySelected: function (model) { 495 this.selectedModel = model; 496 this.variationDetails.model = model; 497 this.details.empty(); 498 this.variationDetails.render(); 499 if (model.Active) { 500 this.activateButton.attr('checked', 'checked'); 501 $('*', this.details).removeAttr('disabled'); 502 } 503 else { 504 this.activateButton.removeAttr('checked'); 505 $('*', this.details).attr('disabled', 'disabled'); 506 } 507 }, 508 generateVariations: function () { 509 this.solutions = []; 510 this.exhaust(0, []); 511 this.trigger('variations-generated', this.solutions); 512 }, 513 exhaust: function (index, element) { 514 if (index == this.model.get('data').AlgorithmParameters.length) { 515 // we found a solution! store it by creating a deep copy 516 this.solutions.push($.extend(true, [], element)); 517 return; 518 } 519 520 var currentParameter = this.model.get('data').AlgorithmParameters[index]; 521 if (currentParameter.Active && currentParameter.Generated) { 522 for (var i = 0; i < currentParameter.Generated.length; i++) { 523 element[index] = { 524 Name: currentParameter.Name, 525 Value: currentParameter.Generated[i] 526 }; 527 if (currentParameter.Options) { 528 element[index].Options = currentParameter.Options; 529 } 530 this.exhaust(index + 1, element); 531 } 532 } else { 495 533 element[index] = { 496 534 Name: currentParameter.Name, 497 Value: currentParameter. Generated[i]535 Value: currentParameter.Value 498 536 }; 499 537 if (currentParameter.Options) { … … 502 540 this.exhaust(index + 1, element); 503 541 } 504 } else { 505 element[index] = { 506 Name: currentParameter.Name, 507 Value: currentParameter.Value 508 }; 509 if (currentParameter.Options) { 510 element[index].Options = currentParameter.Options; 511 } 512 this.exhaust(index + 1, element); 513 } 514 } 515 }); 516 517 var TableEditView = Backbone.View.extend({ 518 events: { 519 'change': 'valueChanged', 520 'click button[data-operation="Add"]': 'addClicked', 521 'click button[data-operation="Remove"]': 'removeClicked' 542 } 543 }); 544 545 my.TableEditView = Backbone.View.extend({ 546 events: { 547 'change': 'valueChanged', 548 'click button[data-operation="Add"]': 'addClicked', 549 'click button[data-operation="Remove"]': 'removeClicked' 550 }, 551 render: function () { 552 this.$el.empty(); 553 // http: //stackoverflow.com/questions/8749236/create-table-with-jquery-append 554 var table = $('<table></table>').addClass('editableTable'); 555 556 // determine dimensions 557 var rows = this.model.length; 558 var columns = 1; 559 if ($.isArray(this.model[0])) { 560 columns = this.model[0].length; 561 } 562 563 // create head elements 564 var head = $('<thead></thead>'); 565 var headerRow = $('<tr></tr>'); 566 headerRow.appendTo(head); 567 if (this.options.rowNames) { 568 var rowNames = this.options.rowNames; 569 for (var i = 0; i < rowNames.length; i++) { 570 $('<td />').text(rowNames[i]).appendTo(headerRow); 571 } 572 } else { 573 for (var i = 0; i < columns; i++) { 574 $('<td />').text((i + 1) + '. Column').appendTo(headerRow); 575 } 576 } 577 head.appendTo(table); 578 579 // create body 580 var body = $('<tbody></tbody>'); 581 582 for (var i = 0; i < rows; i++) { 583 var row = $('<tr></tr>'); 584 for (var j = 0; j < columns; j++) { 585 var rowContent = this.model[i]; 586 var columnEntry = $.isArray(rowContent) ? rowContent[j] : rowContent; 587 var col = $('<td></td>'); 588 if (this.options.editable) { 589 $('<input type="text" name="' + i + '_' + j + '" />').val(columnEntry).appendTo(col); 590 } else { 591 col.text(columnEntry); 592 } 593 col.appendTo(row); 594 } 595 if (this.options.editable) { 596 $('<button data-operation="Add" name="' + i + '" />').val(columnEntry).text('+').appendTo(col); 597 $('<button data-operation="Remove" name="' + i + '" />').val(columnEntry).text('-').appendTo(col); 598 } 599 row.appendTo(body); 600 } 601 body.appendTo(table); 602 603 table.appendTo(this.$el); 604 if (this.options.useDatatable) 605 table.dataTable(); 606 }, 607 valueChanged: function (evt) { 608 var target = $(evt.target); 609 var value = target.val(); 610 var index = target.attr('name'); 611 var splittedName = index.split('_'); 612 var i = parseInt(splittedName[0]); 613 var j = parseInt(splittedName[1]); 614 if ($.isArray(this.model[i])) { 615 this.model[i][j] = parseFloat(value); 616 } else { 617 this.model[i] = parseFloat(value); 618 } 619 }, 620 addClicked: function (evt) { 621 var target = $(evt.target); 622 var index = target.attr('name'); 623 var i = parseInt(index); 624 if ($.isArray(this.model[i])) { 625 var cpy = []; 626 for (var j = 0; j < this.model[i].length; j++) { 627 cpy.push(this.model[i][j]); 628 } 629 this.model.splice(i, 0, cpy); 630 } else { 631 this.model.splice(i, 0, this.model[i]); 632 } 633 // render after model changes 634 this.render(); 635 }, 636 removeClicked: function (evt) { 637 var target = $(evt.target); 638 var index = target.attr('name'); 639 var i = parseInt(index); 640 this.model.splice(i, 1); 641 // render after model changes 642 this.render(); 643 } 644 }); 645 646 my.NumberEditableView = Backbone.View.extend({ 647 events: { 648 'change': 'valueChanged' 649 }, 650 render: function () { 651 $('<input type="text" />').val(this.model.Value).appendTo(this.$el); 652 653 }, 654 valueChanged: function (evt) { 655 var value = $(evt.target).val(); 656 if (!isNaN(value)) { 657 value = parseFloat(value); 658 this.model.Value = value; 659 } else { 660 $('input', this.$el).val(this.model.Value); 661 } 662 } 663 }); 664 665 my.SelectionView = Backbone.View.extend({ 666 events: { 667 'change': 'checked' 668 }, 669 render: function () { 670 this.$el.empty(); 671 var s = $('<select />').attr('data-name', this.model.Name).appendTo(this.$el); 672 for (var i = 0; i < this.model.Options.length; i++) { 673 $('<option />', { value: this.model.Options[i], text: this.model.Options[i] }).appendTo(s); 674 } 675 s.val(this.model.Value); 676 }, 677 checked: function (evt) { 678 var value = $(evt.target).val(); 679 var name = $(evt.target).attr('data-name') 680 this.trigger('selected', { name: name, value: value }); 681 } 682 }); 683 684 my.OptionSelectionView = Backbone.View.extend({ 685 events: { 686 'change': 'checked' 687 }, 688 render: function () { 689 this.$el.empty(); 690 if ($.isArray(this.model)) { 691 for (var i = 0; i < this.model.length; i++) { 692 $(_.template($('#checkbox_template').html(), { checked: false, name: this.model[i], text: this.model[i], hideText: this.options.hideText })).appendTo(this.$el); 693 } 694 } 695 else { 696 $(_.template($('#checkbox_template').html(), { checked: this.model, name: this.model, text: this.model, hideText: this.options.hideText })).appendTo(this.$el); 697 } 698 }, 699 checked: function (evt) { 700 var checked = $(evt.target).is(':checked'); 701 var name = $(evt.target).attr('name') 702 this.trigger('changed', { name: name, checked: checked }); 703 } 704 }); 705 706 707 my.PlotView = Backbone.View.extend({ 708 render: function () { 709 this.$el.empty(); 710 var plotLabels = undefined; 711 if (this.model.RowNames) { 712 plotLabels = []; 713 for (var i = 0; i < this.model.RowNames.length; i++) { 714 plotLabels.push({ label: this.model.RowNames[i] }); 715 } 716 } 717 718 var values = this.model.Value ? this.model.Value : this.model; 719 720 var plotValues = []; 721 if ($.isArray(values[0])) { 722 var columnCount = values[0].length; 723 var colVals = {}; 724 for (var i = 0; i < columnCount; i++) 725 colVals[i] = []; 726 727 for (var i = 0; i < values.length; i++) { 728 for (var j = 0; j < columnCount; j++) { 729 colVals[j].push(values[i][j]); 730 } 731 } 732 733 for (var i = 0; i < columnCount; i++) { 734 plotValues.push(colVals[i]); 735 } 736 } else { 737 plotValues.push(values); 738 } 739 740 if (!this.$el.attr('id')) { 741 this.$el.attr('id', my.PlotView.nextId()); 742 } 743 744 this.$el.css('width', '500px'); 745 746 this.plot = $.jqplot(this.$el.attr('id'), plotValues, { 747 cursor: { 748 show: true, 749 zoom: true, 750 showTooltip: false 751 }, 752 series: plotLabels, 753 seriesDefaults: { 754 lineWidth: 1.5, 755 markerOptions: { 756 size: 2, 757 lineWidth: 2 758 } 759 }, 760 legend: { 761 show: true, 762 placement: 'outsideGrid' 763 }, 764 highlighter: { 765 show: true, 766 sizeAdjust: 7.5 767 } 768 }); 769 }, 770 refresh: function () { 771 if (this.plot) 772 this.plot.replot({ resetAxes: true }); 773 } 522 774 }, 523 render: function () { 524 this.$el.empty(); 525 // http: //stackoverflow.com/questions/8749236/create-table-with-jquery-append 526 var table = $('<table></table>').addClass('editableTable'); 527 528 // determine dimensions 529 var rows = this.model.length; 530 var columns = 1; 531 if ($.isArray(this.model[0])) { 532 columns = this.model[0].length; 533 } 534 535 // create head elements 536 var head = $('<thead></thead>'); 537 var headerRow = $('<tr></tr>'); 538 headerRow.appendTo(head); 539 for (var i = 0; i < columns; i++) { 540 $('<td />').text((i + 1) + '. Column').appendTo(headerRow); 541 } 542 head.appendTo(table); 543 544 // create body 545 var body = $('<tbody></tbody>'); 546 547 for (var i = 0; i < rows; i++) { 548 var row = $('<tr></tr>'); 549 for (var j = 0; j < columns; j++) { 550 var rowContent = this.model[i]; 551 var columnEntry = $.isArray(rowContent) ? rowContent[j] : rowContent; 552 var col = $('<td></td>'); 553 $('<input type="text" name="' + i + '_' + j + '" />').val(columnEntry).appendTo(col); 554 col.appendTo(row); 555 } 556 if (this.options.editable) { 557 $('<button data-operation="Add" name="' + i + '" />').val(columnEntry).text('+').appendTo(col); 558 $('<button data-operation="Remove" name="' + i + '" />').val(columnEntry).text('-').appendTo(col); 559 } 560 row.appendTo(body); 561 } 562 body.appendTo(table); 563 table.appendTo(this.$el); 564 }, 565 valueChanged: function (evt) { 566 var target = $(evt.target); 567 var value = target.val(); 568 var index = target.getattr('name'); 569 var splittedName = index.split('_'); 570 var i = parseInt(splittedName[0]); 571 var j = parseInt(splittedName[1]); 572 if ($.isArray(this.model[i])) { 573 this.model[i][j] = parseFloat(value); 574 } else { 575 this.model[i] = parseFloat(value); 576 } 577 }, 578 addClicked: function (evt) { 579 var target = $(evt.target); 580 var index = target.attr('name'); 581 var i = parseInt(index); 582 if ($.isArray(this.model[i])) { 583 var cpy = []; 584 for (var j = 0; j < this.model[i].length; j++) { 585 cpy.push(this.model[i][j]); 586 } 587 this.model.splice(i, 0, cpy); 588 } else { 589 this.model.splice(i, 0, this.model[i]); 590 } 591 // render after model changes 592 this.render(); 593 }, 594 removeClicked: function (evt) { 595 var target = $(evt.target); 596 var index = target.attr('name'); 597 var i = parseInt(index); 598 this.model.splice(i, 1); 599 // render after model changes 600 this.render(); 601 } 602 }); 603 604 var OptionSelectionView = Backbone.View.extend({ 605 events: { 606 'change': 'checked' 607 }, 608 render: function () { 609 this.$el.empty(); 610 611 for (var i = 0; i < this.model.length; i++) { 612 $(_.template($('#checkbox_template').html(), { name: this.model[i], text: this.model[i] })).appendTo(this.$el); 613 } 614 }, 615 checked: function (evt) { 616 var checked = $(evt.target).is(':checked'); 617 var name = $(evt.target).attr('name') 618 this.trigger('changed', { name: name, checked: checked }); 619 } 620 }); 621 622 var VariationContentView = Backbone.View.extend({ 623 render: function () { 624 var self = this; 625 if (this.model.Value === 'false' || this.model.Value === 'true' || 626 this.model.Value === true || this.model.Value === false) { 627 $(_.template($('#variation_boolean_template').html(), {})).appendTo(this.$el); 628 this.model.Generated = [false, true]; 629 } 630 else if (!isNaN(this.model.Value)) { 631 var elem = $(_.template($('#variation_number_template').html(), {})); 632 elem.appendTo(this.$el) 633 $('input[name="generate"]', elem).click(function (evt) { self.openGenerator(evt); }); 634 if (!this.model.Generated) { 635 this.model.Generated = [0, 1, 2]; 636 } 637 var tev = new TableEditView({ model: this.model.Generated, el: $('div div', this.$el), editable: true }); 775 { 776 plotId: 1, 777 nextId: function () { 778 return my.PlotView.plotId++; 779 } 780 }); 781 782 my.VariationContentView = Backbone.View.extend({ 783 render: function () { 784 var self = this; 785 if (this.model.Value === 'false' || this.model.Value === 'true' || 786 this.model.Value === true || this.model.Value === false) { 787 $(_.template($('#variation_boolean_template').html(), {})).appendTo(this.$el); 788 this.model.Generated = [false, true]; 789 } 790 else if (!isNaN(this.model.Value)) { 791 var elem = $(_.template($('#variation_number_template').html(), {})); 792 elem.appendTo(this.$el) 793 $('input[name="generate"]', elem).click(function (evt) { self.openGenerator(evt); }); 794 if (!this.model.Generated) { 795 this.model.Generated = [0, 1, 2]; 796 } 797 var tev = new my.TableEditView({ model: this.model.Generated, el: $('div div', this.$el), editable: true }); 798 tev.render(); 799 } 800 else if (this.model.Options) { 801 var osv = new my.OptionSelectionView({ model: this.model.Options, el: this.$el }); 802 this.listenTo(osv, 'changed', function (evt) { 803 self.selectionChanged(evt); 804 }); 805 if (!this.model.Generated) 806 this.model.Generated = []; 807 osv.render(); 808 for (var i = 0; i < this.model.Generated.length; i++) { 809 $('input[name="' + this.model.Generated[i] + '"]', this.$el).attr('checked', 'checked'); 810 } 811 } 812 }, 813 openGenerator: function (evt) { 814 var self = this; 815 var generator = new my.GeneratorDialog(); 816 this.listenTo(generator, 'success', function (data) { 817 self.doGenerate(data); 818 }); 819 generator.render(); 820 }, 821 doGenerate: function (data) { 822 if (data.minimum > data.maximum) { 823 var tmp = data.minimum; 824 data.minimum = data.maximum; 825 data.maximum = tmp; 826 } 827 if (data.step < 0) 828 data.step *= -1; 829 if (data.step == 0) 830 data.step = 1; 831 this.model.Generated = _.range(data.minimum, data.maximum + 1, data.step); 832 var tev = new my.TableEditView({ model: this.model.Generated, el: $('div div', this.$el), editable: true }); 638 833 tev.render(); 639 } 640 else if (this.model.Options) { 641 var osv = new OptionSelectionView({ model: this.model.Options, el: this.$el }); 642 this.listenTo(osv, 'changed', function (evt) { 643 self.selectionChanged(evt); 644 }); 645 if (!this.model.Generated) 646 this.model.Generated = []; 647 osv.render(); 648 for (var i = 0; i < this.model.Generated.length; i++) { 649 $('input[name="' + this.model.Generated[i] + '"]', this.$el).attr('checked', 'checked'); 650 } 651 } 652 }, 653 openGenerator: function (evt) { 654 var self = this; 655 var generator = new GeneratorDialog(); 656 this.listenTo(generator, 'success', function (data) { 657 self.doGenerate(data); 658 }); 659 generator.render(); 660 }, 661 doGenerate: function (data) { 662 if (data.minimum > data.maximum) { 663 var tmp = data.minimum; 664 data.minimum = data.maximum; 665 data.maximum = tmp; 666 } 667 if (data.step < 0) 668 data.step *= -1; 669 if (data.step == 0) 670 data.step = 1; 671 this.model.Generated = _.range(data.minimum, data.maximum + 1, data.step); 672 var tev = new TableEditView({ model: this.model.Generated, el: $('div div', this.$el), editable: true }); 673 tev.render(); 674 }, 675 selectionChanged: function (evt) { 676 if (!evt.checked) { 677 this.model.Generated = _.without(this.model.Generated, evt.name); 678 } else if (_.indexOf(this.model.Generated, evt.name) == -1) { 679 this.model.Generated.push(evt.name); 680 } 681 } 682 }); 683 684 var GeneratorDialog = Backbone.View.extend({ 685 render: function() { 686 var self = this; 687 var generator = $(_.template($('#variation_generator_template').html(),{})); 688 generator.dialog({ 689 buttons: { 690 "Abort": function () { 691 $(this).dialog("close"); 692 }, 693 "OK": function () { 694 $(this).dialog("close"); 695 self.trigger("success", { 696 minimum: parseInt($('input[name="minimum"]', generator).val()), 697 maximum: parseInt($('input[name="maximum"]', generator).val()), 698 step: parseFloat($('input[name="step"]', generator).val()) 699 }); 700 } 701 } 702 }); 703 } 704 }); 705 706 var VariationEntryView = Backbone.View.extend({ 707 render: function () { 708 var entryTemplate = _.template($('#variationentry_template').html(), this.model); 709 $(entryTemplate).appendTo(this.$el); 710 } 711 }); 834 }, 835 selectionChanged: function (evt) { 836 if (!evt.checked) { 837 this.model.Generated = _.without(this.model.Generated, evt.name); 838 } else if (_.indexOf(this.model.Generated, evt.name) == -1) { 839 this.model.Generated.push(evt.name); 840 } 841 } 842 }); 843 844 my.GeneratorDialog = Backbone.View.extend({ 845 render: function () { 846 var self = this; 847 var generator = $(_.template($('#variation_generator_template').html(), {})); 848 generator.dialog({ 849 buttons: { 850 "Abort": function () { 851 $(this).dialog("close"); 852 }, 853 "OK": function () { 854 $(this).dialog("close"); 855 self.trigger("success", { 856 minimum: parseInt($('input[name="minimum"]', generator).val()), 857 maximum: parseInt($('input[name="maximum"]', generator).val()), 858 step: parseFloat($('input[name="step"]', generator).val()) 859 }); 860 } 861 } 862 }); 863 } 864 }); 865 866 my.VariationEntryView = Backbone.View.extend({ 867 render: function () { 868 var entryTemplate = _.template($('#variationentry_template').html(), this.model); 869 $(entryTemplate).appendTo(this.$el); 870 } 871 }); 872 return my; 873 } (OAAS_VIEW || {}, Backbone, _, $, OAAS_MODEL));
Note: See TracChangeset
for help on using the changeset viewer.