var OAAS_VIEW = (function (my, Backbone, _, $, OAAS_MODEL) { // ================ VIEWS ======================= my.ExperimentTreeView = Backbone.View.extend({ renderTree: function (model) { var jsonModel = model.toJSON(); var self = this; this.tree = $('
').dynatree({ children: [jsonModel], autoExpandMS: 750, onActivate: function (node) { // if we are able to remove this node from the tree, enable the remove button. if (node && node.parent.parent != null) { $('.remove-button', this.$el).removeAttr("disabled"); } else if (node) { $('.remove-button', this.$el).attr("disabled", "disabled"); } var modelNode = OAAS_MODEL.ExperimentNode.lookup(node.data.key); if (modelNode && !modelNode.get('isExperiment')) { $('.variate-button', this.$el).removeAttr("disabled"); } else { $('.variate-button', this.$el).attr("disabled", "disabled"); } }, dnd: { onDragStart: function (node) { return node.parent.parent != null; }, onDragEnter: function (node, sourceNode) { return true; }, onDragOver: function (node, sourceNode, hitMode) { return node.data.title !== "Experiment" || hitMode === "over"; }, onDrop: function (node, sourceNode, hitMode, ui, draggable) { if (hitMode !== 'over') return; var modelNode = OAAS_MODEL.ExperimentNode.lookup(node.data.key); if (sourceNode) { var sourceModelNode = OAAS_MODEL.ExperimentNode.lookup(sourceNode.data.key); sourceNode.move(node, hitMode); // move node into the modelNode sourceModelNode.moveNode(modelNode); } else { var elem = $(draggable.element[0]); var newNode = { nodeId: elem.attr('id'), isExperiment: elem.attr('data-isExperiment') === 'true', title: elem.attr('data-name'), key: OAAS_MODEL.ExperimentNode.nextGlobalKey() }; if (hitMode == "over") { node.addChild(newNode); node.expand(true); // update the data model newNode = modelNode.addNode(newNode); self.trigger('node-added', newNode); } } self.trigger('structure-changed', modelNode); } } }); this.tree.dynatree("getRoot").visit(function (node) { node.expand(true); }); }, initialize: function (spec) { this.renderTree(spec.model); }, events: { 'click .remove-button': 'doRemove', 'click .variate-button': 'doVariate' }, render: function () { this.$el.empty(); this.renderTree(this.model); var content = $(_.template($('#stepwizard_template').html(), {})); this.tree.appendTo(this.$el); content.appendTo(this.$el); }, doRemove: function () { var node = this.tree.dynatree('getActiveNode'); if (node && node.parent.parent != null) { var nxt = node.getNextSibling(); if (nxt == null) nxt = node.getPrevSibling(); if (nxt == null) nxt = node.getParent(); node.remove(); OAAS_MODEL.ExperimentNode.lookup(node.data.key).remove(); if (nxt) { this.tree.dynatree("getTree").activateKey(nxt.data.key); } } this.trigger('structure-changed', node); }, doVariate: function () { var node = this.tree.dynatree('getActiveNode'); var modelNode = OAAS_MODEL.ExperimentNode.lookup(node.data.key); this.trigger('variation-request', { parentNode: node.parent, model: modelNode }); } }); my.ExperimentDetailsTreeView = Backbone.View.extend({ render: function () { var jsonModel = this.model.toJSON(); var self = this; var tree = $('
').dynatree({ children: [jsonModel], autoExpandMS: 750, onActivate: function (node) { // if we click a node, simply open a dialog to enter it's parameters self.trigger('node-clicked', node); } }); this.$el.empty(); tree.appendTo(this.$el); tree.dynatree("getRoot").visit(function (node) { node.expand(true); }); } }); my.DraggableGroup = Backbone.View.extend({ initialize: function () { this.collection.bind('remove', this.render, this); this.collection.bind('add', this.render, this); }, render: function () { var self = this; var div = $('
'); if (this.collection.length == 0) { $('

').text("No items found!").appendTo(div); } for (var i = 0; i < this.collection.length; i++) { new my.DraggableView({ model: this.collection.models[i], el: div }).render(); } this.$el.empty(); div.appendTo(this.$el); } }); my.DraggableView = Backbone.View.extend({ render: function () { var late = _.template($("#draggable_template").html(), this.model.attributes); $(late).draggable({ revert: true, connectToDynatree: true, cursorAt: { top: -5, left: -5 }, helper: "clone" }).appendTo(this.$el); } }); my.SelectableGroup = Backbone.View.extend({ initialize: function () { this.collection.bind('remove', this.render, this); this.collection.bind('add', this.render, this); this.collection.bind('change', this.render, this); }, render: function () { var self = this; var div = $('
'); if (this.collection.length == 0) { $('

').text("No experiments found!").appendTo(div); } for (var i = 0; i < this.collection.length; i++) { new my.SelectableView({ model: this.collection.models[i], el: div }).render(); } this.$el.empty(); div.selectable({ filter: 'div', selected: function (event, ui) { self.selected(event, ui); } }).appendTo(this.$el); }, selected: function (event, ui) { var nodeId = $(ui.selected).attr('id'); this.trigger('node-selected', nodeId); } }); my.SelectableView = Backbone.View.extend({ render: function () { var late = _.template($("#draggable_template").html(), this.model.attributes); $(late).appendTo(this.$el); } }); my.StepWizardView = Backbone.View.extend({ render: function () { var self = this; this.$el.smartWizard({ keyNavigation: false, onLeaveStep: function (step) { var stepNum = parseInt(step.attr("rel")); return self.validateStep(stepNum); }, onShowStep: function (step) { var stepNum = parseInt(step.attr("rel")); return self.showStep(stepNum); }, onFinish: function () { self.trigger('experiment-finished'); } }); }, validateStep: function (stepNumber) { var validationModel = { stepNumber: stepNumber, succeeded: true }; this.trigger('step-validated', validationModel); return validationModel.succeeded; }, showStep: function (stepNumber) { this.trigger('step-shown', stepNumber); return true; } }); my.ParameterWizard = Backbone.View.extend({ createWizard: function (steps) { // use template instead of jquery?! var newWizard = $('
').addClass('wizard swMain'); var stepMenu = $('
    '); var prefix = name + '_'; for (var i = 0; i < steps.length; i++) { var step = steps[i]; var a = $('', { href: '#' + prefix + (i + 1) }); $('