1 /* 2 * Copyright (c) 2012-2018 LabKey Corporation 3 * 4 * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 5 */ 6 Ext.namespace('LABKEY.ext'); 7 8 // TODO: Get these off the global 'Date' object 9 Ext.ns("Date.patterns"); 10 Ext.applyIf(Date.patterns,{ 11 ISO8601Long:"Y-m-d H:i:s", 12 ISO8601Short:"Y-m-d" 13 }); 14 15 LABKEY.ext.Utils = new function() { 16 var createHttpProxyImpl = function(containerPath, errorListener) { 17 var proxy = new Ext.data.HttpProxy(new Ext.data.Connection({ 18 //where to retrieve data 19 url: LABKEY.ActionURL.buildURL("query", "selectRows", containerPath), //url to data object (server side script) 20 method: 'GET' 21 })); 22 23 if (errorListener) 24 proxy.on("loadexception", errorListener); 25 26 proxy.on("beforeload", mapQueryParameters); 27 28 return proxy; 29 }; 30 31 var mapQueryParameters = function(store, options) { 32 // map all parameters from ext names to labkey names: 33 for (var p in options) 34 { 35 if (options.hasOwnProperty(p)) { 36 if (_extParamMapping[p]) 37 options[_extParamMapping[p]] = options[p]; 38 } 39 } 40 41 // fix up any necessary parameter values: 42 if ("DESC" == options['query.sortdir']) 43 { 44 var sortCol = options['query.sort']; 45 options['query.sort'] = "-" + sortCol; 46 } 47 }; 48 49 /** 50 * This method takes an object that is/extends an Ext3.Container (e.g. Panels, Toolbars, Viewports, Menus) and 51 * resizes it so the Container fits inside the its parent container. 52 * @param extContainer - (Required) outer container which is the target to be resized 53 * @param options - The set of options 54 * @param options.skipWidth - true to skip updating width, default false 55 * @param options.skipHeight - true to skip updating height, default false 56 * @param options.paddingWidth - total width padding 57 * @param options.paddingHeight - total height padding 58 * @param options.offsetY - distance between bottom of page to bottom of component 59 */ 60 var resizeToContainer = function(extContainer, options) { 61 var config = { 62 offsetY: 35, 63 paddingHeight: 0, 64 paddingWidth: 0, 65 skipHeight: false, 66 skipWidth: false 67 }; 68 69 if (Ext.isObject(options)) { 70 config = Ext.apply(config, options); 71 } 72 // else ignore the parameters 73 74 if (!extContainer || !extContainer.rendered || (config.skipWidth && config.skipHeight)) { 75 return; 76 } 77 78 var height = 0; 79 var width = 0; 80 81 if (!config.skipWidth) { 82 width = extContainer.el.parent().getBox().width; 83 } 84 85 86 if (!config.skipHeight) { 87 height = window.innerHeight - extContainer.el.getXY()[1]; 88 } 89 90 var padding = [ 91 config.paddingWidth, 92 config.paddingHeight 93 ]; 94 95 var size = { 96 width: Math.max(100, width - padding[0]), 97 height: Math.max(100, height - padding[1] - config.offsetY) 98 }; 99 100 if (config.skipWidth) { 101 extContainer.setHeight(size.height); 102 } 103 else if (config.skipHeight) { 104 extContainer.setWidth(size.width); 105 } 106 else { 107 extContainer.setSize(size); 108 } 109 110 extContainer.doLayout(); 111 }; 112 113 return { 114 /** 115 * Creates an Ext.data.Store that queries the LabKey Server database and can be used as the data source 116 * for various components, including GridViews, ComboBoxes, and so forth. 117 * @deprecated 118 * @param {Object} config Describes the GridView's properties. 119 * @param {String} config.schemaName Name of a schema defined within the current 120 * container. Example: 'study'. See also: <a class="link" 121 href="https://www.labkey.org/Documentation/wiki-page.view?name=findNames"> 122 How To Find schemaName, queryName & viewName</a>. 123 * @param {String} config.queryName Name of a query defined within the specified schema 124 * in the current container. Example: 'SpecimenDetail'. See also: <a class="link" 125 href="https://www.labkey.org/Documentation/wiki-page.view?name=findNames"> 126 How To Find schemaName, queryName & viewName</a>. 127 * @param {String} [config.containerPath] The container path in which the schemaName and queryName are defined. 128 * @param {String} [config.viewName] Name of a custom view defined over the specified query. 129 * in the current container. Example: 'SpecimenDetail'. See also: <a class="link" 130 href="https://www.labkey.org/Documentation/wiki-page.view?name=findNames"> 131 How To Find schemaName, queryName & viewName</a>. 132 * @param {Object} [config.allowNull] If specified, this configuration will be used to insert a blank 133 * entry as the first entry in the store. 134 * @param {String} [config.allowNull.keyColumn] If specified, the name of the column in the underlying database 135 * that holds the key. 136 * @param {String} [config.allowNull.displayColumn] If specified, the name of the column in the underlying database 137 * that holds the value to be shown by default in the display component. 138 * @param {String} [config.allowNull.emptyName] If specified, what to show in the list for the blank entry. 139 * Defaults to '[None]'. 140 * @param {String} [config.allowNull.emptyValue] If specified, the value to be used for the blank entry. 141 * Defaults to the empty string. 142 * 143 * @return {Ext.data.Store} The initialized Store object 144 */ 145 createExtStore: function(storeConfig) { 146 if (!storeConfig) 147 storeConfig = {}; 148 if (!storeConfig.baseParams) 149 storeConfig.baseParams = {}; 150 storeConfig.baseParams['query.queryName'] = storeConfig.queryName; 151 storeConfig.baseParams['schemaName'] = storeConfig.schemaName; 152 if (storeConfig.viewName) 153 storeConfig.baseParams['query.viewName'] = storeConfig.viewName; 154 155 if (!storeConfig.proxy) 156 storeConfig.proxy = createHttpProxyImpl(storeConfig.containerPath); 157 158 if (!storeConfig.remoteSort) 159 storeConfig.remoteSort = true; 160 161 if (!storeConfig.listeners || !storeConfig.listeners.loadexception) 162 storeConfig.listeners = { loadexception : { fn : handleLoadError } }; 163 164 storeConfig.reader = new Ext.data.JsonReader(); 165 166 var result = new Ext.data.Store(storeConfig); 167 168 if (storeConfig.allowNull) 169 { 170 var emptyValue = storeConfig.allowNull.emptyValue; 171 if (!emptyValue) 172 { 173 emptyValue = ""; 174 } 175 var emptyName = storeConfig.allowNull.emptyName; 176 if (!emptyName) 177 { 178 emptyName = "[None]"; 179 } 180 result.on("load", function(store) 181 { 182 var emptyRecordConstructor = Ext.data.Record.create([storeConfig.allowNull.keyColumn, storeConfig.allowNull.displayColumn]); 183 var recordData = {}; 184 recordData[storeConfig.allowNull.keyColumn] = emptyValue; 185 recordData[storeConfig.allowNull.displayColumn] = emptyName; 186 var emptyRecord = new emptyRecordConstructor(recordData); 187 store.insert(0, emptyRecord); 188 }); 189 } 190 191 return result; 192 }, 193 194 /** 195 * Ensure BoxComponent is visible on the page. 196 * @param boxComponent 197 * @deprecated 198 */ 199 ensureBoxVisible: function(boxComponent) { 200 var box = boxComponent.getBox(true); 201 var viewportWidth = Ext.lib.Dom.getViewWidth(); 202 var scrollLeft = Ext.dd.DragDropMgr.getScrollLeft(); 203 204 var scrollBarWidth = 20; 205 if (viewportWidth - scrollBarWidth + scrollLeft < box.width + box.x) { 206 boxComponent.setPosition(viewportWidth + scrollLeft - box.width - scrollBarWidth); 207 } 208 }, 209 210 /** 211 * Use LABKEY.Utils.handleTabsInTextArea instead 212 * @deprecated 213 */ 214 handleTabsInTextArea: function(event){ 215 LABKEY.Utils.handleTabsInTextArea(event); 216 }, 217 218 /** 219 * This method takes an object that is/extends an Ext.Container (e.g. Panels, Toolbars, Viewports, Menus) and 220 * resizes it so the Container fits inside the viewable region of the window. This is generally used in the case 221 * where the Container is not rendered to a webpart but rather displayed on the page itself (e.g. SchemaBrowser, 222 * manageFolders, etc). 223 * @param extContainer - (Required) outer container which is the target to be resized 224 * @param width - (Required) width of the viewport. In many cases, the window width. If a negative width is passed than 225 * the width will not be set. 226 * @param height - (Required) height of the viewport. In many cases, the window height. If a negative height is passed than 227 * the height will not be set. 228 * @param paddingX - distance from the right edge of the viewport. Defaults to 35. 229 * @param paddingY - distance from the bottom edge of the viewport. Defaults to 35. 230 */ 231 resizeToViewport: function(extContainer, width, height, paddingX, paddingY, offsetX, offsetY) 232 { 233 resizeToContainer.apply(this, arguments); 234 } 235 }; 236 };