
1 new commit in galaxy-central: https://bitbucket.org/galaxy/galaxy-central/commits/5a846bf0080b/ Changeset: 5a846bf0080b User: guerler Date: 2014-09-24 18:37:34+00:00 Summary: ToolForm: Additional validation for batch mode, style fixes Affected #: 11 files diff -r 7d53a4a090a4b17ea46a256b4dc16712297d48ec -r 5a846bf0080bc7db4b7d99e9f6046182fbff8ec5 client/galaxy/scripts/mvc/tools/tools-jobs.js --- a/client/galaxy/scripts/mvc/tools/tools-jobs.js +++ b/client/galaxy/scripts/mvc/tools/tools-jobs.js @@ -32,6 +32,7 @@ console.debug('tools-jobs::submit - Submission canceled. Validation failed.'); return; } + console.log(job_def); // post job Utils.request('POST', galaxy_config.root + 'api/tools', job_def, @@ -66,27 +67,59 @@ // validation flag var valid = true; - // check inputs + // link this + var self = this; + + /** Highlight and scroll to error */ + function foundError (input_id, message) { + // get input field + var input_element = self.app.element_list[input_id]; + + // mark error + input_element.error(message || 'Please verify this parameter.'); + + // set flag + if (valid) { + // scroll to first input element + $(self.app.container).animate({ + scrollTop: input_element.$el.offset().top - 20 + }, 500); + + // set error flag + valid = false; + } + } + + // counter for values declared in batch mode + var n_values = -1; + + // validation for (var job_input_id in job_inputs) { + // get current value + var input_value = job_inputs[job_input_id]; + // collect input field properties - var input = job_inputs[job_input_id]; var input_id = this.app.tree.match(job_input_id); var input_field = this.app.field_list[input_id]; - var input_element = this.app.element_list[input_id]; + var input_def = this.app.input_list[input_id]; - // check field validation - if (input && !input.optional && input_field && input_field.validate && !input_field.validate()) { - this.app.element_list[input_id].error('Please verify this parameter.'); - if (valid) { - // scroll to first input element - $(this.app.container).animate({ - scrollTop: input_element.$el.offset().top - 20 - }, 500); - - // validation failed - valid = false; + // check basic field validation + if (input_def && !input_def.optional && input_field && input_field.validate && !input_field.validate()) { + foundError(input_id); + } + + // check if input field is in batch mode + if (input_value.batch) { + var n = input_value.values.length; + if (n_values === -1) { + n_values = n; + } else { + if (n_values !== n) { + foundError(input_id, 'Please make sure that you select the same number of inputs for all batch mode fields. This field contains <b>' + n + '</b> selection(s) while a previous field contains <b>' + n_values + '</b>.'); + } } } + } // return result diff -r 7d53a4a090a4b17ea46a256b4dc16712297d48ec -r 5a846bf0080bc7db4b7d99e9f6046182fbff8ec5 client/galaxy/scripts/mvc/tools/tools-select-dataset.js --- a/client/galaxy/scripts/mvc/tools/tools-select-dataset.js +++ b/client/galaxy/scripts/mvc/tools/tools-select-dataset.js @@ -1,9 +1,12 @@ // dependencies -define(['utils/utils', 'mvc/ui/ui-misc', 'mvc/ui/ui-tabs'], function(Utils, Ui, Tabs) { +define(['utils/utils', 'mvc/ui/ui-misc', 'mvc/ui/ui-tabs', 'mvc/tools/tools-template'], function(Utils, Ui, Tabs, ToolTemplate) { var View = Backbone.View.extend({ // initialize initialize : function(app, options) { + // configure options + this.options = options; + // link this var self = this; @@ -83,6 +86,11 @@ this.$el.append(this.select_datasets.$el); this.$el.append(this.select_collection.$el); + // check for batch mode + if (!this.options.multiple) { + this.$el.append(ToolTemplate.batchMode()); + } + // refresh view this.refresh(); diff -r 7d53a4a090a4b17ea46a256b4dc16712297d48ec -r 5a846bf0080bc7db4b7d99e9f6046182fbff8ec5 client/galaxy/scripts/mvc/tools/tools-template.js --- a/client/galaxy/scripts/mvc/tools/tools-template.js +++ b/client/galaxy/scripts/mvc/tools/tools-template.js @@ -38,6 +38,13 @@ // return success message element return tmpl; + }, + + batchMode: function() { + return '<div class="ui-table-form-info">' + + '<i class="fa fa-sitemap" style="font-size: 1.2em; padding: 2px 5px;"/>' + + 'This is a batch mode input field. A separate job will be triggered for each dataset.' + '</div>'; } }; diff -r 7d53a4a090a4b17ea46a256b4dc16712297d48ec -r 5a846bf0080bc7db4b7d99e9f6046182fbff8ec5 static/scripts/mvc/tools/tools-jobs.js --- a/static/scripts/mvc/tools/tools-jobs.js +++ b/static/scripts/mvc/tools/tools-jobs.js @@ -32,6 +32,7 @@ console.debug('tools-jobs::submit - Submission canceled. Validation failed.'); return; } + console.log(job_def); // post job Utils.request('POST', galaxy_config.root + 'api/tools', job_def, @@ -66,27 +67,59 @@ // validation flag var valid = true; - // check inputs + // link this + var self = this; + + /** Highlight and scroll to error */ + function foundError (input_id, message) { + // get input field + var input_element = self.app.element_list[input_id]; + + // mark error + input_element.error(message || 'Please verify this parameter.'); + + // set flag + if (valid) { + // scroll to first input element + $(self.app.container).animate({ + scrollTop: input_element.$el.offset().top - 20 + }, 500); + + // set error flag + valid = false; + } + } + + // counter for values declared in batch mode + var n_values = -1; + + // validation for (var job_input_id in job_inputs) { + // get current value + var input_value = job_inputs[job_input_id]; + // collect input field properties - var input = job_inputs[job_input_id]; var input_id = this.app.tree.match(job_input_id); var input_field = this.app.field_list[input_id]; - var input_element = this.app.element_list[input_id]; + var input_def = this.app.input_list[input_id]; - // check field validation - if (input && !input.optional && input_field && input_field.validate && !input_field.validate()) { - this.app.element_list[input_id].error('Please verify this parameter.'); - if (valid) { - // scroll to first input element - $(this.app.container).animate({ - scrollTop: input_element.$el.offset().top - 20 - }, 500); - - // validation failed - valid = false; + // check basic field validation + if (input_def && !input_def.optional && input_field && input_field.validate && !input_field.validate()) { + foundError(input_id); + } + + // check if input field is in batch mode + if (input_value.batch) { + var n = input_value.values.length; + if (n_values === -1) { + n_values = n; + } else { + if (n_values !== n) { + foundError(input_id, 'Please make sure that you select the same number of inputs for all batch mode fields. This field contains <b>' + n + '</b> selection(s) while a previous field contains <b>' + n_values + '</b>.'); + } } } + } // return result diff -r 7d53a4a090a4b17ea46a256b4dc16712297d48ec -r 5a846bf0080bc7db4b7d99e9f6046182fbff8ec5 static/scripts/mvc/tools/tools-select-dataset.js --- a/static/scripts/mvc/tools/tools-select-dataset.js +++ b/static/scripts/mvc/tools/tools-select-dataset.js @@ -1,9 +1,12 @@ // dependencies -define(['utils/utils', 'mvc/ui/ui-misc', 'mvc/ui/ui-tabs'], function(Utils, Ui, Tabs) { +define(['utils/utils', 'mvc/ui/ui-misc', 'mvc/ui/ui-tabs', 'mvc/tools/tools-template'], function(Utils, Ui, Tabs, ToolTemplate) { var View = Backbone.View.extend({ // initialize initialize : function(app, options) { + // configure options + this.options = options; + // link this var self = this; @@ -83,6 +86,11 @@ this.$el.append(this.select_datasets.$el); this.$el.append(this.select_collection.$el); + // check for batch mode + if (!this.options.multiple) { + this.$el.append(ToolTemplate.batchMode()); + } + // refresh view this.refresh(); diff -r 7d53a4a090a4b17ea46a256b4dc16712297d48ec -r 5a846bf0080bc7db4b7d99e9f6046182fbff8ec5 static/scripts/mvc/tools/tools-template.js --- a/static/scripts/mvc/tools/tools-template.js +++ b/static/scripts/mvc/tools/tools-template.js @@ -38,6 +38,13 @@ // return success message element return tmpl; + }, + + batchMode: function() { + return '<div class="ui-table-form-info">' + + '<i class="fa fa-sitemap" style="font-size: 1.2em; padding: 2px 5px;"/>' + + 'This is a batch mode input field. A separate job will be triggered for each dataset.' + '</div>'; } }; diff -r 7d53a4a090a4b17ea46a256b4dc16712297d48ec -r 5a846bf0080bc7db4b7d99e9f6046182fbff8ec5 static/scripts/packed/mvc/tools/tools-jobs.js --- a/static/scripts/packed/mvc/tools/tools-jobs.js +++ b/static/scripts/packed/mvc/tools/tools-jobs.js @@ -1,1 +1,1 @@ -define(["utils/utils","mvc/tools/tools-template"],function(b,a){return Backbone.Model.extend({initialize:function(d,c){this.app=d;this.options=b.merge(c,this.optionsDefault)},submit:function(){var c=this;var d={tool_id:this.app.options.id,inputs:this.app.tree.finalize()};this.app.reset();if(!this._validation(d)){console.debug("tools-jobs::submit - Submission canceled. Validation failed.");return}b.request("POST",galaxy_config.root+"api/tools",d,function(e){c.app.message(a.success(e));c._refreshHdas()},function(e){console.debug(e);if(e&&e.message&&e.message.data){var h=c.app.tree.matchResponse(e.message.data);for(var g in h){var f=h[g];if(!f){f="Please verify this parameter."}c.app.element_list[g].error(f)}}})},_validation:function(h){var e=h.inputs;var g=true;for(var j in e){var d=e[j];var f=this.app.tree.match(j);var c=this.app.field_list[f];var i=this.app.element_list[f];if(d&&!d.optional&&c&&c.validate&&!c.validate()){this.app.element_list[f].error("Please verify this parameter.");if(g){$(this.app.container).animate({scrollTop:i.$el.offset().top-20},500);g=false}}}return g},_refreshHdas:function(){if(parent.Galaxy&&parent.Galaxy.currHistoryPanel){parent.Galaxy.currHistoryPanel.refreshContents()}}})}); \ No newline at end of file +define(["utils/utils","mvc/tools/tools-template"],function(b,a){return Backbone.Model.extend({initialize:function(d,c){this.app=d;this.options=b.merge(c,this.optionsDefault)},submit:function(){var c=this;var d={tool_id:this.app.options.id,inputs:this.app.tree.finalize()};this.app.reset();if(!this._validation(d)){console.debug("tools-jobs::submit - Submission canceled. Validation failed.");return}console.log(d);b.request("POST",galaxy_config.root+"api/tools",d,function(e){c.app.message(a.success(e));c._refreshHdas()},function(e){console.debug(e);if(e&&e.message&&e.message.data){var h=c.app.tree.matchResponse(e.message.data);for(var g in h){var f=h[g];if(!f){f="Please verify this parameter."}c.app.element_list[g].error(f)}}})},_validation:function(h){var e=h.inputs;var c=true;var o=this;function m(n,p){var q=o.app.element_list[n];q.error(p||"Please verify this parameter.");if(c){$(o.app.container).animate({scrollTop:q.$el.offset().top-20},500);c=false}}var l=-1;for(var k in e){var f=e[k];var j=this.app.tree.match(k);var d=this.app.field_list[j];var i=this.app.input_list[j];if(i&&!i.optional&&d&&d.validate&&!d.validate()){m(j)}if(f.batch){var g=f.values.length;if(l===-1){l=g}else{if(l!==g){m(j,"Please make sure that you select the same number of inputs for all batch mode fields. This field contains <b>"+g+"</b> selection(s) while a previous field contains <b>"+l+"</b>.")}}}}return c},_refreshHdas:function(){if(parent.Galaxy&&parent.Galaxy.currHistoryPanel){parent.Galaxy.currHistoryPanel.refreshContents()}}})}); \ No newline at end of file diff -r 7d53a4a090a4b17ea46a256b4dc16712297d48ec -r 5a846bf0080bc7db4b7d99e9f6046182fbff8ec5 static/scripts/packed/mvc/tools/tools-select-dataset.js --- a/static/scripts/packed/mvc/tools/tools-select-dataset.js +++ b/static/scripts/packed/mvc/tools/tools-select-dataset.js @@ -1,1 +1,1 @@ -define(["utils/utils","mvc/ui/ui-misc","mvc/ui/ui-tabs"],function(b,d,a){var c=Backbone.View.extend({initialize:function(m,g){var f=this;this.setElement("<div/>");this.current="hda";this.button_new=new d.RadioButton.View({value:this.current,data:[{icon:"fa-file-o",label:"Select datasets",value:"hda"},{icon:"fa-files-o",label:"Select a collection",value:"hdca"}],onchange:function(i){f.current=i;f.refresh();f.trigger("change")}});var k=m.datasets.filterType({content_type:"dataset",data_types:g.extensions});var j=[];for(var h in k){j.push({label:k[h].get("name"),value:k[h].get("id")})}this.select_datasets=new d.Select.View({multiple:true,data:j,value:j[0]&&j[0].value,onchange:function(){f.trigger("change")}});var l=m.datasets.filterType({content_type:"collection",data_types:g.extensions});var e=[];for(var h in l){e.push({label:l[h].get("name"),value:l[h].get("id")})}this.select_collection=new d.Select.View({data:e,value:e[0]&&e[0].value,onchange:function(){f.trigger("change")}});this.$el.append(b.wrap(this.button_new.$el));this.$el.append(this.select_datasets.$el);this.$el.append(this.select_collection.$el);this.refresh();this.on("change",function(){if(g.onchange){g.onchange(f.value())}})},value:function(){var f=null;switch(this.current){case"hda":f=this.select_datasets;break;case"hdca":f=this.select_collection;break}var h=f.value();if(!(h instanceof Array)){h=[h]}var e={batch:!this.options.multiple,values:[]};for(var g in h){e.values.push({id:h[g],src:this.current})}return e},validate:function(){switch(this.current){case"hda":return this.select_datasets.validate();case"hdca":return this.select_collection.validate()}},refresh:function(){switch(this.current){case"hda":this.select_datasets.$el.fadeIn();this.select_collection.$el.hide();break;case"hdca":this.select_datasets.$el.hide();this.select_collection.$el.fadeIn();break}}});return{View:c}}); \ No newline at end of file +define(["utils/utils","mvc/ui/ui-misc","mvc/ui/ui-tabs","mvc/tools/tools-template"],function(c,e,b,a){var d=Backbone.View.extend({initialize:function(n,h){this.options=h;var g=this;this.setElement("<div/>");this.current="hda";this.button_new=new e.RadioButton.View({value:this.current,data:[{icon:"fa-file-o",label:"Select datasets",value:"hda"},{icon:"fa-files-o",label:"Select a collection",value:"hdca"}],onchange:function(i){g.current=i;g.refresh();g.trigger("change")}});var l=n.datasets.filterType({content_type:"dataset",data_types:h.extensions});var k=[];for(var j in l){k.push({label:l[j].get("name"),value:l[j].get("id")})}this.select_datasets=new e.Select.View({multiple:true,data:k,value:k[0]&&k[0].value,onchange:function(){g.trigger("change")}});var m=n.datasets.filterType({content_type:"collection",data_types:h.extensions});var f=[];for(var j in m){f.push({label:m[j].get("name"),value:m[j].get("id")})}this.select_collection=new e.Select.View({data:f,value:f[0]&&f[0].value,onchange:function(){g.trigger("change")}});this.$el.append(c.wrap(this.button_new.$el));this.$el.append(this.select_datasets.$el);this.$el.append(this.select_collection.$el);if(!this.options.multiple){this.$el.append(a.batchMode())}this.refresh();this.on("change",function(){if(h.onchange){h.onchange(g.value())}})},value:function(){var g=null;switch(this.current){case"hda":g=this.select_datasets;break;case"hdca":g=this.select_collection;break}var j=g.value();if(!(j instanceof Array)){j=[j]}var f={batch:!this.options.multiple,values:[]};for(var h in j){f.values.push({id:j[h],src:this.current})}return f},validate:function(){switch(this.current){case"hda":return this.select_datasets.validate();case"hdca":return this.select_collection.validate()}},refresh:function(){switch(this.current){case"hda":this.select_datasets.$el.fadeIn();this.select_collection.$el.hide();break;case"hdca":this.select_datasets.$el.hide();this.select_collection.$el.fadeIn();break}}});return{View:d}}); \ No newline at end of file diff -r 7d53a4a090a4b17ea46a256b4dc16712297d48ec -r 5a846bf0080bc7db4b7d99e9f6046182fbff8ec5 static/scripts/packed/mvc/tools/tools-template.js --- a/static/scripts/packed/mvc/tools/tools-template.js +++ b/static/scripts/packed/mvc/tools/tools-template.js @@ -1,1 +1,1 @@ -define([],function(){return{help:function(a){return'<div class="toolHelp"><div class="toolHelpBody">'+a+"</div></div>"},citations:function(){return'<div id="citations"></div>'},success:function(c){var a=c.jobs.length;var d="";if(a==1){d="1 job has"}else{d=a+" jobs have been"}var b='<div class="donemessagelarge"><p>'+d+" been successfully added to the queue - resulting in the following datasets:</p>";for(var e in c.outputs){b+='<p style="padding: 10px 20px;"><b>'+(parseInt(e)+1)+": "+c.outputs[e].name+"</b></p>"}b+="<p>You can check the status of queued jobs and view the resulting data by refreshing the History pane. When the job has been run the status will change from 'running' to 'finished' if completed successfully or 'error' if problems were encountered.</p></div>";return b}}}); \ No newline at end of file +define([],function(){return{help:function(a){return'<div class="toolHelp"><div class="toolHelpBody">'+a+"</div></div>"},citations:function(){return'<div id="citations"></div>'},success:function(c){var a=c.jobs.length;var d="";if(a==1){d="1 job has"}else{d=a+" jobs have been"}var b='<div class="donemessagelarge"><p>'+d+" been successfully added to the queue - resulting in the following datasets:</p>";for(var e in c.outputs){b+='<p style="padding: 10px 20px;"><b>'+(parseInt(e)+1)+": "+c.outputs[e].name+"</b></p>"}b+="<p>You can check the status of queued jobs and view the resulting data by refreshing the History pane. When the job has been run the status will change from 'running' to 'finished' if completed successfully or 'error' if problems were encountered.</p></div>";return b},batchMode:function(){return'<div class="ui-table-form-info"><i class="fa fa-sitemap" style="font-size: 1.2em; padding: 2px 5px;"/>This is a batch mode input field. A separate job will be triggered for each dataset.';"</div>"}}}); \ No newline at end of file diff -r 7d53a4a090a4b17ea46a256b4dc16712297d48ec -r 5a846bf0080bc7db4b7d99e9f6046182fbff8ec5 static/style/blue/base.css --- a/static/style/blue/base.css +++ b/static/style/blue/base.css @@ -1294,7 +1294,7 @@ .ui-button-icon{margin-right:5px}.ui-button-icon ul i{font-size:1.2em;margin-right:5px;position:relative;top:1px} .ui-button-icon .button{margin-right:5px;margin-left:5px}.ui-button-icon .button .title{position:relative;font-size:0.8em;font-weight:normal;top:-1px} .ui-button-icon .button.disabled{filter:alpha(opacity=65);opacity:.65;-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=65);filter:alpha(opacity=65)} -.ui-button-icon-plain{border:none !important;background:none !important} +.ui-button-icon-plain{border:none !important;background:none !important;height:inherit !important} .ui-tabs .ui-tabs-add{font-size:0.8em;margin-right:5px} .ui-tabs .ui-tabs-delete{font-size:0.8em;margin-left:5px;cursor:pointer} .ui-portlet,.ui-portlet-repeat,.ui-portlet-repeat{border:solid #d6b161 1px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;position:relative;clear:both;width:auto;height:100%}.ui-portlet .portlet-header{background:#ebd9b2;border-bottom:solid #d6b161 1px;padding:2px 8px;overflow:visible;float:right;width:100%}.ui-portlet .portlet-header .portlet-title .portlet-title-text{vertical-align:middle} diff -r 7d53a4a090a4b17ea46a256b4dc16712297d48ec -r 5a846bf0080bc7db4b7d99e9f6046182fbff8ec5 static/style/src/less/ui.less --- a/static/style/src/less/ui.less +++ b/static/style/src/less/ui.less @@ -109,6 +109,7 @@ &:extend(.icon-btn); border: none !important; background: none !important; + height: inherit !important; } .ui-tabs { Repository URL: https://bitbucket.org/galaxy/galaxy-central/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email.