-<html>\r
-<head>\r
- <title>The source code</title>\r
- <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />\r
- <script type="text/javascript" src="../resources/prettify/prettify.js"></script>\r
-</head>\r
-<body onload="prettyPrint();">\r
- <pre class="prettyprint lang-js">Ext.sql.Table = function(conn, name, keyName){\r
- this.conn = conn;\r
- this.name = name;\r
- this.keyName = keyName;\r
-};\r
-\r
-Ext.sql.Table.prototype = {\r
- update : function(o){\r
- var clause = this.keyName + " = ?";\r
- return this.updateBy(o, clause, [o[this.keyName]]);\r
- },\r
-\r
- updateBy : function(o, clause, args){\r
- var sql = "UPDATE " + this.name + " set ";\r
- var fs = [], a = [];\r
- for(var key in o){\r
- if(o.hasOwnProperty(key)){\r
- fs[fs.length] = key + ' = ?';\r
- a[a.length] = o[key];\r
- }\r
- }\r
- for(var key in args){\r
- if(args.hasOwnProperty(key)){\r
- a[a.length] = args[key];\r
- }\r
- }\r
- sql = [sql, fs.join(','), ' WHERE ', clause].join('');\r
- return this.conn.execBy(sql, a);\r
- },\r
-\r
- insert : function(o){\r
- var sql = "INSERT into " + this.name + " ";\r
- var fs = [], vs = [], a = [];\r
- for(var key in o){\r
- if(o.hasOwnProperty(key)){\r
- fs[fs.length] = key;\r
- vs[vs.length] = '?';\r
- a[a.length] = o[key];\r
- }\r
- }\r
- sql = [sql, '(', fs.join(','), ') VALUES (', vs.join(','), ')'].join('');\r
- return this.conn.execBy(sql, a);\r
- },\r
-\r
- lookup : function(id){\r
- return this.selectBy('where ' + this.keyName + " = ?", [id])[0] || null;\r
- },\r
-\r
- exists : function(id){\r
- return !!this.lookup(id);\r
- },\r
-\r
- save : function(o){\r
- if(this.exists(o[this.keyName])){\r
- this.update(o);\r
- }else{\r
- this.insert(o);\r
- }\r
- },\r
-\r
- select : function(clause){\r
- return this.selectBy(clause, null);\r
- },\r
-\r
- selectBy : function(clause, args){\r
- var sql = "select * from " + this.name;\r
- if(clause){\r
- sql += ' ' + clause;\r
- }\r
- args = args || {};\r
- return this.conn.queryBy(sql, args);\r
- },\r
-\r
- remove : function(clause){\r
- this.deleteBy(clause, null);\r
- },\r
-\r
- removeBy : function(clause, args){\r
- var sql = "delete from " + this.name;\r
- if(clause){\r
- sql += ' where ' + clause;\r
- }\r
- args = args || {};\r
- this.conn.execBy(sql, args);\r
- }\r
-};</pre> \r
-</body>\r
-</html>
\ No newline at end of file
+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>The source code</title>
+ <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
+ <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
+ <style type="text/css">
+ .highlight { display: block; background-color: #ddd; }
+ </style>
+ <script type="text/javascript">
+ function highlight() {
+ document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
+ }
+ </script>
+</head>
+<body onload="prettyPrint(); highlight();">
+ <pre class="prettyprint lang-js"><span id='Ext-layout-container-Table'>/**
+</span> * This layout allows you to easily render content into an HTML table. The total number of columns can be specified, and
+ * rowspan and colspan can be used to create complex layouts within the table. This class is intended to be extended or
+ * created via the `layout: {type: 'table'}` {@link Ext.container.Container#layout} config, and should generally not
+ * need to be created directly via the new keyword.
+ *
+ * Note that when creating a layout via config, the layout-specific config properties must be passed in via the {@link
+ * Ext.container.Container#layout} object which will then be applied internally to the layout. In the case of
+ * TableLayout, the only valid layout config properties are {@link #columns} and {@link #tableAttrs}. However, the items
+ * added to a TableLayout can supply the following table-specific config properties:
+ *
+ * - **rowspan** Applied to the table cell containing the item.
+ * - **colspan** Applied to the table cell containing the item.
+ * - **cellId** An id applied to the table cell containing the item.
+ * - **cellCls** A CSS class name added to the table cell containing the item.
+ *
+ * The basic concept of building up a TableLayout is conceptually very similar to building up a standard HTML table. You
+ * simply add each panel (or "cell") that you want to include along with any span attributes specified as the special
+ * config properties of rowspan and colspan which work exactly like their HTML counterparts. Rather than explicitly
+ * creating and nesting rows and columns as you would in HTML, you simply specify the total column count in the
+ * layoutConfig and start adding panels in their natural order from left to right, top to bottom. The layout will
+ * automatically figure out, based on the column count, rowspans and colspans, how to position each panel within the
+ * table. Just like with HTML tables, your rowspans and colspans must add up correctly in your overall layout or you'll
+ * end up with missing and/or extra cells! Example usage:
+ *
+ * @example
+ * Ext.create('Ext.panel.Panel', {
+ * title: 'Table Layout',
+ * width: 300,
+ * height: 150,
+ * layout: {
+ * type: 'table',
+ * // The total column count must be specified here
+ * columns: 3
+ * },
+ * defaults: {
+ * // applied to each contained panel
+ * bodyStyle: 'padding:20px'
+ * },
+ * items: [{
+ * html: 'Cell A content',
+ * rowspan: 2
+ * },{
+ * html: 'Cell B content',
+ * colspan: 2
+ * },{
+ * html: 'Cell C content',
+ * cellCls: 'highlight'
+ * },{
+ * html: 'Cell D content'
+ * }],
+ * renderTo: Ext.getBody()
+ * });
+ */
+Ext.define('Ext.layout.container.Table', {
+
+ /* Begin Definitions */
+
+ alias: ['layout.table'],
+ extend: 'Ext.layout.container.Auto',
+ alternateClassName: 'Ext.layout.TableLayout',
+
+ /* End Definitions */
+
+<span id='Ext-layout-container-Table-cfg-columns'> /**
+</span> * @cfg {Number} columns
+ * The total number of columns to create in the table for this layout. If not specified, all Components added to
+ * this layout will be rendered into a single row using one column per Component.
+ */
+
+ // private
+ monitorResize:false,
+
+ type: 'table',
+
+ // Table layout is a self-sizing layout. When an item of for example, a dock layout, the Panel must expand to accommodate
+ // a table layout. See in particular AbstractDock::onLayout for use of this flag.
+ autoSize: true,
+
+ clearEl: true, // Base class will not create it if already truthy. Not needed in tables.
+
+ targetCls: Ext.baseCSSPrefix + 'table-layout-ct',
+ tableCls: Ext.baseCSSPrefix + 'table-layout',
+ cellCls: Ext.baseCSSPrefix + 'table-layout-cell',
+
+<span id='Ext-layout-container-Table-cfg-tableAttrs'> /**
+</span> * @cfg {Object} tableAttrs
+ * An object containing properties which are added to the {@link Ext.DomHelper DomHelper} specification used to
+ * create the layout's `<table>` element. Example:
+ *
+ * {
+ * xtype: 'panel',
+ * layout: {
+ * type: 'table',
+ * columns: 3,
+ * tableAttrs: {
+ * style: {
+ * width: '100%'
+ * }
+ * }
+ * }
+ * }
+ */
+ tableAttrs:null,
+
+<span id='Ext-layout-container-Table-cfg-trAttrs'> /**
+</span> * @cfg {Object} trAttrs
+ * An object containing properties which are added to the {@link Ext.DomHelper DomHelper} specification used to
+ * create the layout's <tr> elements.
+ */
+
+<span id='Ext-layout-container-Table-cfg-tdAttrs'> /**
+</span> * @cfg {Object} tdAttrs
+ * An object containing properties which are added to the {@link Ext.DomHelper DomHelper} specification used to
+ * create the layout's <td> elements.
+ */
+
+<span id='Ext-layout-container-Table-method-renderItems'> /**
+</span> * @private
+ * Iterates over all passed items, ensuring they are rendered in a cell in the proper
+ * location in the table structure.
+ */
+ renderItems: function(items) {
+ var tbody = this.getTable().tBodies[0],
+ rows = tbody.rows,
+ i = 0,
+ len = items.length,
+ cells, curCell, rowIdx, cellIdx, item, trEl, tdEl, itemCt;
+
+ // Calculate the correct cell structure for the current items
+ cells = this.calculateCells(items);
+
+ // Loop over each cell and compare to the current cells in the table, inserting/
+ // removing/moving cells as needed, and making sure each item is rendered into
+ // the correct cell.
+ for (; i < len; i++) {
+ curCell = cells[i];
+ rowIdx = curCell.rowIdx;
+ cellIdx = curCell.cellIdx;
+ item = items[i];
+
+ // If no row present, create and insert one
+ trEl = rows[rowIdx];
+ if (!trEl) {
+ trEl = tbody.insertRow(rowIdx);
+ if (this.trAttrs) {
+ trEl.set(this.trAttrs);
+ }
+ }
+
+ // If no cell present, create and insert one
+ itemCt = tdEl = Ext.get(trEl.cells[cellIdx] || trEl.insertCell(cellIdx));
+ if (this.needsDivWrap()) { //create wrapper div if needed - see docs below
+ itemCt = tdEl.first() || tdEl.createChild({tag: 'div'});
+ itemCt.setWidth(null);
+ }
+
+ // Render or move the component into the cell
+ if (!item.rendered) {
+ this.renderItem(item, itemCt, 0);
+ }
+ else if (!this.isValidParent(item, itemCt, 0)) {
+ this.moveItem(item, itemCt, 0);
+ }
+
+ // Set the cell properties
+ if (this.tdAttrs) {
+ tdEl.set(this.tdAttrs);
+ }
+ tdEl.set({
+ colSpan: item.colspan || 1,
+ rowSpan: item.rowspan || 1,
+ id: item.cellId || '',
+ cls: this.cellCls + ' ' + (item.cellCls || '')
+ });
+
+ // If at the end of a row, remove any extra cells
+ if (!cells[i + 1] || cells[i + 1].rowIdx !== rowIdx) {
+ cellIdx++;
+ while (trEl.cells[cellIdx]) {
+ trEl.deleteCell(cellIdx);
+ }
+ }
+ }
+
+ // Delete any extra rows
+ rowIdx++;
+ while (tbody.rows[rowIdx]) {
+ tbody.deleteRow(rowIdx);
+ }
+ },
+
+ afterLayout: function() {
+ this.callParent();
+
+ if (this.needsDivWrap()) {
+ // set wrapper div width to match layed out item - see docs below
+ Ext.Array.forEach(this.getLayoutItems(), function(item) {
+ Ext.fly(item.el.dom.parentNode).setWidth(item.getWidth());
+ });
+ }
+ },
+
+<span id='Ext-layout-container-Table-method-calculateCells'> /**
+</span> * @private
+ * Determine the row and cell indexes for each component, taking into consideration
+ * the number of columns and each item's configured colspan/rowspan values.
+ * @param {Array} items The layout components
+ * @return {Object[]} List of row and cell indexes for each of the components
+ */
+ calculateCells: function(items) {
+ var cells = [],
+ rowIdx = 0,
+ colIdx = 0,
+ cellIdx = 0,
+ totalCols = this.columns || Infinity,
+ rowspans = [], //rolling list of active rowspans for each column
+ i = 0, j,
+ len = items.length,
+ item;
+
+ for (; i < len; i++) {
+ item = items[i];
+
+ // Find the first available row/col slot not taken up by a spanning cell
+ while (colIdx >= totalCols || rowspans[colIdx] > 0) {
+ if (colIdx >= totalCols) {
+ // move down to next row
+ colIdx = 0;
+ cellIdx = 0;
+ rowIdx++;
+
+ // decrement all rowspans
+ for (j = 0; j < totalCols; j++) {
+ if (rowspans[j] > 0) {
+ rowspans[j]--;
+ }
+ }
+ } else {
+ colIdx++;
+ }
+ }
+
+ // Add the cell info to the list
+ cells.push({
+ rowIdx: rowIdx,
+ cellIdx: cellIdx
+ });
+
+ // Increment
+ for (j = item.colspan || 1; j; --j) {
+ rowspans[colIdx] = item.rowspan || 1;
+ ++colIdx;
+ }
+ ++cellIdx;
+ }
+
+ return cells;
+ },
+
+<span id='Ext-layout-container-Table-method-getTable'> /**
+</span> * @private
+ * Return the layout's table element, creating it if necessary.
+ */
+ getTable: function() {
+ var table = this.table;
+ if (!table) {
+ table = this.table = this.getTarget().createChild(
+ Ext.apply({
+ tag: 'table',
+ role: 'presentation',
+ cls: this.tableCls,
+ cellspacing: 0, //TODO should this be specified or should CSS handle it?
+ cn: {tag: 'tbody'}
+ }, this.tableAttrs),
+ null, true
+ );
+ }
+ return table;
+ },
+
+<span id='Ext-layout-container-Table-method-needsDivWrap'> /**
+</span> * @private
+ * Opera 10.5 has a bug where if a table cell's child has box-sizing:border-box and padding, it
+ * will include that padding in the size of the cell, making it always larger than the
+ * shrink-wrapped size of its contents. To get around this we have to wrap the contents in a div
+ * and then set that div's width to match the item rendered within it afterLayout. This method
+ * determines whether we need the wrapper div; it currently does a straight UA sniff as this bug
+ * seems isolated to just Opera 10.5, but feature detection could be added here if needed.
+ */
+ needsDivWrap: function() {
+ return Ext.isOpera10_5;
+ }
+});</pre>
+</body>
+</html>