mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
300 lines
10 KiB
JavaScript
300 lines
10 KiB
JavaScript
/*
|
|
This class maps the tool form dom to an api compatible javascript dictionary.
|
|
*/
|
|
// dependencies
|
|
define(['utils/utils'], function(Utils) {
|
|
|
|
// tool form tree
|
|
return Backbone.Model.extend({
|
|
// initialize
|
|
initialize: function(app) {
|
|
this.app = app;
|
|
},
|
|
|
|
/** Convert dictionary representation into tool api specific flat dictionary format.
|
|
*/
|
|
finalize: function(patch) {
|
|
// link this
|
|
var self = this;
|
|
|
|
// dictionary with api specific identifiers
|
|
this.map_dict = {};
|
|
|
|
// check if section is available
|
|
if (!this.app.section) {
|
|
return {};
|
|
}
|
|
|
|
// ensure that dictionary with patching functions exists
|
|
patch = patch || {};
|
|
|
|
// dictionary formatted for job submission or tool form update
|
|
var result_dict = {};
|
|
|
|
// prepare full dictionary
|
|
var dict = {};
|
|
|
|
// fill dictionary from dom
|
|
this._iterate(this.app.section.$el, dict);
|
|
|
|
// add identifier and value to job definition
|
|
function add(job_input_id, input_id, input_value) {
|
|
// add entry to result dictionary
|
|
result_dict[job_input_id] = input_value;
|
|
|
|
// backup id mapping
|
|
self.map_dict[job_input_id] = input_id;
|
|
};
|
|
|
|
// converter between raw dictionary and job dictionary
|
|
function convert(identifier, head) {
|
|
for (var index in head) {
|
|
var node = head[index];
|
|
if (node.input) {
|
|
// get node
|
|
var input = node.input;
|
|
|
|
// create identifier
|
|
var job_input_id = identifier;
|
|
if (identifier != '') {
|
|
job_input_id += '|';
|
|
}
|
|
job_input_id += input.name;
|
|
|
|
// process input type
|
|
switch (input.type) {
|
|
// handle repeats
|
|
case 'repeat':
|
|
// section identifier
|
|
var section_label = 'section-';
|
|
|
|
// collect repeat block identifiers
|
|
var block_indices = [];
|
|
var block_prefix = null;
|
|
for (var block_label in node) {
|
|
var pos = block_label.indexOf(section_label);
|
|
if (pos != -1) {
|
|
pos += section_label.length;
|
|
block_indices.push(parseInt(block_label.substr(pos)));
|
|
if (!block_prefix) {
|
|
block_prefix = block_label.substr(0, pos);
|
|
}
|
|
}
|
|
}
|
|
|
|
// sort repeat blocks
|
|
block_indices.sort(function(a,b) { return a - b; });
|
|
|
|
// add to response dictionary in created order
|
|
var index = 0;
|
|
for (var i in block_indices) {
|
|
convert(job_input_id + '_' + index++, node[block_prefix + block_indices[i]]);
|
|
}
|
|
break;
|
|
// handle conditionals
|
|
case 'conditional':
|
|
// get and patch conditional value
|
|
var value = self.app.field_list[input.id].value();
|
|
if (patch[input.test_param.type]) {
|
|
value = patch[input.test_param.type](value);
|
|
}
|
|
|
|
// add conditional value
|
|
add (job_input_id + '|' + input.test_param.name, input.id, value);
|
|
|
|
// identify selected case
|
|
var selectedCase = self.matchCase(input, value);
|
|
if (selectedCase != -1) {
|
|
convert(job_input_id, head[input.id + '-section-' + selectedCase]);
|
|
}
|
|
break;
|
|
// handle custom sub sections
|
|
case 'section':
|
|
convert('', node);
|
|
break;
|
|
default:
|
|
// get field
|
|
var field = self.app.field_list[input.id];
|
|
if (field && field.value) {
|
|
// validate field value
|
|
var value = field.value();
|
|
|
|
// get and patch field value
|
|
if (patch[input.type]) {
|
|
value = patch[input.type](value);
|
|
}
|
|
|
|
// ignore certain values
|
|
if (input.ignore === undefined || input.ignore != value) {
|
|
// add value to submission
|
|
add (job_input_id, input.id, value);
|
|
|
|
// add payload to submission
|
|
if (input.payload) {
|
|
for (var p_id in input.payload) {
|
|
add (p_id, input.id, input.payload[p_id]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// start conversion
|
|
convert('', dict);
|
|
|
|
// return result
|
|
return result_dict;
|
|
},
|
|
|
|
/** Match job definition identifier to input element identifier
|
|
*/
|
|
match: function (job_input_id) {
|
|
return this.map_dict && this.map_dict[job_input_id];
|
|
},
|
|
|
|
/** Match conditional values to selected cases
|
|
*/
|
|
matchCase: function(input, value) {
|
|
// format value for boolean inputs
|
|
if (input.test_param.type == 'boolean') {
|
|
if (value == 'true') {
|
|
value = input.test_param.truevalue || 'true';
|
|
} else {
|
|
value = input.test_param.falsevalue || 'false';
|
|
}
|
|
}
|
|
|
|
// find selected case
|
|
for (var i in input.cases) {
|
|
if (input.cases[i].value == value) {
|
|
return i;
|
|
}
|
|
}
|
|
|
|
// selected case not found
|
|
return -1;
|
|
},
|
|
|
|
/** Matches identifier from api model to input elements
|
|
*/
|
|
matchModel: function(model, callback) {
|
|
// final result dictionary
|
|
var result = {};
|
|
|
|
// link this
|
|
var self = this;
|
|
|
|
// search throughout response
|
|
function search (id, head) {
|
|
for (var i in head) {
|
|
var node = head[i];
|
|
var index = node.name;
|
|
if (id != '') {
|
|
index = id + '|' + index;
|
|
}
|
|
switch (node.type) {
|
|
case 'repeat':
|
|
for (var j in node.cache) {
|
|
search (index + '_' + j, node.cache[j]);
|
|
}
|
|
break;
|
|
case 'conditional':
|
|
var value = node.test_param && node.test_param.value;
|
|
var selectedCase = self.matchCase(node, value);
|
|
if (selectedCase != -1) {
|
|
search (index, node.cases[selectedCase].inputs);
|
|
}
|
|
break;
|
|
default:
|
|
var input_id = self.map_dict[index];
|
|
if (input_id) {
|
|
callback(input_id, node);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// match all ids and return messages
|
|
search('', model.inputs);
|
|
|
|
// return matched results
|
|
return result;
|
|
},
|
|
|
|
/** Matches identifier from api response to input elements
|
|
*/
|
|
matchResponse: function(response) {
|
|
// final result dictionary
|
|
var result = {};
|
|
|
|
// link this
|
|
var self = this;
|
|
|
|
// search throughout response
|
|
function search (id, head) {
|
|
if (typeof head === 'string') {
|
|
var input_id = self.map_dict[id];
|
|
if (input_id) {
|
|
result[input_id] = head;
|
|
}
|
|
} else {
|
|
for (var i in head) {
|
|
var new_id = i;
|
|
if (id !== '') {
|
|
var separator = '|';
|
|
if (head instanceof Array) {
|
|
separator = '_';
|
|
}
|
|
new_id = id + separator + new_id;
|
|
}
|
|
search (new_id, head[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
// match all ids and return messages
|
|
search('', response);
|
|
|
|
// return matched results
|
|
return result;
|
|
},
|
|
|
|
/** Iterate through the tool form dom and map it to the dictionary.
|
|
*/
|
|
_iterate: function(parent, dict) {
|
|
// get child nodes
|
|
var self = this;
|
|
var children = $(parent).children();
|
|
children.each(function() {
|
|
// get child element
|
|
var child = this;
|
|
|
|
// get id
|
|
var id = $(child).attr('id');
|
|
|
|
// create new branch
|
|
if ($(child).hasClass('section-row')) {
|
|
// create sub dictionary
|
|
dict[id] = {};
|
|
|
|
// add input element if it exists
|
|
var input = self.app.input_list[id];
|
|
if (input) {
|
|
dict[id] = {
|
|
input : input
|
|
}
|
|
}
|
|
|
|
// fill sub dictionary
|
|
self._iterate(child, dict[id]);
|
|
} else {
|
|
self._iterate(child, dict);
|
|
}
|
|
});
|
|
}
|
|
});
|
|
|
|
}); |