1 /** 2 * @fileOverview 3 * @author <a href="https://www.labkey.org">LabKey</a> (<a href="mailto:info@labkey.com">info@labkey.com</a>) 4 * @license Copyright (c) 2012-2019 LabKey Corporation 5 * <p/> 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * <p/> 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * <p/> 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 * <p/> 18 */ 19 20 /** 21 * @namespace The Experiment static class allows you to create hidden run groups and other experiment-related functionality. 22 * <p>Additional Documentation: 23 * <ul> 24 * <li><a href='https://www.labkey.org/Documentation/wiki-page.view?name=moduleassay'>LabKey File-Based Assays</a></li> 25 * <li><a href="https://www.labkey.org/Documentation/wiki-page.view?name=experiment">LabKey Experiment</a></li> 26 * </ul> 27 * </p> 28 */ 29 LABKEY.Experiment = new function() 30 { 31 function getSuccessCallbackWrapper(createExpFn, fn, scope) 32 { 33 return function(response, options) 34 { 35 //ensure response is JSON before trying to decode 36 var json = null; 37 var experiment = null; 38 if (response && response.getResponseHeader && response.getResponseHeader('Content-Type') 39 && response.getResponseHeader('Content-Type').indexOf('application/json') >= 0) 40 { 41 json = LABKEY.Utils.decode(response.responseText); 42 experiment = createExpFn(json); 43 } 44 45 if(fn) 46 fn.call(scope || this, experiment, response); 47 }; 48 } 49 50 function _saveBatches(config, createExps) 51 { 52 LABKEY.Ajax.request({ 53 url: LABKEY.ActionURL.buildURL("assay", "saveAssayBatch", LABKEY.ActionURL.getContainer()), 54 method: 'POST', 55 jsonData: { 56 assayId: config.assayId, 57 assayName: config.assayName, 58 providerName: config.providerName, 59 protocolName : config.protocolName, 60 batches: config.batches 61 }, 62 success: getSuccessCallbackWrapper(createExps, config.success, config.scope), 63 failure: LABKEY.Utils.getCallbackWrapper(config.failure, config.scope, true), 64 scope: config.scope, 65 headers: { 66 'Content-Type' : 'application/json' 67 } 68 }); 69 } 70 71 // normalize the different config object passed in for saveBatch and saveBatches into one config 72 // appropriate for _saveBatches call above 73 function getSaveBatchesConfig(config) 74 { 75 var wrapConfig = {}; 76 77 if (config.batches) 78 { 79 wrapConfig.batches = config.batches; 80 } 81 else 82 { 83 wrapConfig.batches=[]; 84 wrapConfig.batches.push(config.batch); 85 } 86 wrapConfig.assayId = config.assayId; 87 wrapConfig.assayName = config.assayName; 88 wrapConfig.providerName = config.providerName; 89 wrapConfig.protocolName = config.protocolName; 90 wrapConfig.scope = config.scope; 91 wrapConfig.success = LABKEY.Utils.getOnSuccess(config); 92 wrapConfig.failure = LABKEY.Utils.getOnFailure(config); 93 return wrapConfig; 94 } 95 96 /** @scope LABKEY.Experiment */ 97 return { 98 99 SAMPLE_DERIVATION_PROTOCOL : "Sample Derivation Protocol", 100 101 /** 102 * Create or recycle an existing run group. Run groups are the basis for some operations, like comparing 103 * MS2 runs to one another. 104 * @param config A configuration object with the following properties: 105 * @param {function} config.success A reference to a function to call with the API results. This 106 * function will be passed the following parameters: 107 * <ul> 108 * <li><b>runGroup:</b> a {@link LABKEY.Exp.RunGroup} object containing properties about the run group</li> 109 * <li><b>response:</b> The XMLHttpResponse object</li> 110 * </ul> 111 * @param {Integer[]} [config.runIds] An array of integer ids for the runs to be members of the group. Either 112 * runIds or selectionKey must be specified. 113 * @param {string} [config.selectionKey] The DataRegion's selectionKey to be used to resolve the runs to be 114 * members of the group. Either runIds or selectionKey must be specified. 115 * @param {function} [config.failure] A reference to a function to call when an error occurs. This 116 * function will be passed the following parameters: 117 * <ul> 118 * <li><b>errorInfo:</b> an object containing detailed error information (may be null)</li> 119 * <li><b>response:</b> The XMLHttpResponse object</li> 120 * </ul> 121 * @param {string} [config.containerPath] An alternate container path to get permissions from. If not specified, 122 * the current container path will be used. 123 * @param {object} [config.scope] A scoping object for the success and error callback functions (default to this). 124 * @static 125 */ 126 createHiddenRunGroup : function (config) 127 { 128 function createExp(json) 129 { 130 return new LABKEY.Exp.RunGroup(json); 131 } 132 133 var jsonData = {}; 134 if (config.runIds && config.selectionKey) 135 { 136 throw "Only one of runIds or selectionKey config parameter is allowed for a single call."; 137 } 138 else if (config.runIds) 139 { 140 jsonData.runIds = config.runIds; 141 } 142 else if (config.selectionKey) 143 { 144 jsonData.selectionKey = config.selectionKey; 145 } 146 else 147 { 148 throw "Either the runIds or the selectionKey config parameter is required."; 149 } 150 LABKEY.Ajax.request( 151 { 152 url : LABKEY.ActionURL.buildURL("experiment", "createHiddenRunGroup", config.containerPath), 153 method : 'POST', 154 jsonData : jsonData, 155 success: getSuccessCallbackWrapper(createExp, LABKEY.Utils.getOnSuccess(config), config.scope), 156 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true), 157 headers : 158 { 159 'Content-Type' : 'application/json' 160 } 161 }); 162 }, 163 164 /** 165 * Loads a batch from the server. 166 * @param config An object that contains the following configuration parameters 167 * @param {Number} config.assayId The assay protocol id. 168 * @param {Number} config.batchId The batch id. 169 * @param {function} config.success The function to call when the function finishes successfully. 170 * This function will be called with a the parameters: 171 * <ul> 172 * <li><b>batch</b> A new {@link LABKEY.Exp.RunGroup} object. 173 * <li><b>response</b> The original response 174 * </ul> 175 * @param {function} [config.failure] The function to call if this function encounters an error. 176 * This function will be called with the following parameters: 177 * <ul> 178 * <li><b>response</b> The original response 179 * </ul> 180 * @param {object} [config.scope] A scoping object for the success and error callback functions (default to this). 181 * @see The <a href='https://www.labkey.org/Documentation/wiki-page.view?name=moduleassay'>Module Assay</a> documentation for more information. 182 * @example Load batch: 183 LABKEY.Experiment.loadBatch({ 184 protocolName: LABKEY.Experiment.SAMPLE_DERIVATION_PROTOCOL, 185 batchId: 12 186 }); 187 */ 188 loadBatch : function (config) 189 { 190 function createExp(json) 191 { 192 return new LABKEY.Exp.RunGroup(json.batch); 193 } 194 195 LABKEY.Ajax.request({ 196 url: LABKEY.ActionURL.buildURL("assay", "getAssayBatch", LABKEY.ActionURL.getContainer()), 197 method: 'POST', 198 success: getSuccessCallbackWrapper(createExp, LABKEY.Utils.getOnSuccess(config), config.scope), 199 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true), 200 scope: config.scope, 201 jsonData : { 202 assayId: config.assayId, 203 assayName: config.assayName, 204 protocolName: config.protocolName, 205 providerName: config.providerName, 206 batchId: config.batchId 207 }, 208 headers : { 209 'Content-Type' : 'application/json' 210 } 211 }); 212 }, 213 214 /** 215 * Loads batches from the server. 216 * @param config An object that contains the following configuration parameters 217 * @param {Number} config.assayId The assay protocol id. 218 * @param {Number} config.batchIds The list of batch ids. 219 * @param {function} config.success The function to call when the function finishes successfully. 220 * This function will be called with a the parameters: 221 * <ul> 222 * <li><b>batches</b> The list of {@link LABKEY.Exp.RunGroup} objects. 223 * <li><b>response</b> The original response 224 * </ul> 225 * @param {function} [config.failure] The function to call if this function encounters an error. 226 * This function will be called with the following parameters: 227 * <ul> 228 * <li><b>response</b> The original response 229 * </ul> 230 * @param {object} [config.scope] A scoping object for the success and error callback functions (default to this). 231 * @see The <a href='https://www.labkey.org/Documentation/wiki-page.view?name=moduleassay'>Module Assay</a> documentation for more information. 232 * @static 233 */ 234 loadBatches : function (config) 235 { 236 function createExp(json) 237 { 238 var batches = []; 239 if (json.batches) { 240 for (var i = 0; i < json.batches.length; i++) { 241 batches.push(new LABKEY.Exp.RunGroup(json.batches[i])); 242 } 243 } 244 return batches; 245 } 246 247 LABKEY.Ajax.request({ 248 url: LABKEY.ActionURL.buildURL("assay", "getAssayBatches", LABKEY.ActionURL.getContainer()), 249 method: 'POST', 250 success: getSuccessCallbackWrapper(createExp, LABKEY.Utils.getOnSuccess(config), config.scope), 251 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true), 252 scope: config.scope, 253 jsonData : { 254 assayId: config.assayId, 255 assayName: config.assayName, 256 protocolName: config.protocolName, 257 providerName: config.providerName, 258 batchIds: config.batchIds 259 }, 260 headers : { 261 'Content-Type' : 'application/json' 262 } 263 }); 264 }, 265 266 /** 267 * Loads runs from the server. 268 * @param config An object that contains the following configuration parameters 269 * @param {Array} config.lsids. The list of run lsids. 270 * @param {Array} config.runIds The list of run ids. 271 * @param {function} config.success The function to call when the function finishes successfully. 272 * This function will be called with a the parameters: 273 * <ul> 274 * <li><b>runs</b> The list of {@link LABKEY.Exp.Run} objects. 275 * <li><b>response</b> The original response 276 * </ul> 277 * @param {function} [config.failure] The function to call if this function encounters an error. 278 * This function will be called with the following parameters: 279 * <ul> 280 * <li><b>response</b> The original response 281 * </ul> 282 * @param {object} [config.scope] A scoping object for the success and error callback functions (default to this). 283 * @see The <a href='https://www.labkey.org/Documentation/wiki-page.view?name=moduleassay'>Module Assay</a> documentation for more information. 284 * @static 285 */ 286 loadRuns : function (config) 287 { 288 function createExp(json) 289 { 290 var runs = []; 291 if (json.runs) { 292 for (var i = 0; i < json.runs.length; i++) { 293 runs.push(new LABKEY.Exp.Run(json.runs[i])); 294 } 295 } 296 return runs; 297 } 298 299 LABKEY.Ajax.request({ 300 url: LABKEY.ActionURL.buildURL("assay", "getAssayRuns.api", LABKEY.ActionURL.getContainer()), 301 method: 'POST', 302 success: getSuccessCallbackWrapper(createExp, LABKEY.Utils.getOnSuccess(config), config.scope), 303 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true), 304 scope: config.scope, 305 jsonData : { 306 runIds: config.runIds, 307 lsids: config.lsids 308 }, 309 headers : { 310 'Content-Type' : 'application/json' 311 } 312 }); 313 }, 314 315 /** 316 * Saves a modified batch. 317 * Runs within the batch may refer to existing data and material objects, either inputs or outputs, by ID or LSID. 318 * Runs may also define new data and materials objects by not specifying an ID or LSID in their properties. 319 * @param config An object that contains the following configuration parameters 320 * @param {Number} [config.assayId] Optional assay protocol id, either assayId or protocolName must be specified. 321 * @param {String} [config.protocolName] Optional protocol name to be used for non-assay backed runs. Currently only 322 * SAMPLE_DERIVATION_PROTOCOL is supported. 323 * @param {LABKEY.Exp.RunGroup} config.batch The modified batch object. 324 * @param {function} config.success The function to call when the function finishes successfully. 325 * This function will be called with the following parameters: 326 * <ul> 327 * <li><b>batch</b> A new {@link LABKEY.Exp.RunGroup} object. Some values (such as IDs and LSIDs) will be filled in by the server. 328 * <li><b>response</b> The original response 329 * </ul> 330 * @param {function} [config.failure] The function to call if this function encounters an error. 331 * This function will be called with the following parameters: 332 * <ul> 333 * <li><b>response</b> The original response 334 * </ul> 335 * @see The <a href='https://www.labkey.org/Documentation/wiki-page.view?name=moduleassay'>Module Assay</a> documentation for more information. 336 * @example Save batch: 337 LABKEY.Experiment.saveBatch({ 338 protocolName: LABKEY.Experiment.SAMPLE_DERIVATION_PROTOCOL, 339 batch: { 340 properties: { 341 // property URI from a Vocabulary 342 'urn:lsid:labkey.com:Vocabulary.Folder-114:MyVocab#field1': '123' 343 }, 344 runs: [{ 345 name: 'two', 346 properties: { 347 // property URI from a Vocabulary 348 'urn:lsid:labkey.com:Vocabulary.Folder-114:MyVocab#field1': '123' 349 } 350 }] 351 } 352 }); 353 */ 354 saveBatch : function (config) 355 { 356 _saveBatches(getSaveBatchesConfig(config), function(json) { 357 if (json.batches) { 358 return new LABKEY.Exp.RunGroup(json.batches[0]) 359 } 360 }); 361 }, 362 363 saveRuns: function (config) 364 { 365 function createExp(json) 366 { 367 var runs = []; 368 if (json.runs) { 369 for (var i = 0; i < json.runs.length; i++) { 370 runs.push(new LABKEY.Exp.Run(json.runs[i])); 371 } 372 } 373 return runs; 374 } 375 376 LABKEY.Ajax.request({ 377 url: LABKEY.ActionURL.buildURL("assay", "saveAssayRuns.api", LABKEY.ActionURL.getContainer()), 378 method: 'POST', 379 success: getSuccessCallbackWrapper(createExp, LABKEY.Utils.getOnSuccess(config), config.scope), 380 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true), 381 scope: config.scope, 382 jsonData : { 383 assayId: config.assayId, 384 assayName: config.assayName, 385 providerName: config.providerName, 386 protocolName: config.protocolName, 387 runs: config.runs, 388 }, 389 scope: config.scope, 390 headers: { 391 'Content-Type' : 'application/json' 392 } 393 }); 394 }, 395 396 /** 397 * Saves an array of modified batches. 398 * Runs within the batches may refer to existing data and material objects, either inputs or outputs, by ID or LSID. 399 * Runs may also define new data and materials objects by not specifying an ID or LSID in their properties. 400 * @param config An object that contains the following configuration parameters 401 * @param {Number} config.assayId The assay protocol id. 402 * @param {LABKEY.Exp.RunGroup[]} config.batches The modified batch objects. 403 * @param {function} config.success The function to call when the function finishes successfully. 404 * This function will be called with the following parameters: 405 * <ul> 406 * <li><b>batches</b> An array of new {@link LABKEY.Exp.RunGroup} objects. Some values (such as IDs and LSIDs) will be filled in by the server. 407 * <li><b>response</b> The original response 408 * </ul> 409 * @param {function} [config.failure] The function to call if this function encounters an error. 410 * This function will be called with the following parameters: 411 * <ul> 412 * <li><b>response</b> The original response 413 * </ul> 414 * @see The <a href='https://www.labkey.org/Documentation/wiki-page.view?name=moduleassay'>Module Assay</a> documentation for more information. 415 * @static 416 */ 417 saveBatches : function (config) 418 { 419 _saveBatches(getSaveBatchesConfig(config), function(json){ 420 var batches = []; 421 if (json.batches) { 422 for (var i = 0; i < json.batches.length; i++) { 423 batches.push(new LABKEY.Exp.RunGroup(json.batches[i])); 424 } 425 } 426 return batches; 427 }); 428 }, 429 430 /** 431 * Saves materials. 432 * @deprecated Use LABKEY.Query.insertRows({schemaName: 'Samples', queryName: '<sample set name>', ...}); 433 * 434 * @param config An object that contains the following configuration parameters 435 * @param config.name name of the sample set 436 * @param config.materials An array of LABKEY.Exp.Material objects to be saved. 437 * @param {function} config.success The function to call when the function finishes successfully. 438 * This function will be called with the following parameters: 439 * <ul> 440 * <li><b>batch</b> A new {@link LABKEY.Exp.RunGroup} object. Some values will be filled in by the server. 441 * <li><b>response</b> The original response 442 * </ul> 443 * @param {function} [config.failure] The function to call if this function encounters an error. 444 * This function will be called with the following parameters: 445 * <ul> 446 * <li><b>response</b> The original response 447 * </ul> 448 * @param {object} [config.scope] A scoping object for the success and error callback functions (default to this). 449 * @static 450 */ 451 saveMaterials : function (config) 452 { 453 LABKEY.Query.insertRows({ 454 schemaName: 'Samples', 455 queryName: config.name, 456 rows: config.materials, 457 success: LABKEY.Utils.getOnSuccess(config), 458 failure: LABKEY.Utils.getOnFailure(config), 459 scope: config.scope 460 }); 461 }, 462 463 /** 464 * Get parent/child relationships of ExpData, ExpMaterial, or ExpRun. 465 * @param config 466 * @param config.lsids Array of LSIDs for the seed ExpData, ExpMaterials, or ExpRun. 467 * @param {Number} [config.depth] An optional depth argument. Defaults to include all. 468 * @param {Boolean} [config.parents] Include parents in the lineage response. Defaults to true. 469 * @param {Boolean} [config.children] Include children in the lineage response. Defaults to true. 470 * @param {String} [config.expType] Optional experiment type to filter response -- either "Data", "Material", or "ExperimentRun". Defaults to include all. 471 * @param {String} [config.cpasType] Optional LSID of a SampleSet or DataClass to filter the response. Defaults to include all. 472 * @static 473 */ 474 lineage : function (config) 475 { 476 var params = {}; 477 if (config.lsids) { 478 params.lsids = config.lsids; 479 } 480 else if (config.lsid) { 481 // Allow singluar 'lsid' for backwards compatibility with <19.3. 482 // Response will include a top-level 'seed' instead of 'seeds' property. 483 params.lsid = config.lsid; 484 } 485 486 if (config.hasOwnProperty('parents')) 487 params.parents = config.parents; 488 if (config.hasOwnProperty('children')) 489 params.children = config.children; 490 if (config.hasOwnProperty('depth')) 491 params.depth = config.depth; 492 493 if (config.expType) 494 params.expType = config.expType; 495 if (config.cpasType) 496 params.cpasType = config.cpasType; 497 498 LABKEY.Ajax.request({ 499 method: 'GET', 500 url: LABKEY.ActionURL.buildURL("experiment", "lineage.api"), 501 params: params, 502 success: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnSuccess(config), config.scope), 503 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true), 504 scope: config.scope 505 }); 506 } 507 }; 508 }; 509 510 if (typeof LABKEY.Exp == "undefined") 511 LABKEY.Exp = {}; 512 513 /** 514 * This constructor isn't called directly, but is used by derived classes. 515 * @class The experiment object base class describes basic 516 * characteristics of a protocol or an experimental run. Many experiment classes (such as {@link LABKEY.Exp.Run}, 517 * {@link LABKEY.Exp.Data} and {@link LABKEY.Exp.Material}) are subclasses 518 * of ExpObject, so they provide the fields defined by this object (e.g., name, lsid, etc). 519 * In a Java representation of these same classes, ExpObject is an abstract class. 520 * <p>Additional Documentation: 521 * <ul> 522 * <li><a href="https://www.labkey.org/Documentation/wiki-page.view?name=experiment">LabKey Experiment</a></li> 523 * </ul> 524 * </p> 525 * @memberOf LABKEY.Exp 526 * 527 * @param {Object} [config] Configuration object. 528 * 529 * @param {String} config.lsid The LSID of the ExpObject. 530 * @param {String} config.name The name of the ExpObject. 531 * @param {number} config.id The id of the ExpObject. 532 * @param {number} config.rowId The id of the ExpObject (alias of id property) 533 * @param {String} config.comment User editable comment. 534 * @param {Date} config.created When the ExpObject was created. 535 * @param {String} config.createdBy The person who created the ExpObject. 536 * @param {Date} config.modified When the ExpObject was last modified. 537 * @param {String} config.modifiedBy The person who last modified the ExpObject. 538 * @param {Object} config.properties Map of property descriptor names to values. Most types, such as strings and 539 * numbers, are just stored as simple properties. Properties of type FileLink will be returned by the server in the 540 * same format as {@link LABKEY.Exp.Data} objects (missing many properties such as id and createdBy if they exist on disk but 541 * have no row with metadata in the database). FileLink values are accepted from the client in the same way, or a simple value of the 542 * following three types: the data's RowId, the data's LSID, or the full path on the server's file system. 543 */ 544 LABKEY.Exp.ExpObject = function (config) { 545 config = config || {}; 546 this.lsid = config.lsid; 547 this.name = config.name; 548 this.id = config.id || config.rowId; 549 this.rowId = this.id; 550 this.comment = config.comment; 551 this.created = config.created; 552 this.createdBy = config.createdBy; 553 this.modified = config.modified; 554 this.modifiedBy = config.modifiedBy; 555 this.properties = config.properties || {}; 556 }; 557 558 /** 559 * Constructs a new experiment run object. 560 * @class The Exp.Run class describes an experiment run. An experiment run is an application of an experimental 561 * protocol to concrete inputs, producing concrete outputs. In object-oriented terminology, a protocol would be a class 562 * while a run would be an instance. 563 * <p>Additional Documentation: 564 * <ul> 565 * <li><a href="https://www.labkey.org/Documentation/wiki-page.view?name=experiment">LabKey Experiment</a></li> 566 * </ul> 567 * </p> 568 * @extends LABKEY.Exp.ExpObject 569 * @memberOf LABKEY.Exp 570 * 571 * @param {Object} [config] The configuration object. Inherits the config properties of {@link LABKEY.Exp.ExpObject}. 572 * @param {Object[]} config.dataInputs Array of {@link LABKEY.Exp.Data} objects that are the inputs to this run. Datas typically represent a file on the server's file system. 573 * @param {Object[]} config.dataOutputs Array of {@link LABKEY.Exp.Data} objects that are the outputs from this run. Datas typically represent a file on the server's file system. 574 * @param {Object[]} config.dataRows Array of Objects where each Object corresponds to a row in the results domain. 575 * @param {Object[]} config.materialInputs Array of {@link LABKEY.Exp.Material} objects that are material/sample inputs to the run. 576 * @param {Object[]} config.materialOutputs Array of {@link LABKEY.Exp.Material} objects that are material/sample outputs from the run. 577 * 578 * @see LABKEY.Exp.Data#getContent 579 * 580 * @example 581 * var result = // ... result of uploading a new assay results file 582 * var data = new LABKEY.Exp.Data(result); 583 * 584 * var run = new LABKEY.Exp.Run(); 585 * run.name = data.name; 586 * run.properties = { "MyRunProperty" : 3 }; 587 * run.dataInputs = [ data ]; 588 * 589 * data.getContent({ 590 * format: 'jsonTSV', 591 * success: function (content, format) { 592 * data.content = content; 593 * var sheet = content.sheets[0]; 594 * var filedata = sheet.data; 595 * 596 * // transform the file content into the dataRows array used by the run 597 * run.dataRows = []; 598 * for (var i = 1; i < filedata.length; i++) { 599 * var row = filedata[i]; 600 * run.dataRows.push({ 601 * "SampleId": row[0], 602 * "DataValue": row[1], 603 * // ... other columns 604 * }); 605 * } 606 * 607 * var batch = // ... the LABKEY.Exp.RunGroup object 608 * batch.runs.push(run); 609 * }, 610 * failure: function (error, format) { 611 * alert("error: " + error); 612 * } 613 * }); 614 */ 615 LABKEY.Exp.Run = function (config) { 616 LABKEY.Exp.ExpObject.call(this, config); 617 config = config || {}; 618 619 this.experiments = config.experiments || []; 620 this.protocol = config.protocol; 621 this.filePathRoot = config.filePathRoot; 622 623 this.dataInputs = []; 624 if (config.dataInputs) { 625 for (var i = 0; i < config.dataInputs.length; i++) { 626 this.dataInputs.push(new LABKEY.Exp.Data(config.dataInputs[i])); 627 } 628 } 629 630 this.dataOutputs = config.dataOutputs || []; 631 this.dataRows = config.dataRows || []; 632 this.materialInputs = config.materialInputs || []; 633 this.materialOutputs = config.materialOutputs || []; 634 this.objectProperties = config.objectProperties || {}; 635 }; 636 LABKEY.Exp.Run.prototype = new LABKEY.Exp.ExpObject; 637 LABKEY.Exp.Run.prototype.constructor = LABKEY.Exp.Run; 638 639 /** 640 * Deletes the run from the database. 641 * @param config An object that contains the following configuration parameters 642 * @param {Function} config.success A reference to a function to call with the API results. This 643 * function will be passed the following parameters: 644 * <ul> 645 * <li><b>data:</b> a simple object with one property called 'success' which will be set to true.</li> 646 * <li><b>response:</b> The XMLHttpResponse object</li> 647 * </ul> 648 * @param {Function} [config.failure] A reference to a function to call when an error occurs. This 649 * function will be passed the following parameters: 650 * <ul> 651 * <li><b>errorInfo:</b> an object containing detailed error information (may be null)</li> 652 * <li><b>response:</b> The XMLHttpResponse object</li> 653 * </ul> 654 */ 655 LABKEY.Exp.Run.prototype.deleteRun = function(config) 656 { 657 LABKEY.Ajax.request( 658 { 659 url : LABKEY.ActionURL.buildURL("experiment", "deleteRun"), 660 method : 'POST', 661 params : { runId : this.id }, 662 success: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnSuccess(config), this, false), 663 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), this, true) 664 }); 665 }; 666 667 668 669 /** 670 * The Protocol constructor is private. 671 * @class Experiment protocol. 672 * @extends LABKEY.Exp.ExpObject 673 * @memberOf LABKEY.Exp 674 * 675 * @param {Object} [config] private constructor argument. Inherits config properties of {@link LABKEY.Exp.ExpObject}. 676 * 677 * @ignore hide from JsDoc for now 678 */ 679 LABKEY.Exp.Protocol = function (config) { 680 LABKEY.Exp.ExpObject.call(this, config); 681 config = config || {}; 682 683 this.instrument = config.instrument; 684 this.software = config.software; 685 this.contact = config.contact; 686 this.childProtocols = config.childProtocols || []; 687 this.steps = config.steps || []; 688 this.applicationType = config.applicationType; 689 this.description = config.description; 690 this.runs = []; 691 if (config.runs) { 692 for (var i = 0; i < config.runs.length; i++) { 693 this.runs.push(new LABKEY.Exp.Run(config.runs[i])); 694 } 695 } 696 }; 697 LABKEY.Exp.Protocol.prototype = new LABKEY.Exp.ExpObject; 698 LABKEY.Exp.Protocol.prototype.constructor = LABKEY.Exp.Protocol; 699 700 /** 701 * The RunGroup constructor is private. To retrieve a batch RunGroup 702 * from the server, see {@link LABKEY.Experiment.loadBatch}. 703 * @class An experiment run group contains an array of 704 * {@link LABKEY.Exp.Run}s. If all runs have the same assay protocol, the run group 705 * is considered a batch. To add runs to a batch, insert new {@link LABKEY.Exp.Run} 706 * instances into to the 'runs' Array and save the batch. 707 * <p> 708 * Use {@link LABKEY.Experiment.loadBatch} and {@link LABKEY.Experiment.saveBatch} to 709 * load and save a RunGroup. 710 * </p> 711 * <p>Additional Documentation: 712 * <ul> 713 * <li><a href='https://www.labkey.org/Documentation/wiki-page.view?name=moduleassay'>LabKey File-Based Assays</a></li> 714 * <li><a href="https://www.labkey.org/Documentation/wiki-page.view?name=experiment">LabKey Experiment</a></li> 715 * </ul> 716 * </p> 717 * @extends LABKEY.Exp.ExpObject 718 * @memberOf LABKEY.Exp 719 * 720 * @param {Object} [config] Private configuration object. Inherits config properties of {@link LABKEY.Exp.ExpObject}. 721 * @param {LABKEY.Exp.Run[]} config.runs Array of {@link LABKEY.Exp.Run}s in this run group. 722 * @param {Boolean} config.hidden Determines whether the RunGroup is hidden. 723 */ 724 LABKEY.Exp.RunGroup = function (config) { 725 LABKEY.Exp.ExpObject.call(this, config); 726 config = config || {}; 727 728 this.batchProtocolId = config.batchProtocolId || 0; 729 this.runs = []; 730 if (config.runs) { 731 for (var i = 0; i < config.runs.length; i++) { 732 this.runs.push(new LABKEY.Exp.Run(config.runs[i])); 733 } 734 } 735 //this.protocols = config.protocols || []; 736 //this.batchProtocol = config.batchProtocol; 737 this.hidden = config.hidden; 738 }; 739 LABKEY.Exp.RunGroup.prototype = new LABKEY.Exp.ExpObject; 740 LABKEY.Exp.RunGroup.prototype.constructor = LABKEY.Exp.RunGroup; 741 742 /** 743 * The ProtocolApplication constructor is private. 744 * @class Experiment ProtocolApplication. 745 * @extends LABKEY.Exp.ExpObject 746 * @memberOf LABKEY.Exp 747 * 748 * @param {Object} [config] Private configuration object. Inherits config properties of {@link LABKEY.Exp.ExpObject}. 749 * 750 * @ignore hide from JsDoc for now 751 */ 752 LABKEY.Exp.ProtocolApplication = function (config) { 753 LABKEY.Exp.ExpObject.call(this, config); 754 config = config || {}; 755 756 }; 757 LABKEY.Exp.ProtocolApplication.prototype = new LABKEY.Exp.ExpObject; 758 LABKEY.Exp.ProtocolApplication.prototype.constructor = LABKEY.Exp.ProtocolApplication; 759 760 /** 761 * @class The SampleSet class describes a collection of experimental samples, which are 762 * also known as materials (see {@link LABKEY.Exp.Material}). This class defines the set of fields that 763 * you you wish to attach to all samples in the group. These fields supply characteristics of the sample 764 * (e.g., its volume, number of cells, color, etc.). 765 * <p>Additional Documentation: 766 * <ul> 767 * <li><a href="https://www.labkey.org/Documentation/wiki-page.view?name=experiment">LabKey Experiment</a></li> 768 * </ul> 769 * </p> 770 * @extends LABKEY.Exp.ExpObject 771 * @memberOf LABKEY.Exp 772 * 773 * @param {Object} [config] Describes the SampleSet's properties. Inherits the config properties of {@link LABKEY.Exp.ExpObject}. 774 * @param {Object[]} config.samples Array of {@link LABKEY.Exp.Material} config objects. 775 * @param {String} config.description Description of the SampleSet 776 */ 777 778 LABKEY.Exp.SampleSet = function (config) { 779 LABKEY.Exp.ExpObject.call(this, config); 780 config = config || {}; 781 this.samples = config.samples; 782 this.description = config.description; 783 }; 784 LABKEY.Exp.SampleSet.prototype = new LABKEY.Exp.ExpObject; 785 LABKEY.Exp.SampleSet.prototype.constructor = LABKEY.Exp.SampleSet; 786 787 /** 788 * Get a domain design for the SampleSet. 789 * 790 * @param {Function} config.success Required. Function called if the 791 * "getDomain" function executes successfully. Will be called with the argument {@link LABKEY.Domain.DomainDesign}, 792 * which describes the fields of a domain. 793 * @param {Function} [config.failure] Function called if execution of the "getDomain" function fails. 794 * @param {String} [config.containerPath] The container path in which the requested Domain is defined. 795 * If not supplied, the current container path will be used. 796 * 797 * @ignore hide from JsDoc for now 798 * 799 * @example 800 * <script type="text/javascript"> 801 * Ext.onReady(function() { 802 * var ss = new LABKEY.Exp.SampleSet({name: 'MySampleSet'}); 803 * ss.getDomain({ 804 * success : function (domain) { 805 * console.log(domain); 806 * } 807 * }); 808 * } 809 * </script> 810 */ 811 LABKEY.Exp.SampleSet.prototype.getDomain = function (config) 812 { 813 LABKEY.Domain.get(LABKEY.Utils.getOnSuccess(config), LABKEY.Utils.getOnFailure(config), "Samples", this.name, config.containerPath); 814 }; 815 816 /** 817 * Create a new Sample Set definition. 818 * @param {Function} config.success Required callback function. 819 * @param {Function} [config.failure] Failure callback function. 820 * @param {LABKEY.Domain.DomainDesign} config.domainDesign The domain design to save. 821 * @param {Object} [config.options] Set of extra options used when creating the SampleSet: 822 * <ul> 823 * <li>idCols: Optional. Array of indexes into the domain design fields. If the domain design contains a 'Name' field, no idCols are allowed. Either a 'Name' field must be present or at least one idCol must be supplied.. 824 * <li>parentCol: Optional. Index of the parent id column. 825 * </ul> 826 * @param {String} [config.containerPath] The container path in which to create the domain. 827 * @static 828 * 829 * @ignore hide from JsDoc for now 830 * 831 * @example 832 * var domainDesign = { 833 * name: "BoyHowdy", 834 * description: "A client api created sample set", 835 * fields: [{ 836 * name: 'TestName', 837 * label: 'The First Field', 838 * rangeURI: 'http://www.w3.org/2001/XMLSchema#string' 839 * },{ 840 * name: 'Num', 841 * rangeURI: 'http://www.w3.org/2001/XMLSchema#int' 842 * },{ 843 * name: 'Parent', 844 * rangeURI: 'http://www.w3.org/2001/XMLSchema#string' 845 * }] 846 * }; 847 * 848 * LABKEY.Exp.SampleSet.create({ 849 * success: function () { alert("success!"); }, 850 * failure: function () { alert("failure!"); }, 851 * domainDesign: domainDesign, 852 * options: { idCols: [0, 1], parentCol: 2 } 853 * }); 854 */ 855 LABKEY.Exp.SampleSet.create = function (config) 856 { 857 LABKEY.Domain.create(LABKEY.Utils.getOnSuccess(config), LABKEY.Utils.getOnFailure(config), "SampleSet", config.domainDesign, config.options, config.containerPath); 858 }; 859 860 /** 861 * DataClass represents a set of ExpData objects that share a set of properties. 862 * 863 * @class DataClass describes a collection of Data objects. 864 * This class defines the set of fields that you you wish to attach to all datas in the group. 865 * Within the DataClass, each Data has a unique name. 866 * 867 * @extends LABKEY.Exp.ExpObject 868 * @memberOf LABKEY.Exp 869 * 870 * @param config 871 * @param {String} config.description Description of the DataClass. 872 * @param {String} [config.nameExpression] Optional name expression used to generate unique names for ExpData inserted into the DataClass. 873 * @param {Object} [config.sampleSet] The optional SampleSet the DataClass is associated with. With the following properties: 874 * @param {Integer} [config.sampleSet.id] The row id of the SampleSet. 875 * @param {String} [config.sampleSet.name] The name of the SampleSet. 876 * @constructor 877 */ 878 LABKEY.Exp.DataClass = function (config) 879 { 880 "use strict"; 881 882 LABKEY.Exp.ExpObject.call(this, config); 883 config = config || {}; 884 this.description = config.description; 885 this.sampleSet = config.sampleSet; 886 }; 887 LABKEY.Exp.DataClass.prototype = new LABKEY.Exp.ExpObject; 888 LABKEY.Exp.DataClass.prototype.constructor = LABKEY.Exp.DataClass; 889 890 LABKEY.Exp.DataClass.prototype.getDomain = function (config) 891 { 892 "use strict"; 893 LABKEY.Domain.get({ 894 success: LABKEY.Utils.getOnSuccess(config), 895 failure: LABKEY.Utils.getOnFailure(config), 896 schemaName: "exp.data", 897 queryName: this.name, 898 containerPath: config.containerPath 899 }); 900 }; 901 902 LABKEY.Exp.DataClass.create = function (config) 903 { 904 "use strict"; 905 LABKEY.Domain.create({ 906 success: LABKEY.Utils.getOnSuccess(config), 907 failure: LABKEY.Utils.getOnFailure(config), 908 type: "dataclass", 909 domainDesign: config.domainDesign, 910 options: config.options, 911 containerPath: config.containerPath 912 }); 913 }; 914 915 /** 916 * The ChildObject constructor is private. 917 * @class Experiment Child 918 * @extends LABKEY.Exp.ExpObject 919 * @memberOf LABKEY.Exp 920 * 921 * @param {Object} [config] Private configuration object. Inherits the config properties of {@link LABKEY.Exp.ExpObject}. 922 * 923 * @ignore hide from JsDoc for now 924 */ 925 LABKEY.Exp.ChildObject = function (config) { 926 LABKEY.Exp.ExpObject.call(this, config); 927 config = config || {}; 928 // property holder 929 }; 930 LABKEY.Exp.ChildObject.prototype = new LABKEY.Exp.ExpObject; 931 LABKEY.Exp.ChildObject.prototype.constructor = LABKEY.Exp.ChildObject; 932 933 /** 934 * The RunItem constructor is private. 935 * @class Experiment Run Item. Base class for {@link LABKEY.Exp.Data} 936 * and {@link LABKEY.Exp.Material}. 937 * @extends LABKEY.Exp.ExpObject 938 * @memberOf LABKEY.Exp 939 * @param {Object} [config] Private configuration object. Inherits config properties of {@link LABKEY.Exp.ExpObject}. 940 * @ignore hide from JsDoc for now 941 */ 942 LABKEY.Exp.RunItem = function (config) { 943 LABKEY.Exp.ExpObject.call(this, config); 944 config = config || {}; 945 946 this.sourceProtocol = config.sourceProtocol; 947 this.run = config.run; 948 this.targetApplications = config.targetApplications; 949 this.sourceApplications = config.sourceApplications; 950 this.sucessorRuns = config.sucessorRuns; 951 this.cpasType = config.cpasType; 952 }; 953 LABKEY.Exp.RunItem.prototype = new LABKEY.Exp.ExpObject; 954 LABKEY.Exp.RunItem.prototype.constructor = LABKEY.Exp.RunItem; 955 956 /** 957 * Constructs a new experiment material object. 958 * @class The Exp.Material class describes an experiment material. "Material" is a synonym for both 959 * "sample" and "specimen." Thus, for example, the input to an assay could be called a material. 960 * The fields of this class are inherited from the {@link LABKEY.Exp.ExpObject} object and 961 * the private LABKEY.Exp.RunItem object. 962 * <p>Additional Documentation: 963 * <ul> 964 * <li><a href="https://www.labkey.org/Documentation/wiki-page.view?name=experiment">LabKey Experiment</a></li> 965 * </ul> 966 * </p> 967 * @extends LABKEY.Exp.RunItem 968 * @extends LABKEY.Exp.ExpObject 969 * @memberOf LABKEY.Exp 970 * 971 * @param {Object} [config] Configuration object. Inherits the config properties of {@link LABKEY.Exp.ExpObject}. 972 * @param {Object} [config.sampleSet] The SampleSet the material belongs to. With the following properties: 973 * @param {Integer} [config.sampleSet.id] The row id of the SampleSet. 974 * @param {String} [config.sampleSet.name] The name of the SampleSet. 975 */ 976 LABKEY.Exp.Material = function (config) { 977 LABKEY.Exp.RunItem.call(this, config); 978 config = config || {}; 979 980 this.sampleSet = config.sampleSet; 981 }; 982 LABKEY.Exp.Material.prototype = new LABKEY.Exp.RunItem; 983 LABKEY.Exp.Material.prototype.constructor = LABKEY.Exp.Material; 984 985 /** 986 * The Data constructor is private. 987 * To create a LABKEY.Exp.Data object, upload a file using to the "assayFileUpload" action of 988 * the "assay" controller. 989 * 990 * @class The Experiment Data class describes the data input or output of a {@link LABKEY.Exp.Run}. This typically 991 * corresponds to an assay results file uploaded to the LabKey server. 992 * <p> 993 * To create a LABKEY.Exp.Data object, upload a file using to the "assayFileUpload" action of 994 * the "assay" controller. 995 * </p> 996 * <p>Additional Documentation: 997 * <ul> 998 * <li><a href='https://www.labkey.org/Documentation/wiki-page.view?name=moduleassay'>LabKey File-Based Assays</a></li> 999 * <li><a href="https://www.labkey.org/Documentation/wiki-page.view?name=experiment">LabKey Experiment</a></li> 1000 * </ul> 1001 * </p> 1002 * 1003 * @extends LABKEY.Exp.RunItem 1004 * @extends LABKEY.Exp.ExpObject 1005 * @memberOf LABKEY.Exp 1006 * 1007 * @param {Object} [config] Private configuration object. Inherits the config properties of {@link LABKEY.Exp.ExpObject}. 1008 * @param {String} config.dataFileURL The local file url of the uploaded file. 1009 * @param {Object} [config.dataClass] The DataClass the data belongs to. With the following properties: 1010 * @param {Integer} [config.dataClass.id] The row id of the DataClass. 1011 * @param {String} [config.dataClass.name] The name of the DataClass. 1012 * 1013 * @example 1014 * // To perform a file upload over HTTP: 1015 * <form id="upload-run-form" enctype="multipart/form-data" method="POST"> 1016 * <div id="upload-run-button"></div> 1017 * </form> 1018 * <script type="text/javascript"> 1019 * LABKEY.Utils.requiresScript("FileUploadField.js"); 1020 * // Optional - specify a protocolId so that the Exp.Data object is assigned the related LSID namespace. 1021 * var url = LABKEY.ActionURL.buildURL("assay", "assayFileUpload", LABKEY.ActionURL.getContainer(), { protocolId: 50 }); 1022 * Ext.onReady(function() { 1023 * var form = new Ext.form.BasicForm( 1024 * Ext.get("upload-run-form"), { 1025 * fileUpload: true, 1026 * frame: false, 1027 * url: url, 1028 * listeners: { 1029 * actioncomplete : function (form, action) { 1030 * alert('Upload successful!'); 1031 * var data = new LABKEY.Exp.Data(action.result); 1032 * 1033 * // now add the data as a dataInput to a LABKEY.Exp.Run 1034 * var run = new LABKEY.Exp.Run(); 1035 * run.name = data.name; 1036 * run.dataInputs = [ data ]; 1037 * 1038 * // add the new run to a LABKEY.Exp.Batch object and 1039 * // fetch the parsed file contents from the data object 1040 * // using the LABKEY.Exp.Data#getContent() method. 1041 * }, 1042 * actionfailed: function (form, action) { 1043 * alert('Upload failed!'); 1044 * } 1045 * } 1046 * }); 1047 * 1048 * var uploadField = new Ext.form.FileUploadField({ 1049 * id: "upload-run-field", 1050 * renderTo: "upload-run-button", 1051 * buttonText: "Upload Data...", 1052 * buttonOnly: true, 1053 * buttonCfg: { cls: "labkey-button" }, 1054 * listeners: { 1055 * "fileselected": function (fb, v) { 1056 * form.submit(); 1057 * } 1058 * } 1059 * }); 1060 * }); 1061 * </script> 1062 * 1063 * // Or, to upload the contents of a JavaScript string as a file: 1064 * <script type="text/javascript"> 1065 * Ext.onReady(function() { 1066 * LABKEY.Ajax.request({ 1067 * url: LABKEY.ActionURL.buildURL("assay", "assayFileUpload"), 1068 * params: { fileName: 'test.txt', fileContent: 'Some text!' }, 1069 * success: function(response, options) { 1070 * var data = new LABKEY.Exp.Data(Ext.util.JSON.decode(response.responseText)); 1071 * 1072 * // now add the data as a dataInput to a LABKEY.Exp.Run 1073 * var run = new LABKEY.Exp.Run(); 1074 * run.name = data.name; 1075 * run.dataInputs = [ data ]; 1076 * 1077 * // add the new run to a LABKEY.Exp.Batch object here 1078 * } 1079 * }); 1080 * }); 1081 * 1082 * </script> 1083 */ 1084 LABKEY.Exp.Data = function (config) { 1085 LABKEY.Exp.RunItem.call(this, config); 1086 config = config || {}; 1087 1088 this.dataType = config.dataType; 1089 this.dataFileURL = config.dataFileURL; 1090 this.dataClass = config.dataClass; 1091 if (config.pipelinePath) 1092 this.pipelinePath = config.pipelinePath; 1093 if (config.role) 1094 this.role = config.role; 1095 }; 1096 LABKEY.Exp.Data.prototype = new LABKEY.Exp.RunItem; 1097 LABKEY.Exp.Data.prototype.constructor = LABKEY.Exp.Data; 1098 1099 /** 1100 * Retrieves the contents of the data object from the server. 1101 * @param config An object that contains the following configuration parameters 1102 * @param {object} [config.scope] A scoping object for the success and error callback functions (default to this). 1103 * @param {function} config.success The function to call when the function finishes successfully. 1104 * This function will be called with the parameters: 1105 * <ul> 1106 * <li><b>content</b> The type of the content varies based on the format requested. 1107 * <li><b>format</b> The format used in the request 1108 * <li><b>response</b> The original response 1109 * </ul> 1110 * @param {function} [config.failure] The function to call if this function encounters an error. 1111 * This function will be called with the following parameters: 1112 * <ul> 1113 * <li><b>errorInfo:</b> An object with a property called "exception," which contains the error message.</li> 1114 * <li><b>format</b> The format used in the request 1115 * <li><b>response</b> The original response 1116 * </ul> 1117 * @param {String} [config.format] How to format the content. Defaults to plaintext, supported for text/* MIME types, 1118 * including .html, .xml, .tsv, .txt, and .csv. Use 'jsonTSV' to get a JSON version of the .xls, .tsv, .or .csv 1119 * files, the structure of which matches the argument to convertToExcel in {@link LABKEY.Utils}. 1120 * <ul> 1121 * <li><b>fileName:</b> the name of the file</li> 1122 * <li><b>sheets:</b> an array of the sheets in the file. Text file types will have a single sheet named 'flat'. 1123 * <ul><li><b>name:</b> the name of the sheet</li> 1124 * <li><b>values:</b> two-dimensional array of all the cells in the worksheet. First array index is row, second is column</li> 1125 * </ul> 1126 * </ul> 1127 * <br/>Use 'jsonTSVExtended' to get include metadata in the 2D array of cells. 1128 * Text file types will not supply additional metadata but populate the 'value' attribute in the map. 1129 * Excel files will include: 1130 * <ul> 1131 * <li><b>value:</b> the string, boolean, date, or number in the cell</li> 1132 * <li><b>timeOnly:</b> whether the date part should be ignored for dates</li> 1133 * <li><b>formatString:</b> the Java format string to be used to render the value for dates and numbers</li> 1134 * <li><b>formattedValue:</b> the formatted string for that value for all value types</li> 1135 * <li><b>error:</b> true if this cell has an error</li> 1136 * <li><b>formula:</b> if the cell's value is specified by a formula, the text of the formula</li> 1137 * </ul> 1138 * <br/>Use 'jsonTSVIgnoreTypes' to always return string values for all cells, regardless of type. 1139 * <br/> 1140 * An example of the results for a request for 'jsonTsv' format: 1141 * <pre> 1142 * { 1143 "sheets": [ 1144 { 1145 "name": "Sheet1", 1146 "data": [ 1147 [ 1148 "StringColumn", 1149 "DateColumn" 1150 ], 1151 [ 1152 "Hello", 1153 "16 May 2009 17:00:00" 1154 ], 1155 [ 1156 "world", 1157 "12/21/2008 08:45AM" 1158 ] 1159 ] 1160 }, 1161 { 1162 "name": "Sheet2", 1163 "data": [ 1164 ["NumberColumn"], 1165 [55.44], 1166 [100.34], 1167 [-1] 1168 ] 1169 }, 1170 { 1171 "name": "Sheet3", 1172 "data": [] 1173 } 1174 ], 1175 "fileName": "SimpleExcelFile.xls" 1176 }</pre> 1177 <br/> 1178 An example of the same file in the 'jsonTSVExtended' format: 1179 <pre> 1180 * { 1181 "sheets": [ 1182 { 1183 "name": "Sheet1", 1184 "data": [ 1185 [ 1186 { 1187 "value": "StringColumn", 1188 "formattedValue": "StringColumn" 1189 }, 1190 { 1191 "value": "DateColumn", 1192 "formattedValue": "DateColumn" 1193 } 1194 ], 1195 [ 1196 { 1197 "value": "Hello", 1198 "formattedValue": "Hello" 1199 }, 1200 { 1201 "formatString": "MMMM d, yyyy", 1202 "value": "16 May 2009 17:00:00", 1203 "timeOnly": false, 1204 "formattedValue": "May 17, 2009" 1205 } 1206 ], 1207 [ 1208 { 1209 "value": "world", 1210 "formattedValue": "world" 1211 }, 1212 { 1213 "formatString": "M/d/yy h:mm a", 1214 "value": "21 Dec 2008 19:31:00", 1215 "timeOnly": false, 1216 "formattedValue": "12/21/08 7:31 PM" 1217 } 1218 ] 1219 ] 1220 }, 1221 { 1222 "name": "Sheet2", 1223 "data": [ 1224 [{ 1225 "value": "NumberColumn", 1226 "formattedValue": "NumberColumn" 1227 }], 1228 [{ 1229 "formatString": "$#,##0.00", 1230 "value": 55.44, 1231 "formattedValue": "$55.44" 1232 }], 1233 [{ 1234 "value": 100.34, 1235 "formattedValue": "100.34" 1236 }], 1237 [{ 1238 "value": -1, 1239 "formattedValue": "-1" 1240 }] 1241 ] 1242 }, 1243 { 1244 "name": "Sheet3", 1245 "data": [] 1246 } 1247 ], 1248 "fileName": "SimpleExcelFile.xls" 1249 } 1250 </pre> 1251 * 1252 */ 1253 LABKEY.Exp.Data.prototype.getContent = function(config) 1254 { 1255 if(!LABKEY.Utils.getOnSuccess(config)) 1256 { 1257 alert("You must specify a callback function in config.success when calling LABKEY.Exp.Data.getContent()!"); 1258 return; 1259 } 1260 1261 function getSuccessCallbackWrapper(fn, format, scope) 1262 { 1263 return function(response) 1264 { 1265 //ensure response is JSON before trying to decode 1266 var content = null; 1267 if(response && response.getResponseHeader && response.getResponseHeader('Content-Type') 1268 && response.getResponseHeader('Content-Type').indexOf('application/json') >= 0) 1269 { 1270 content = LABKEY.Utils.decode(response.responseText); 1271 } 1272 else 1273 { 1274 content = response.responseText; 1275 } 1276 1277 if(fn) 1278 fn.call(scope || this, content, format, response); 1279 }; 1280 } 1281 1282 LABKEY.Ajax.request( 1283 { 1284 url : LABKEY.ActionURL.buildURL("experiment", "showFile"), 1285 method : 'GET', 1286 params : { rowId : this.id, format: config.format }, 1287 success: getSuccessCallbackWrapper(LABKEY.Utils.getOnSuccess(config), config.format, config.scope), 1288 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true) 1289 }); 1290 1291 }; 1292 1293 1294