[ Mini Kiebo ]
Server: Windows NT DESKTOP-5B8S0D4 6.2 build 9200 (Windows 8 Professional Edition) i586
Path:
D:
/
xampp182
/
htdocs
/
simpeg
/
zapatec
/
zpgrid
/
zpgrid
/
jsdocs
/
[
Home
]
File: overview-summary-zpgrid-core.js.html
<!doctype html public "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd"> <html> <head> <title> Zapatec Grid Overview </title> <link rel ="stylesheet" type="text/css" href="stylesheet.css" title="Style"> <script> function asd() { parent.document.title="zpgrid-core.js Overview"; } </script> </head> <body bgcolor="white" onload="asd();"> <!-- ========== START OF NAVBAR ========== --> <a name="navbar_top"><!-- --></a> <table border="0" width="100%" cellpadding="1" cellspacing="0"> <tr> <td colspan=2 bgcolor="#EEEEFF" class="NavBarCell1"> <a name="navbar_top_firstrow"><!-- --></a> <table border="0" cellpadding="0" cellspacing="3"> <tr align="center" valign="top"> <td bgcolor="#EEEEFF" class="NavBarCell1"> <a href="overview-summary.html"><font class="NavBarFont1"><b>Overview</b></font></a> </td> <td bgcolor="#FFFFFF" class="NavBarCell1Rev"> <font class="NavBarFont1Rev"><b>File</b></font> </td> <td bgcolor="#FFFFFF" class="NavBarCell1"> <font class="NavBarFont1">Class</font> </td> <td bgcolor="#EEEEFF" class="NavBarCell1"> <a href="overview-tree.html"><font class="NavBarFont1"><b>Tree</b></font></a> </td> <td bgcolor="#EEEEFF" class="NavBarCell1"> <a href="index-all.html"--><font class="NavBarFont1"><b>Index</b></font></a> </td> <td bgcolor="#EEEEFF" class="NavBarCell1"> <a href="help-doc.html"><font class="NavBarFont1"><b>Help</b></font></a> </td> </tr> </table> </td> <td bgcolor="#EEEEFF" align="right" valign="top"> <em> <b>Zapatec Grid</b></em> </td> </tr> <tr> <td bgcolor="white" class="NavBarCell2"><font size="-2"> PREV NEXT</font></td> <td bgcolor="white" class="NavBarCell2"><font size="-2"> <a href="index.html" target="_top"><b>FRAMES</b></a> <a href="overview-summary.html" target="_top"><b>NO FRAMES</b></a> <script> <!-- if(window==top) { document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>'); } //--> </script> <noscript> <a href="allclasses-noframe.html" target=""><b>All Classes</b></a> </noscript> </font></td> </tr> </table> <!-- =========== END OF NAVBAR =========== --> <hr> <center> <h2>zpgrid-core.js</h2> </center> <h4>Summary</h4> <p> Zapatec Grid core. Provides base grid features: sorting, filtering, ranges, search, adding and removing rows, pagination, selection, JSON input format, output using callback functions. Can be used alone if data types and standard output functions are not needed. <pre> Copyright (c) 2004-2007 by Zapatec, Inc. http://www.zapatec.com 1700 MLK Way, Berkeley, California, 94709, U.S.A. All rights reserved. </pre><BR/><BR/> </p> <hr> <table border="1" cellpadding="3" cellspacing="0" width="100%"> <tr bgcolor="#CCCCFF" class="TableHeadingColor"> <td colspan=2><font size="+2"> <b>Class Summary</b> </font></td> </tr> <tr bgcolor="white" class="TableRowColor"> <td width="15%"><b><a href="Zapatec/Grid.html">Zapatec.Grid</a></b></td> <td> </td> </tr> </table> <hr/> <!-- ========== METHOD SUMMARY =========== --> <!-- ========== END METHOD SUMMARY =========== --> <pre class="sourceview"><span class="comment">/** * <span class="attrib">@fileoverview</span> Zapatec Grid core. Provides base grid features: sorting, * filtering, ranges, search, adding and removing rows, pagination, selection, * JSON input format, output using callback functions. Can be used alone if data * types and standard output functions are not needed. * * <pre> * Copyright (c) 2004-2007 by Zapatec, Inc. * http://www.zapatec.com * 1700 MLK Way, Berkeley, California, * 94709, U.S.A. * All rights reserved. * </pre> */</span> <span class="comment">/* $Id: zpgrid-core.js 7649 2007-08-03 14:15:03Z alex $ */</span> <span class="comment">// Emulate window.event in Mozilla for certain events</span> Zapatec.Utils.emulateWindowEvent([<span class="literal">'mousedown'</span>, <span class="literal">'mouseup'</span>, <span class="literal">'click'</span>, <span class="literal">'dblclick'</span>]); <span class="comment">/** * Grid core. * * <pre> * <strong>Input data formats:</strong> * * <strong>JSON:</strong> * * { * style: [string, optional] table style attribute, * headerStyle: [string, optional] header table row style attribute, * fields: * [ * { * i: [number] zero-based column number, <b>dataPrepared</b> specific, * title: [string, optional] column title, * dataType: [string, optional] defines which standard or custom data type * to use for cell conversion (if not specified, no conversion is done), * columnWidth: [string, optional] column width, e.g. "10px", "10em", * style: [string, optional] header table cell style attribute, * span: [number, optional] how many columns to span, * spanTitle: [string, optional] span title, * spanStyle: [string, optional] span table cell style attribute, * hidden: [boolean, optional] if true, column will not be displayed, but * filtering and searching can still be done on this column, * nosort: [boolean, optional] if true, grid will not be sorted when this * header is clicked, * sortByColumn: [number, optional] zero-based number of column to use for * sorting, * hiddenValues: [object, optional] array of hidden values - rows * conaining these values in the column will not be displayed, * minValue: [any, optional] rows containing values in the column lesser * than this value will not be displayed, * maxValue: [any, optional] rows containing values in the column greater * than this value will not be displayed, * regexpFilter: [string, optional] rows where column value don't match * this regular expression will not be displayed, * textFilter: [string, optional] rows which don't contain this pattern * in the column value will not be displayed, * columnRange: [object, optional] see {<span class="attrib">@link</span> Zapatec.Grid#getColumnRange} * }, * ... * ], * primaryKey: [number, optional] number of column to use as primary key, * rows: * [ * { * i: [number] zero-based row number, <b>dataPrepared</b> specific, * cells: * [ * { * i: [number] zero-based column number, <b>dataPrepared</b> specific, * r: [number] zero-based row number, <b>dataPrepared</b> specific, * v: [any] cell value to display, * c: [any, optional] cell value to compare, * o: [any, optional] original cell value, * style: [string, optional] table cell style attribute, * colspan: [number, optional] number of columns this cell spans, * rowspan: [number, optional] number of rows this cell spans * }, * ... * ], * style: [string, optional] table row style attribute * }, * ... * ], * totalRows: [number, optional] <b>dataOnDemand</b> specific, * displayedRows: [number, optional] <b>dataOnDemand</b> specific, * currentPage: [number, optional] <b>dataOnDemand</b> specific * } * * "i" and "r" properties are required when <b>dataPrepared</b> config option is * true. When <b>dataPrepared</b> is false, they are overwritten by automatic * column and row numbers. * * "c" and "o" properties may be useful when column "dataType" is not set. Also * they are required when <b>dataPrepared</b> config option is true and their * values differ from the value of "v" property of the cell. Anyway, they * shouldn't be set if their values are equal to the value of "v" property of * the cell. * * "totalRows" property is used to pass total number of rows in the grid when * <b>dataOnDemand</b> config option is used. * * "displayedRows" property is used to pass number of displayed rows when * <b>dataOnDemand</b> config option is used and filter is applied. If filter * is not applied and there are no hidden rows, should be equal to totalRows. * * "currentPage" property is used to pass zero-based current page number when * <b>dataOnDemand</b> config option is used. * * "totalRows", "displayedRows" and "currentPage" properties are required when * <b>dataOnDemand</b> config option is true. When <b>dataOnDemand</b> is false, * they are ignored. * * "dataType" property requires zpgrid-convert.js module that is included by * default. * * "hiddenValues", "minValue", "maxValue", "regexpFilter", "regexpFilter", * "columnRange" properies are useful when <b>dataOnDemand</b> config option is * true. See phone_ondemand.html demo. * * <strong>HTML:</strong> * (requires zpgrid-html.js that is included by default) * * <xmp> * <table style="border: 1px solid #000"> * <tbody> * <tr style="background-color: #00f"> * <td width="56" class="zpGridTypeDate" style="font-weight: bold" * span="2" spantitle="Date & Time" spanstyle="text-align: center"> * Date * </td> * <td width="56" class="zpGridTypeTime" style="font-weight: bold"> * Time * </td> * <td> * Title * </td> * <td> * Comments * </td> * ... * </tr> * <tr style="background-color: #ccc"> * <td style="background-color: #f00">01/01/2001</td> * <td style="background-color: #f00">09:30AM</td> * <td colspan="2" rowspan="2">Meeting</td> * ... * </tr> * <tr style="background-color: #ccc"> * <td style="background-color: #f00">01/01/2001</td> * <td style="background-color: #f00">10:30AM</td> * ... * </tr> * ... * </tbody> * </table> * </xmp> * * First row in the source table defines grid columns. * * To set column data type other than "string", add one of standard or custom * data type class names to the "class" attribute of the corresponding cell * in the first row. * Difference from JSON input format: If data type is not specified, conversion * will be done according to the "string" data type. * * Column width can be set through "width" attribute of the corresponding cell * in the first row. * * Special "zpGridTypeHidden" class makes column hidden and it will not be * displayed, but filtering and searching can still be done on this column. * This field type can be used alone or in conjunction with other field type, * e.g. class="zpGridTypeInt zpGridTypeHidden". * * Special "zpGridTypeNosort" class makes column header not clickable. Grid will * not be sorted when this header is clicked. This field type can be used alone * or in conjunction with other field type, * e.g. class="zpGridTypeInt zpGridTypeNosort". * * Special "zpGridTypeNotags" class makes grid skip all tags in the column, and * only uses the text. This will facilitate migrating from an existing table * to the grid. This field type can be used alone or in conjunction with other * field type, e.g. class="zpGridTypeInt zpGridTypeNotags". * * Special "zpGridTypeSortByN" class makes column use anoter column for sorting. * Where N is zero-based column number to use for sorting. This field type can * be used alone or in conjunction with other field type, e.g. * class="zpGridTypeInt zpGridTypeSortBy2". * * Special "zpGridTypePrimaryKey" class makes column a primary key for the grid. * This field type can be used alone or in conjunction with other field type, * e.g. class="zpGridTypeInt zpGridTypePrimaryKey". * * Attributes "style", "width", "span", "spantitle", "spanstyle", "colspan" are * optional. * * "span" how many columns to span. * * "spantitle" span title. * * "spanstyle" span table cell style attribute. * * Other attributes mean the same as for regular HTML table. * * <strong>XML:</strong> * (requires zpgrid-xml.js that is NOT included by default) * * <xmp> * <?xml version="1.0"?> * <grid> * <table style="border: solid black 1px" headerstyle="background: #ccc" * primarykey="0" totalrows="123" displayedrows="89" currentpage="3"> * <fields> * <field width="10px" hidden="true" nosort="true" sortbycolumn="2" * style="color: #00f" span="2" spantitle="Span Title" * spanstyle="text-align: center"> * <title>Title</title> * <datatype>string</datatype> * <hiddenvalues> * <hiddenval>Hidden value</hiddenval> * ... * </hiddenvalues> * <minlimit>Min displayed value (useful for Slider)</minlimit> * <maxlimit>Max displayed value (useful for Slider)</maxlimit> * <regexpfilter>Regexp filter</regexpfilter> * <textfilter>Text filter</textfilter> * <columnrange> * <minvalue>Min value</minvalue> * <maxvalue>Max value</maxvalue> * <uniquevalues> * <uniqueval>Unique value</uniqueval> * ... * </uniquevalues> * </columnrange> * </field> * ... * </fields> * <rows> * <row style="background: #eee"> * <cell style="color: #f00" colspan="2" rowspan="2">Value</cell> * ... * </row> * ... * </rows> * </table> * </grid> * </xmp> * * Where "style", "headerstyle", "primarykey", "totalrows", "displayedrows", * "currentpage", "width", "hidden", "nosort", "sortbycolumn", "span", * "spantitle", "spanstyle", "colspan" attributes are optional. * * "style" is style attribute of table, row or cell. * * "headerstyle" is header table row style attribute. * * "primarykey" defines column number to use as primary key. If not specified, * no primary key is created. * * "totalrows" is total number of rows when <b>dataOnDemand</b> config option is * true. * * "displayedrows" is number of rows displayed when <b>dataOnDemand</b> config * option is true. * * "currentpage" is zero-based current page number when <b>dataOnDemand</b> * config option is true. * * "width" is column width. * * "hidden=true" attribute makes column hidden and it will not be displayed, but * filtering and searching can still be done on this column. * * "nosort=true" attribute makes column header not clickable. Grid will not be * sorted when this header is clicked. * * "sortbycolumn=N" attribute makes column use anoter column for sorting. * Where N is zero-based column number to use for sorting. * * "span" how many columns to span. * * "spantitle" span title. * * "spanstyle" span table cell style attribute. * * "datatype" tag is optional. Defines which standard or custom data type to use * for cell conversion. If not specified, no conversion is done. * * "hiddenvalues", "minlimit", "maxlimit", "regexpfilter", "textfilter", * "columnrange" tags are optional. They are useful when <b>dataOnDemand</b> * config option is true. See phone_ondemand_xml.html demo. * * "colspan" number of columns this cell spans. Works the same as in HTML table. * * "rowspan" number of rows this cell spans. Works the same as in HTML table. * * <strong>Possible data types:</strong> * * ----------------------------------------------------------------------------- * Name for JSON |Class name for HTML |Input data |Format of * and XML formats |format |format |displayed data * -----------------|---------------------------|----------------|-------------- * string |zpGridTypeString |string |same as input * -----------------|---------------------------|----------------| * istring |zpGridTypeStringInsensitive|case insensitive| * | |string | * -----------------|---------------------------|----------------| * int |zpGridTypeInt |number or | * | |Infinity | * -----------------|---------------------------|----------------| * intGerman |zpGridTypeIntGerman |number in | * | |German format or| * | |Infinity | * -----------------|---------------------------|----------------| * float |zpGridTypeFloat |number or | * | |Infinity | * -----------------|---------------------------|----------------| * floatGerman |zpGridTypeFloatGerman |number in | * | |German format or| * | |Infinity | * -----------------|---------------------------|----------------| * date |zpGridTypeDate |string accepted | * | |by builtin | * | |javascript Date | * | |object | * -----------------|---------------------------|----------------| * time |zpGridTypeTime |HH:MM:SS | * | |HH:MM:SS AM/PM | * | |HH:MM | * | |HH:MM AM/PM | * | |HHMMSS | * | |HHMMSS AM/PM | * | |HHMM | * | |HHMM AM/PM | * -----------------|---------------------------|----------------|-------------- * timestamp |zpGridTypeTimestampLocale |integer (number |Date in locale * | |of seconds since|format * -----------------|---------------------------|01/01/1970 |-------------- * timestampMMDDYYYY|zpGridTypeTimestampMMDDYYYY|00:00 GMT) |MM/DD/YYYY * -----------------|---------------------------| |-------------- * timestampDDMMYYYY|zpGridTypeTimestampDDMMYYYY| |DD/MM/YYYY * -----------------|---------------------------| |-------------- * timestampYYYYMMDD|zpGridTypeTimestampYYYYMMDD| |YYYY/MM/DD * -----------------|---------------------------|----------------|-------------- * boolean |zpGridTypeBoolean |case insensitive|No/Yes * | |0 or 1 |or custom * -----------------|---------------------------|f or t |-------------- * booleanTF |zpGridTypeBooleanTF |false or true |False/True * | |n or y |or custom * | |no or yes | * ----------------------------------------------------------------------------- * * <strong>In addition to config options defined in base Zapatec.Widget class * provides following config options:</strong> * * <b>show_asis</b> [boolean] Show data as is. * The original data the is imported to the grid needs to be translated to it's field type. * In many cases this translation changes the original data. * This option gives control back to the user to define how to display the grid cell * Possible values: * boolean * true - Show ALL cells as is * false - Show the cells based on the field type conversion * object {bBoth, funcShow} * bBoth - Show both in cell, Ex: Orig = Zapatec Value * Ex: Showing both * BYTES- cell=|15 MB=15360000000|; where 15 MB is orig and 15360000000 bytes is converted value * HOURS- cell=|2 days 1 hour=49|; where 2 days 1 hour is orig and 49 hours is converted value * WEIGHT- cell=|1 lb 2 oz=18|; where 1 lb 2 oz is orig and 18 oz is converted value * funcShow - callback function to create presentable cell data * Function to visually present the data. Does NOT effect sorting, just visual * sShowData = this.config.show_asis.funcShow(oGrid, oCell); * param oCell - Zapatec.Grid object * param oCell - cell object * * <b>funcStyle</b> [function] Callback function to dynamically change the style * of a cell. * Dynamically change the style of a cell based on the contents. * param oGrid - Zapatec.Grid object * param oCell - cell object * param iRow - index of the row in the displayed rows array returned by * {<span class="attrib">@link</span> Zapatec.Grid#applyPaging} method * return undefined if NO change to style * return string for the inline style that should be applied to this cell * * <b>convert</b> [function] Callback function to convert the cell value. * Receives Zapatec.Grid object and cell object. If returns a value, that value * will be assigned to the cell display and compare values. * * <b>container</b> [object or string] Element or id of element that will hold * the grid. If "callbackHeaderDisplay" and "callbackRowDisplay" or * "callbackDataDisplay" options are defined, grid will be drawn using those * functions and "container" option is ignored. Also can be used instead of * "source" option. If "source" option is not defined, first child table of * container element is used as source. * * Standard output requires zpgrid-output.js module that is included by default. * * <b>headerContainer</b> [object or string] Element or id of element that will * hold header of the grid. Used together with "container" option when header * should be separated from the grid. E.g. to have grid data scrollable * vertically and header always visible. See scroll.html demo for details. * * <b>totalsContainer</b> [object or string] Element or id of element that will * hold totals. Used together with "container" option when totals should be * separated from the grid. E.g. to have grid data scrollable vertically and * totals always visible. See scroll.html demo for details. * * <b>visibleRows</b> [number] Used for displaying custom vertical scrollbar. * If > 0, limits number of rows displayed starting from current vertical offset. * See {<span class="attrib">@link</span> Zapatec.Grid#gotoVerticalOffset} method for details about current * vertical offset. Default: 0. * * <b>visibleColumns</b> [number] Used for displaying custom horizontal * scrollbar. If > 0, limits number of columns displayed starting from current * horizontal offset. See {<span class="attrib">@link</span> Zapatec.Grid#gotoHorizontalOffset} method for * details about current horizontal offset. Default: 0. * * <b>rowsPerPage</b> [number] If > 0, paging is used. Default: 0. * * <b>paginationContainer</b> [object or string] Element or id of element that * will hold pagination of the grid. Used together with "container" and * "rowsPerPage" options when pagination should be separated from the grid. See * scroll.html demo for example. You can pass several containers in an array to * this option if you need to display pagination in two or more places. See * compare.html demo for example. * * <b>border</b> [object or string] Element or id of element that is parent for * all grid containers. Used to determine dimensions of the grid when it has * several containers. Need only for <b>fitIntoParent</b> feature below when * grid has several containers. Default is parent element of the * <b>container</b>. * * <b>fitIntoParent</b> [boolean, object or string] When true, grid will be * adjusted dynamically to fit into parent element of the <b>border</b>. * When element or id of element, grid will be adjusted dynamically to fit into * that element. * * <b>horizontal</b> [boolean] If true, horizontal layout is used in standard * output. Default: false. * * <b>selectRows</b> [boolean] If true, selected rows will be marked by * different color depending from theme. Default: true. Ignored when callback * functions are used to display grid. * * <b>selectCells</b> [boolean] If true, selected cells will be marked by * different color depending from theme. Default: true. Ignored when callback * functions are used to display grid. * * <b>activeRows</b> [boolean] If true, active rows will be marked by * different color depending from theme. Default: true. Ignored when callback * functions are used to display grid. * * <b>activeCells</b> [boolean] If true, active cells will be marked by * different color depending from theme. Default: true. Ignored when callback * functions are used to display grid. * * <b>multipleSelect</b> [boolean] If true, "Shift" and "Ctrl" click will select * multiple rows and cells. If false, only one row and cell can be selected at * a time. Default: true. * * <b>callbackHeaderDisplay</b> [function] Callback function to display grid * header. Used togeter with callbackRowDisplay or callbackDataDisplay option as * alternetive way to display the grid. Otherwise ignored. Receives Zapatec.Grid * object. No return value is needed. * * <b>callbackDataDisplay</b> [function] Callback function to display grid rows. * Used togeter with callbackHeaderDisplay option as alternetive way to display * the grid. Otherwise ignored. Receives Zapatec.Grid object and array of row * objects. No return value is needed. * * <b>callbackRowDisplay</b> [function] Callback function to display grid row. * Called for each row. Used togeter with callbackHeaderDisplay option as * alternetive way to display the grid. Otherwise ignored. Ignored when * callbackDataDisplay is set. Receives Zapatec.Grid object and row object. * No return value is needed. * * <b>callbackTotalsDisplay</b> [function] Callback function to display totals. * Used togeter with callbackHeaderDisplay, callbackRowDisplay and * callbackDataDisplay options as alternetive way to display the grid, but also * can be used separately as a replacement for standard totals. Receives * Zapatec.Grid object and array of row objects for totals. If totals option is * not set this option still can be used, but it receives undefined instead of * array of rows. No return value is needed. * * <b>callbackTotalDisplay</b> [function] Callback function to display totals * row. Called for each totals row. Used togeter with callbackHeaderDisplay, * callbackRowDisplay and callbackDataDisplay options as alternetive way to * display the grid, but also can be used separately as a replacement for * standard totals. Ignored when callbackTotalsDisplay is set. Receives * Zapatec.Grid object and totals row object. No return value is needed. * * <b>callbackPaginationDisplay</b> [function] Callback function to display grid * pagination. Used togeter with callbackHeaderDisplay, callbackRowDisplay and * callbackDataDisplay options as alternetive way to display the grid, but also * can be used separately as a replacement for standard pagination. * Receives Zapatec.Grid object. No return value is needed. See also * {<span class="attrib">@link</span> Zapatec.Grid#gotoPage}, {<span class="attrib">@link</span> Zapatec.Grid#previousPage}, * {<span class="attrib">@link</span> Zapatec.Grid#firstPage}, {<span class="attrib">@link</span> Zapatec.Grid#nextPage}, * {<span class="attrib">@link</span> Zapatec.Grid#lastPage}. * * <b>callbackRowOnClick</b> [function] Callback function to call when grid row * is clicked with left mouse button. Receives Zapatec.Grid object and row * object. No return value is needed. * * <b>callbackRowOnRightClick</b> [function] Callback function to call when grid * row is clicked with right mouse button. Receives Zapatec.Grid object and row * object. No return value is needed. * * <b>callbackCellOnClick</b> [function] Callback function to call when grid * cell is clicked with left mouse button. Receives Zapatec.Grid object and cell * object. No return value is needed. If this option is defined, above * "callbackRowOnClick" option is ignored. * * <b>callbackCellOnRightClick</b> [function] Callback function to call when * grid cell is clicked with right mouse button. Receives Zapatec.Grid object * and cell object. No return value is needed. If this option is defined, above * "callbackRowOnRightClick" option is ignored. * * <b>callbackRowOnDblClick</b> [function] Callback function to call when grid * row is double clicked. Receives Zapatec.Grid object and row object. No return * value is needed. * * <b>callbackCellOnDblClick</b> [function] Callback function to call when grid * cell is double clicked. Receives Zapatec.Grid object and cell object. No * return value is needed. If this option is defined, above * "callbackRowOnDblClick" option is ignored. * * <b>callbackRowSelect</b> [function] Callback function to call when grid row * is selected. Receives Zapatec.Grid object and row object. No return value is * needed. * * <b>callbackCellSelect</b> [function] Callback function to call when grid cell * is selected. Receives Zapatec.Grid object and cell object. No return value is * needed. If this option is defined, above "callbackRowSelect" option is * ignored. * * <b>callbackRowUnselect</b> [function] Callback function to call when grid row * is unselected. Receives Zapatec.Grid object and row object. No return value * is needed. * * <b>callbackCellUnselect</b> [function] Callback function to call when grid * cell is unselected. Receives Zapatec.Grid object and cell object. No return * value is needed. If this option is defined, above "callbackRowUnselect" * option is ignored. * * <b>callbackOnRefresh</b> [function] Callback function to call when grid is * refreshed. Receives Zapatec.Grid object. No return value is needed. * Deprecated. Use <b>gridRefreshed</b> event described below instead. * * <b>sortColumn</b> [number] Number of column to sort initially. First column * number is 0. If not set, initially grid will not be sorted. * * <b>sortDesc</b> [boolean] Used together with sortColumn option. Otherwise * ignored. If true, initially grid will be sorted in descending order. * * <b>filterOut</b> [object] Array of associative arrays: * [ * { * column: [object or number] array of zero-based column numbers or single * zero-based column number to use as source of values to filter out, * sortDesc: [boolean, optional] if true, list of values will be sorted * descending, otherwise ascending (default is false), * container: [object or string, optional] element or id of element that * will hold the list of values to filter out , * onclick: [string, optional] string with javascript code that will be * evaluated when checkbox is clicked before filtering out the grid * (should not contain " (double quote) symbol), * callback: [function, optional] callback function reference used as * alternative way to display filter out list * }, * ... * ] * If "callback" property is defined, "container" and "onclick" properties * are ingnored. "onclick" is useful when some simple actions like function call * or alert should be done before filtering out the grid. If you need to do more * complex actions than the code that can be passed in the string, use * alternative way to display filter out list with callback function. * callback function receives following array of associative arrays: * [ * { * value: [string] the unique value from grid column, * onclick: [string] onclick attribute value of the corresponding checkbox, * checked: [boolean] true if this checkbox is checked, * link: [string] onclick attribute for the link to filter out all values * except this, * selectall: [string] onclick attribute for the link to unfilter out all * values (this property is defined only for the first value), * clearall: [string] onclick attribute for the link to filter out all * values (this property is defined only for the first value) * }, * ... * ] * No return value is needed. * * <b>totals</b> (requires zpgrid-aggregate.js module that is included by * default) [object] Array of associative arrays: * [ * { * column: [object or number, optional] array of zero-based column numbers * or single zero-based column number to calculate (passed to the function; * required for standard aggregate functions, optional for custom callback * function), * callback: [function, optional] callback function to calculate value * (see below) or one of standard static aggregate functions: * Zapatec.Grid.sum, Zapatec.Grid.avg, Zapatec.Grid.max, Zapatec.Grid.min, * Zapatec.Grid.count, Zapatec.Grid.countDistinct (default is * Zapatec.Grid.sum), * label: [string, optional] label for the value (passed to the function; * overrides standard label), * labelColumn: [number, optional] zero-based column number where to put * label (passed to the function; by default label is placed before the * value in the same cell) * }, * ... * ] * "callback" property is a callback function that calculates totals * using desired algorithm. It receives following object containing grid rows: * { * grid: [object] grid object, * rows: [object] array of row objects, * column: [object or number, optional] "column" property of "totals", * label: [string, optional] "label" property of "totals", * labelColumn: [string, optional] "labelColumn" property of "totals" * } * and should return following object containing one or several rows with * totals (number of cells should correspond to the number of grid fields): * { * rows: * [ * { * cells: * [ * { * v: [string] value to display, * style: [string, optional] table cell style attribute * }, * ... * ], * style: [string, optional] table row style attribute * }, * ... * ] * } * See {<span class="attrib">@link</span> Zapatec.Grid#sum} for example. * * <b>dataPrepared</b> [boolean] If true, grid will not attempt to check and * correct input data. External application is responsible for data preparation. * May be used with json source type to speed up large grid initialization. Data * must be prepared strictly according to grid internal format. * * <b>dataOnDemand</b> [boolean] If true, on every paging, sorting, filtering, * ranging, and search action grid instead of doing actual operation reloads * its data. It makes sence to use this option together with "callbackSource" * config option defined in Zapatec.Widget class. In this case grid passes to * callbackSource function following object: * { * currentPage: [number] zero-based current page number, * sortColumn: [number] zero-based column number on which grid is currently * sorted (deprecated, use order instead), * sortDesc: [boolean] true if grid is currently sorted in descending order * (deprecated, use order instead), * order: [object] array showing how the grid is currently sorted with * sorting priority from first to last element of the array, see * {<span class="attrib">@link</span> Zapatec.Grid#sort} method for more details about sorting: * [ * { * col: [number] zero-based column number, * desc: [boolean, optional] indicates descending order for this column, * lt: [number] 1 if desc, -1 otherwise, * gt: [number] -1 if desc, 1 otherwise * }, * ... * ] * filters: [object] array containing an object for each grid column: * [ * { * hiddenValues: [object] array of hidden values - rows conaining these * values in the column should not be displayed, * minValue: [any] rows containing values in the column lesser than this * value should not be displayed, * maxValue: [any] rows containing values in the column greater than this * value should not be displayed, * regexpFilter: [string, optional] rows where column value don't match * this regular expression should not be displayed, * textFilter: [string] rows which don't contain this pattern in the * column value should not be displayed * }, * ... * ] * } * and lets it to form the source, e.g. server URL, from which grid is reloaded * then. See {<span class="attrib">@link</span> Zapatec.Widget} for details. * * <b>fixedLeft</b> [number] Number of columns starting from the left that are * not moved during horizontal scrolling. * * <b>columnWidth</b> [string] Default column width. Should contain correct CSS * value, e.g. 'auto', '200px', etc. 'auto' must not be used with grids having * separate container for header. Default: 'auto' if headerContainer and * totalsContainer are not set, '100px' if headerContainer or totalsContainer is * set. * * <b>rowHeight</b> [string] Default row height. Should contain correct CSS * value, e.g. 'auto', '1.2em', etc. 'auto' must not be used with grids having * fixed columns. Default: 'auto'. * * <b>mouseSelect</b> [boolean or string] Allow selection of cells and rows * using left mouse button. Default: true. * * <b>dragAndDropCells</b> [boolean or string] Allow drag and drop cells using * left mouse button. Default: false. * Note: if this option is true, <b>mouseSelect</b> must be false. * * <b>dragAndDropColumns</b> [boolean or string] Allow drag and drop columns * using left mouse button. Default: false. * * <strong>In addition to events fired from base Zapatec.Widget class fires * following events:</strong> * * <b>gridInitialized</b> when grid initialization process is completed. * * <b>gridPrepareRefresh</b> before grid refresh is started. * * <b>gridRefreshed</b> when grid refresh is completed. * * <b>gridPrepareModify</b> before splice or query is started. * * <b>gridModified</b> when splice or query is completed. * * <b>gridPrepareFilter</b> before filtering is started. * * <b>gridFiltered</b> when filtering is completed. * * <b>gridResizedColumn</b> when standard output is used and column was resized * manually. Listener receives two arguments: column id and width increment in * pixels. Width increment can be negative. * * <b>gridMovedColumn</b> when column is moved. Listener receives following * argument: * { * fieldId: [number] zero-based id of the moved field, * position: [number] new zero-based column position * } * * <b>gridCellMousedown</b> when mouse down event occurs on the cell's td * element. Listener receives two arguments: row id and cell id. * </pre> * * <span class="attrib">@constructor</span> * <span class="attrib">@extends</span> Zapatec.Widget * <span class="attrib">@param</span> {object} oArg User configuration */</span> Zapatec.Grid = <span class="reserved">function</span>(oArg) { <span class="comment">// Call constructor of superclass</span> Zapatec.Grid.SUPERconstructor.call(<span class="reserved">this</span>, oArg); }; <span class="comment">/** * Unique static id of the widget class. Gives ability for Zapatec#inherit to * determine and store path to this file correctly when it is included using * Zapatec#include. When this file is included using Zapatec#include or path * to this file is gotten using Zapatec#getPath, this value must be specified * as script id. * <span class="attrib">@private</span> */</span> Zapatec.Grid.id = <span class="literal">'Zapatec.Grid'</span>; <span class="comment">// Inherit Widget</span> Zapatec.inherit(Zapatec.Grid, Zapatec.Widget); <span class="comment">/** * Initializes grid. * * <span class="attrib">@param</span> {object} oArg User configuration */</span> Zapatec.Grid.<span class="reserved">prototype</span>.init = <span class="reserved">function</span>(oArg) { <span class="comment">// Indicates that initialization process is completed</span> <span class="reserved">this</span>.initialized = false; <span class="comment">// Call parent method</span> Zapatec.Grid.SUPERclass.init.call(<span class="reserved">this</span>, oArg); var oConfig = <span class="reserved">this</span>.config; <span class="comment">// Holds grid data</span> <span class="reserved">this</span>.data = {}; <span class="comment">// Reference to fields array in data object</span> <span class="reserved">this</span>.fields = []; <span class="comment">// Reference to rows array in data object</span> <span class="reserved">this</span>.rows = []; <span class="comment">// Array where indexes are the same as row ids to reference grid rows by id</span> <span class="reserved">this</span>.rowsIndex = []; <span class="comment">// Holds filtered row objects</span> <span class="reserved">this</span>.filteredRows = []; <span class="comment">// Holds current page number</span> <span class="reserved">this</span>.currentPage = 0; <span class="comment">// Holds current frame for autoresize</span> <span class="reserved">this</span>.autoresizeFrame = { direction: 0, currentRow: 0, visibleRows: oConfig.rowsPerPage }; <span class="comment">// Holds current vertical offset on the page</span> <span class="reserved">this</span>.currentVerticalOffset = 0; <span class="comment">// Holds current horizontal offset on the page</span> <span class="reserved">this</span>.currentHorizontalOffset = 0; <span class="comment">// Holds sorting order</span> <span class="reserved">this</span>.order = []; <span class="comment">// Initially may be sorted on the specified column and in the specified order</span> <span class="comment">// null is object</span> <span class="reserved">if</span> (typeof oConfig.sortColumn != <span class="literal">'object'</span>) { <span class="reserved">this</span>.order.push({ col: oConfig.sortColumn * 1, desc: oConfig.sortDesc, lt: oConfig.sortDesc ? 1 : -1, gt: oConfig.sortDesc ? -1 : 1 }); } <span class="comment">// Object that holds last selection to be able to modify it</span> <span class="reserved">this</span>.lastSelection = null; <span class="comment">// Load data from the specified source</span> <span class="reserved">this</span>.loadData(); }; <span class="comment">/** * Reconfigures the grid with new config options after it was initialized. * May be used to change look or behavior of the grid after it has loaded * the data. In the argument pass only values for changed config options. * There is no need to pass config options that were not changed. * * <pre> * Note: "sortColumn" and "sortDesc" config options are ignored by this method * because they are useful only on initialization. To sort the grid after it was * initialized use sort method instead. * </pre> * * <span class="attrib">@param</span> {object} oArg Changes to user configuration */</span> Zapatec.Grid.<span class="reserved">prototype</span>.reconfigure = <span class="reserved">function</span>(oArg) { <span class="comment">// Call parent method</span> Zapatec.Grid.SUPERclass.reconfigure.call(<span class="reserved">this</span>, oArg); <span class="comment">// Redraw grid</span> <span class="reserved">this</span>.refresh(); }; <span class="comment">/** * Configures grid. Gets called from parent init method. * * <span class="attrib">@private</span> * <span class="attrib">@param</span> {object} oArg User configuration */</span> Zapatec.Grid.<span class="reserved">prototype</span>.configure = <span class="reserved">function</span>(oArg) { <span class="comment">// Define config options</span> <span class="reserved">this</span>.defineConfigOption(<span class="literal">'show_asis'</span>, false); <span class="reserved">this</span>.defineConfigOption(<span class="literal">'funcStyle'</span>); <span class="reserved">this</span>.defineConfigOption(<span class="literal">'convert'</span>); <span class="reserved">this</span>.defineConfigOption(<span class="literal">'container'</span>); <span class="reserved">this</span>.defineConfigOption(<span class="literal">'headerContainer'</span>); <span class="reserved">this</span>.defineConfigOption(<span class="literal">'totalsContainer'</span>); <span class="reserved">this</span>.defineConfigOption(<span class="literal">'visibleRows'</span>, 0); <span class="reserved">this</span>.defineConfigOption(<span class="literal">'visibleColumns'</span>, 0); <span class="reserved">this</span>.defineConfigOption(<span class="literal">'rowsPerPage'</span>, 0); <span class="reserved">this</span>.defineConfigOption(<span class="literal">'paginationContainer'</span>); <span class="reserved">this</span>.defineConfigOption(<span class="literal">'border'</span>); <span class="reserved">this</span>.defineConfigOption(<span class="literal">'fitIntoParent'</span>); <span class="reserved">this</span>.defineConfigOption(<span class="literal">'horizontal'</span>, false); <span class="reserved">this</span>.defineConfigOption(<span class="literal">'selectRows'</span>, true); <span class="reserved">this</span>.defineConfigOption(<span class="literal">'selectCells'</span>, true); <span class="reserved">this</span>.defineConfigOption(<span class="literal">'activeRows'</span>, true); <span class="reserved">this</span>.defineConfigOption(<span class="literal">'activeCells'</span>, true); <span class="reserved">this</span>.defineConfigOption(<span class="literal">'multipleSelect'</span>, true); <span class="reserved">this</span>.defineConfigOption(<span class="literal">'callbackHeaderDisplay'</span>); <span class="reserved">this</span>.defineConfigOption(<span class="literal">'callbackDataDisplay'</span>); <span class="reserved">this</span>.defineConfigOption(<span class="literal">'callbackRowDisplay'</span>); <span class="reserved">this</span>.defineConfigOption(<span class="literal">'callbackTotalsDisplay'</span>); <span class="reserved">this</span>.defineConfigOption(<span class="literal">'callbackTotalDisplay'</span>); <span class="reserved">this</span>.defineConfigOption(<span class="literal">'callbackPaginationDisplay'</span>); <span class="reserved">this</span>.defineConfigOption(<span class="literal">'callbackRowOnClick'</span>); <span class="reserved">this</span>.defineConfigOption(<span class="literal">'callbackRowOnRightClick'</span>); <span class="reserved">this</span>.defineConfigOption(<span class="literal">'callbackCellOnClick'</span>); <span class="reserved">this</span>.defineConfigOption(<span class="literal">'callbackCellOnRightClick'</span>); <span class="reserved">this</span>.defineConfigOption(<span class="literal">'callbackRowOnDblClick'</span>); <span class="reserved">this</span>.defineConfigOption(<span class="literal">'callbackCellOnDblClick'</span>); <span class="reserved">this</span>.defineConfigOption(<span class="literal">'callbackRowSelect'</span>); <span class="reserved">this</span>.defineConfigOption(<span class="literal">'callbackCellSelect'</span>); <span class="reserved">this</span>.defineConfigOption(<span class="literal">'callbackRowUnselect'</span>); <span class="reserved">this</span>.defineConfigOption(<span class="literal">'callbackCellUnselect'</span>); <span class="reserved">this</span>.defineConfigOption(<span class="literal">'callbackOnRefresh'</span>); <span class="reserved">this</span>.defineConfigOption(<span class="literal">'sortColumn'</span>); <span class="reserved">this</span>.defineConfigOption(<span class="literal">'sortDesc'</span>); <span class="reserved">this</span>.defineConfigOption(<span class="literal">'filterOut'</span>, []); <span class="reserved">this</span>.defineConfigOption(<span class="literal">'totals'</span>, []); <span class="reserved">this</span>.defineConfigOption(<span class="literal">'dataPrepared'</span>, false); <span class="reserved">this</span>.defineConfigOption(<span class="literal">'dataOnDemand'</span>, false); <span class="reserved">this</span>.defineConfigOption(<span class="literal">'fixedLeft'</span>, 0); <span class="reserved">this</span>.defineConfigOption(<span class="literal">'columnWidth'</span>, <span class="literal">'auto'</span>); <span class="reserved">this</span>.defineConfigOption(<span class="literal">'rowHeight'</span>, <span class="literal">'auto'</span>); <span class="reserved">this</span>.defineConfigOption(<span class="literal">'mouseSelect'</span>, true); <span class="reserved">this</span>.defineConfigOption(<span class="literal">'dragAndDropCells'</span>, false); <span class="reserved">this</span>.defineConfigOption(<span class="literal">'dragAndDropColumns'</span>, false); <span class="reserved">this</span>.defineConfigOption(<span class="literal">'langId'</span>, <span class="literal">'Zapatec.Grid'</span>); <span class="reserved">this</span>.defineConfigOption(<span class="literal">'lang'</span>, <span class="literal">'eng'</span>); <span class="comment">// Call parent method</span> Zapatec.Grid.SUPERclass.configure.call(<span class="reserved">this</span>, oArg); <span class="comment">// Correct config options</span> var fGetElById = Zapatec.Widget.getElementById; var fCorrectCssLength = Zapatec.Utils.correctCssLength; var oConfig = <span class="reserved">this</span>.config; <span class="comment">// Correct rowsPerPage config option</span> oConfig.rowsPerPage = parseInt(oConfig.rowsPerPage); <span class="reserved">if</span> (isNaN(oConfig.rowsPerPage)) { oConfig.rowsPerPage = 0; } <span class="comment">// Correct visibleRows config option</span> oConfig.visibleRows = parseInt(oConfig.visibleRows); <span class="reserved">if</span> (isNaN(oConfig.visibleRows)) { oConfig.visibleRows = 0; } <span class="comment">// Correct visibleColumns config option</span> oConfig.visibleColumns = parseInt(oConfig.visibleColumns); <span class="reserved">if</span> (isNaN(oConfig.visibleColumns)) { oConfig.visibleColumns = 0; } <span class="comment">// There is no sense to use dataOnDemand without rowsPerPage</span> <span class="reserved">if</span> (!oConfig.rowsPerPage) { oConfig.dataOnDemand = false; } <span class="comment">// Indicates that we are responsible for visualisation</span> <span class="reserved">this</span>.visualize = true; <span class="reserved">if</span> (typeof oConfig.callbackHeaderDisplay == <span class="literal">'function'</span> && (typeof oConfig.callbackRowDisplay == <span class="literal">'function'</span> || typeof oConfig.callbackDataDisplay == <span class="literal">'function'</span>)) { <span class="reserved">this</span>.visualize = false; <span class="comment">// Prevent displaying of "Theme not found" message</span> oConfig.theme = <span class="literal">''</span>; } <span class="comment">// Grid container</span> <span class="reserved">this</span>.container = fGetElById(oConfig.container); <span class="comment">// Grid header container</span> <span class="reserved">this</span>.headerContainer = fGetElById(oConfig.headerContainer); <span class="comment">// Grid totals container</span> <span class="reserved">this</span>.totalsContainer = fGetElById(oConfig.totalsContainer); <span class="comment">// Grid pagination containers array</span> <span class="reserved">this</span>.paginationContainers = []; var vPagCont = oConfig.paginationContainer; <span class="reserved">if</span> (typeof vPagCont != <span class="literal">'undefined'</span>) { <span class="reserved">if</span> (vPagCont instanceof Array) { var aPagCont = <span class="reserved">this</span>.paginationContainers; var iEls = vPagCont.length; var iEl, oEl; <span class="reserved">for</span> (iEl = 0; iEls--; iEl++) { oEl = fGetElById(vPagCont[iEl]); <span class="reserved">if</span> (oEl) { aPagCont.push(oEl); } } } <span class="reserved">else</span> { var oEl = fGetElById(vPagCont); <span class="reserved">if</span> (oEl) { <span class="reserved">this</span>.paginationContainers.push(oEl); } } } <span class="comment">// Grid border element</span> <span class="reserved">this</span>.border = fGetElById(oConfig.border); <span class="reserved">if</span> (!<span class="reserved">this</span>.border && <span class="reserved">this</span>.container) { <span class="comment">// Assume border is parent node of the container</span> <span class="reserved">this</span>.border = <span class="reserved">this</span>.container.parentNode; } <span class="comment">// Element to fit into</span> <span class="reserved">this</span>.fitInto = null; <span class="reserved">if</span> (<span class="reserved">this</span>.border) { <span class="reserved">if</span> (typeof oConfig.fitIntoParent == <span class="literal">'boolean'</span>) { <span class="reserved">if</span> (oConfig.fitIntoParent) { <span class="reserved">this</span>.fitInto = <span class="reserved">this</span>.border.parentNode; } } <span class="reserved">else</span> { <span class="reserved">this</span>.fitInto = fGetElById(oConfig.fitIntoParent); } } <span class="comment">// Adjust number of rows per page to fit into specified container</span> <span class="reserved">if</span> (<span class="reserved">this</span>.fitInto && typeof <span class="reserved">this</span>.autoresize == <span class="literal">'function'</span>) { <span class="reserved">this</span>.addEventListener(<span class="literal">'gridRefreshed'</span>, <span class="reserved">this</span>.autoresize); <span class="reserved">this</span>.addEventListener(<span class="literal">'gridResizedColumn'</span>, <span class="reserved">this</span>.autoresize); } <span class="comment">// Correct columnWidth config option</span> oConfig.columnWidth = fCorrectCssLength(oConfig.columnWidth); <span class="reserved">if</span> (oConfig.columnWidth == <span class="literal">'auto'</span> && (<span class="reserved">this</span>.headerContainer || <span class="reserved">this</span>.totalsContainer)) { oConfig.columnWidth = <span class="literal">'100px'</span>; } <span class="comment">// Correct rowHeight config option</span> oConfig.rowHeight = fCorrectCssLength(oConfig.rowHeight); <span class="comment">// Setup mouse selection</span> <span class="reserved">if</span> (oConfig.mouseSelect && <span class="reserved">this</span>.mouseSelect) { <span class="reserved">this</span>.addEventListener(<span class="literal">'gridCellMousedown'</span>, <span class="reserved">this</span>.mouseSelect); } <span class="comment">// Setup cell dragging</span> <span class="reserved">if</span> (oConfig.dragAndDropCells && <span class="reserved">this</span>.dragCell) { <span class="reserved">this</span>.addEventListener(<span class="literal">'gridCellMousedown'</span>, <span class="reserved">this</span>.dragCell); } <span class="comment">// Setup column dragging</span> <span class="reserved">if</span> (oConfig.dragAndDropColumns && <span class="reserved">this</span>.dragColumn) { <span class="reserved">this</span>.addEventListener(<span class="literal">'gridFieldMousedown'</span>, <span class="reserved">this</span>.dragColumn); } <span class="comment">// Setup right mouse click callbacks</span> <span class="reserved">if</span> (typeof oConfig.callbackCellOnRightClick == <span class="literal">'function'</span> || typeof oConfig.callbackRowOnRightClick == <span class="literal">'function'</span>) { <span class="comment">// Disable context menu</span> window.document.oncontextmenu = <span class="reserved">function</span>() {<span class="reserved">return</span> false}; <span class="comment">// Add event listener to mouseup event to be able to get button number</span> <span class="reserved">this</span>.addEventListener(<span class="literal">'gridCellMouseup'</span>, Zapatec.Grid.onCellMouseup); } <span class="comment">// Filter out rules</span> <span class="reserved">this</span>.filterOutRules = oConfig.filterOut; <span class="reserved">if</span> (!(<span class="reserved">this</span>.filterOutRules instanceof Array)) { <span class="reserved">this</span>.filterOutRules = []; } <span class="comment">// Totals rules</span> <span class="reserved">this</span>.totalsRules = oConfig.totals; <span class="reserved">if</span> (!(<span class="reserved">this</span>.totalsRules instanceof Array)) { <span class="reserved">this</span>.totalsRules = []; } }; <span class="comment">/** * Extends parent method. * <span class="attrib">@private</span> */</span> Zapatec.Grid.<span class="reserved">prototype</span>.addStandardEventListeners = <span class="reserved">function</span>() { <span class="comment">// Call parent method</span> Zapatec.Grid.SUPERclass.addStandardEventListeners.call(<span class="reserved">this</span>); <span class="comment">// Add grid specific event listeners</span> <span class="reserved">this</span>.addEventListener(<span class="literal">'fetchSourceError'</span>, <span class="reserved">this</span>.displayErrorSource); <span class="comment">// If zpgrid-output.js is loaded</span> <span class="reserved">if</span> (<span class="reserved">this</span>.displayLoading) { <span class="reserved">this</span>.addEventListener(<span class="literal">'fetchSourceStart'</span>, <span class="reserved">this</span>.displayLoading); <span class="reserved">this</span>.addEventListener(<span class="literal">'fetchSourceEnd'</span>, <span class="reserved">this</span>.removeLoading); <span class="reserved">this</span>.addEventListener(<span class="literal">'loadThemeEnd'</span>, <span class="reserved">this</span>.visualizeThemeLoad); <span class="reserved">this</span>.addEventListener(<span class="literal">'loadDataEnd'</span>, <span class="reserved">this</span>.visualizeDataLoad); } }; <span class="comment">/** * Displays error when external source is malformed. * <span class="attrib">@private</span> */</span> Zapatec.Grid.<span class="reserved">prototype</span>.displayErrorSource = <span class="reserved">function</span>(oError) { alert(<span class="reserved">this</span>.getMessage(<span class="literal">'errorSource'</span>, <span class="reserved">this</span>.config.source, oError.errorDescription)); }; <span class="comment">/** * Reloads data from the specified source after grid is initialized. Argument * should be passed only when dataOnDemand config option is true and * callbackSource config option is defined. See description of dataOnDemand * config option for details. * * <span class="attrib">@param</span> {object} oArg Optional. Argument object */</span> Zapatec.Grid.<span class="reserved">prototype</span>.loadData = <span class="reserved">function</span>(oArg) { <span class="comment">// Form argument for server side</span> <span class="reserved">if</span> (<span class="reserved">this</span>.config.dataOnDemand) { <span class="reserved">if</span> (typeof oArg != <span class="literal">'object'</span>) { oArg = {}; } oArg.currentPage = <span class="reserved">this</span>.currentPage; <span class="reserved">if</span> (<span class="reserved">this</span>.order.length) { oArg.sortColumn = <span class="reserved">this</span>.order[0].col; oArg.sortDesc = <span class="reserved">this</span>.order[0].desc; oArg.order = <span class="reserved">this</span>.order; } oArg.filters = []; <span class="reserved">for</span> (var iCol = 0; iCol < <span class="reserved">this</span>.fields.length; iCol++) { var oField = <span class="reserved">this</span>.fields[iCol]; <span class="reserved">if</span> (oField) { oArg.filters[iCol] = { hiddenValues: oField.hiddenValues, minValue: oField.minValue, maxValue: oField.maxValue, regexpFilter: oField.regexpFilter, textFilter: oField.textFilter }; } <span class="reserved">else</span> { oArg.filters[iCol] = {}; } } } <span class="comment">// Call parent method</span> Zapatec.Grid.SUPERclass.loadData.call(<span class="reserved">this</span>, oArg); }; <span class="comment">/** * Performs some actions when grid is refreshed. * <span class="attrib">@private</span> */</span> Zapatec.Grid.<span class="reserved">prototype</span>.onRefresh = <span class="reserved">function</span>() { <span class="comment">// Several refresh processes may run simultaneously.</span> <span class="reserved">if</span> (<span class="reserved">this</span>.refreshState > 1) { <span class="reserved">this</span>.refreshState--; <span class="reserved">return</span>; } <span class="comment">// If we are responsible for visualisation</span> <span class="reserved">if</span> (<span class="reserved">this</span>.visualizeRefresh && <span class="reserved">this</span>.visualize) { <span class="reserved">this</span>.visualizeRefresh(); } <span class="comment">// Indicates number of running refresh processes</span> <span class="reserved">this</span>.refreshState--; <span class="comment">// Onrefresh callback (deprecated)</span> <span class="reserved">if</span> (typeof <span class="reserved">this</span>.config.callbackOnRefresh == <span class="literal">'function'</span>) { <span class="reserved">this</span>.config.callbackOnRefresh(<span class="reserved">this</span>); } <span class="comment">// Fire event</span> <span class="reserved">this</span>.fireEvent(<span class="literal">'gridRefreshed'</span>); }; <span class="comment">/** * Loads data from the JSON source. * * <span class="attrib">@private</span> * <span class="attrib">@param</span> {object} oData Input data object */</span> Zapatec.Grid.<span class="reserved">prototype</span>.loadDataJson = <span class="reserved">function</span>(oData) { <span class="comment">// Remove index</span> <span class="reserved">this</span>.rowsIndex = null; <span class="comment">// Get data</span> <span class="reserved">if</span> (!(oData instanceof Object)) { oData = {}; } <span class="reserved">if</span> (!(oData.fields instanceof Array)) { oData.fields = []; } <span class="reserved">if</span> (!(oData.rows instanceof Array)) { oData.rows = []; } <span class="reserved">this</span>.data = oData; <span class="comment">// References</span> <span class="reserved">this</span>.fields = oData.fields; <span class="reserved">this</span>.rows = oData.rows; <span class="comment">// Check and correct input data</span> <span class="reserved">if</span> (!<span class="reserved">this</span>.config.dataPrepared) { <span class="reserved">this</span>.prepareData(); } <span class="comment">// Duplicate rows array</span> <span class="reserved">this</span>.rowsIndex = <span class="reserved">this</span>.rows.slice(); <span class="comment">// Build primary key</span> <span class="reserved">this</span>.primaryKeyColumn = oData.primaryKey; <span class="reserved">this</span>.buildPrimaryKey(); <span class="comment">// Set page</span> <span class="reserved">if</span> (typeof oData.currentPage != <span class="literal">'undefined'</span>) { <span class="reserved">this</span>.setCurrentPage(oData.currentPage); } <span class="reserved">else</span> { <span class="reserved">this</span>.setCurrentPage(0); } <span class="comment">// Show grid</span> <span class="reserved">this</span>.show(); }; <span class="comment">/** * Builds primary key. * <span class="attrib">@private</span> */</span> Zapatec.Grid.<span class="reserved">prototype</span>.buildPrimaryKey = <span class="reserved">function</span>() { var iKey = <span class="reserved">this</span>.primaryKeyColumn; <span class="reserved">if</span> (!<span class="reserved">this</span>.fields[iKey]) { <span class="reserved">this</span>.primaryKey = null; <span class="reserved">return</span>; } <span class="reserved">this</span>.primaryKey = {}; var oKey = <span class="reserved">this</span>.primaryKey; var aRows = <span class="reserved">this</span>.rows; var iRows = aRows.length; var iRow, sKey; <span class="reserved">for</span> (iRow = 0; iRow < iRows; iRow++) { sKey = <span class="reserved">this</span>.getCellValueCompare(<span class="reserved">this</span>.getCellByRow(aRows[iRow], iKey)); <span class="reserved">if</span> ((typeof sKey == <span class="literal">'string'</span> && sKey.length) || typeof sKey == <span class="literal">'number'</span>) { oKey[sKey] = aRows[iRow]; } } }; <span class="comment">/** * Rebuilds primary key. * <span class="attrib">@private</span> */</span> Zapatec.Grid.<span class="reserved">prototype</span>.rebuildPrimaryKey = <span class="reserved">function</span>() { <span class="reserved">if</span> (<span class="reserved">this</span>.primaryKey) { <span class="reserved">this</span>.buildPrimaryKey(); } }; <span class="comment">/** * Displays grid after data loading. * <span class="attrib">@private</span> */</span> Zapatec.Grid.<span class="reserved">prototype</span>.show = <span class="reserved">function</span>() { <span class="comment">// Duplicate rows array</span> <span class="reserved">this</span>.filteredRows = <span class="reserved">this</span>.rows.slice(); <span class="comment">// Sort if needed</span> <span class="reserved">this</span>.sort(); <span class="comment">// Display grid</span> <span class="reserved">this</span>.refresh(); <span class="comment">// Display filter out forms</span> <span class="reserved">this</span>.displayFilterOut(); <span class="comment">// Fire event</span> <span class="reserved">if</span> (!<span class="reserved">this</span>.initialized) { <span class="reserved">this</span>.initialized = true; <span class="reserved">this</span>.fireEvent(<span class="literal">'gridInitialized'</span>); } }; <span class="comment">/** * Checks if all required properties of input object are defined. Defines missed * properties. * <span class="attrib">@private</span> */</span> Zapatec.Grid.<span class="reserved">prototype</span>.prepareData = <span class="reserved">function</span>() { <span class="comment">// Prepare fields</span> var aItems = <span class="reserved">this</span>.fields; var iItems = aItems.length; var iItem, oItem; <span class="reserved">for</span> (iItem = 0; iItem < iItems; iItem++) { oItem = aItems[iItem]; <span class="reserved">if</span> (!(oItem instanceof Object)) { oItem = {}; } oItem.i = iItem; aItems[iItem] = <span class="reserved">this</span>.prepareField(oItem); } <span class="comment">// Prepare spans</span> aItems = <span class="reserved">this</span>.rows; <span class="reserved">this</span>.prepareSpans(aItems); <span class="comment">// Prepare rows</span> iItems = aItems.length; <span class="reserved">for</span> (iItem = 0; iItem < iItems; iItem++) { oItem = aItems[iItem]; <span class="reserved">if</span> (!(oItem instanceof Object)) { oItem = {}; } oItem.i = iItem; aItems[iItem] = <span class="reserved">this</span>.prepareRow(oItem); } }; <span class="comment">/** * Checks if all required properties of the field object are defined. Defines * missed properties. * * <span class="attrib">@private</span> * <span class="attrib">@param</span> {object} oField Field object * <span class="attrib">@return</span> Prepared field object * <span class="attrib">@type</span> {object} */</span> Zapatec.Grid.<span class="reserved">prototype</span>.prepareField = <span class="reserved">function</span>(oField) { <span class="reserved">return</span> oField; }; <span class="comment">/** * Checks if all required properties of the row object are defined. Defines * missed properties. * * <span class="attrib">@private</span> * <span class="attrib">@param</span> {object} oRow Row object * <span class="attrib">@return</span> Prepared row object * <span class="attrib">@type</span> {object} */</span> Zapatec.Grid.<span class="reserved">prototype</span>.prepareRow = <span class="reserved">function</span>(oRow) { <span class="reserved">if</span> (!oRow.cells || !(oRow.cells instanceof Array)) { oRow.cells = []; } <span class="comment">// Prepare cells</span> var aCells = oRow.cells; var iColumns = <span class="reserved">this</span>.fields.length; var iCol, oCell; <span class="reserved">for</span> (iCol = 0; iCol < iColumns; iCol++) { <span class="comment">// Get cell</span> oCell = aCells[iCol]; <span class="reserved">if</span> (!(oCell instanceof Object)) { oCell = {}; } <span class="comment">// Assign column number</span> oCell.i = iCol; <span class="comment">// In the rowspan the same cell object is shared among several rows</span> <span class="reserved">if</span> (!(oCell.rowspan > 0 && typeof oCell.r != <span class="literal">'undefined'</span>)) { <span class="comment">// Assign row number</span> oCell.r = oRow.i; } <span class="comment">// Convert</span> aCells[iCol] = <span class="reserved">this</span>.convertCell(oCell); <span class="comment">// Skip spanned cells</span> <span class="reserved">if</span> (oCell.colspan > 1) { iCol += oCell.colspan - 1; } } <span class="reserved">return</span> oRow; }; <span class="comment">/** * Converts cell to corresponding data type. * * <span class="attrib">@private</span> * <span class="attrib">@param</span> {object} oCell Cell object * <span class="attrib">@return</span> Converted cell object * <span class="attrib">@type</span> object */</span> Zapatec.Grid.<span class="reserved">prototype</span>.convertCell = <span class="reserved">function</span>(oCell) { <span class="reserved">return</span> <span class="reserved">this</span>.convertCellByField(<span class="reserved">this</span>.getFieldByCell(oCell), oCell); }; <span class="comment">/** * Converts cell to corresponding data type of the field. * * <span class="attrib">@private</span> * <span class="attrib">@param</span> {object} oCell Cell object * <span class="attrib">@return</span> Converted cell object * <span class="attrib">@type</span> object */</span> Zapatec.Grid.<span class="reserved">prototype</span>.convertCellByField = <span class="reserved">function</span>(oField, oCell) { <span class="reserved">if</span> (!(oCell instanceof Object)) { oCell = {}; } <span class="comment">// Convert by type</span> <span class="reserved">if</span> (oField && <span class="reserved">this</span>.getConvertByType) { var sMethod = <span class="reserved">this</span>.getConvertByType(oField.dataType); <span class="reserved">if</span> (sMethod) { oCell = <span class="reserved">this</span>[sMethod](oCell); } } <span class="comment">// Custom convert</span> oCell = <span class="reserved">this</span>.convertCellCallback(oCell); <span class="reserved">return</span> oCell; }; <span class="comment">/** * Converts cell using callback function. * * <span class="attrib">@private</span> * <span class="attrib">@param</span> {object} oCell Cell object * <span class="attrib">@return</span> Converted cell object * <span class="attrib">@type</span> object */</span> Zapatec.Grid.<span class="reserved">prototype</span>.convertCellCallback = <span class="reserved">function</span>(oCell) { <span class="reserved">if</span> (!(oCell instanceof Object)) { oCell = {}; } <span class="reserved">if</span> (typeof <span class="reserved">this</span>.config.convert == <span class="literal">'function'</span>) { var convertedValue = <span class="reserved">this</span>.config.convert(<span class="reserved">this</span>, oCell); <span class="reserved">if</span> (typeof convertedValue != <span class="literal">'undefined'</span>) { <span class="reserved">if</span> (typeof oCell.o == <span class="literal">'undefined'</span>) { oCell.o = oCell.v; } oCell.v = oCell.c = convertedValue; } } <span class="reserved">return</span> oCell; }; <span class="comment">/** * Validates cell according to its data type. If value is invalid, sets * "invalid" cell property to true. * * <span class="attrib">@private</span> * <span class="attrib">@param</span> {object} oCell Cell object * <span class="attrib">@return</span> True if valid * <span class="attrib">@type</span> boolean */</span> Zapatec.Grid.<span class="reserved">prototype</span>.validateCell = <span class="reserved">function</span>(oCell) { <span class="reserved">if</span> (!(oCell instanceof Object)) { oCell = {}; } <span class="comment">// Validate by type</span> <span class="reserved">if</span> (<span class="reserved">this</span>.getValidateByType) { var oField = <span class="reserved">this</span>.getFieldByCell(oCell); <span class="reserved">if</span> (oField) { var sMethod = <span class="reserved">this</span>.getValidateByType(oField.dataType); <span class="reserved">if</span> (sMethod) { var undef; <span class="comment">// Valid by default</span> <span class="reserved">if</span> (oCell.invalid) { oCell.invalid = undef; } <span class="comment">// Validate</span> var bValid = <span class="reserved">this</span>[sMethod](oCell); <span class="reserved">if</span> (!bValid) { oCell.invalid = true; } <span class="comment">// Validate row</span> var oRow = <span class="reserved">this</span>.getRowByCell(oCell); <span class="reserved">if</span> (oRow) { <span class="reserved">if</span> (!bValid) { oRow.invalid = true; } <span class="reserved">else</span> { <span class="comment">// Valid by default</span> <span class="reserved">if</span> (oRow.invalid) { oRow.invalid = undef; } <span class="comment">// Validate</span> var aCells = <span class="reserved">this</span>.getRowCells(oRow); <span class="reserved">for</span> (var iCell = 0; iCell < aCells.length; iCell++) { <span class="reserved">if</span> (aCells[iCell] && aCells[iCell].invalid) { oRow.invalid = true; break; } } } } <span class="reserved">return</span> bValid; } } } <span class="comment">// Default is true</span> <span class="reserved">return</span> true; }; <span class="comment">/** * Changes the content of the grid, replacing, adding or removing rows. * * <pre> * Input object format: * * { * atKey: [string, optional] primary key value at which to start * changing the grid, * atRowId: [number, optional] id of row at which to start changing the grid, * atRow: [number, optional, private] index of row in rows array at which to * start changing the grid, * afterKey: [string, optional] primary key value after which to start * changing the grid, * afterRowId: [number, optional] id of row after which to start changing * the grid, * afterRow: [number, optional, private] index of row in rows array after * which to start changing the grid, * howMany: [number, optional] number of rows to replace or remove * (default is 0), * rows: [object, optional] array of rows to add: * [ * { * cells: * [ * { * v: [any] cell value to display, * c: [any, optional] cell value to compare, * o: [any, optional] original cell value, * style: [string, optional] table cell style attribute * }, * ... * ], * style: [string, optional] table row style attribute * }, * ... * ], * noRefresh: [boolean, optional] indicates that grid should not be refreshed * after changing (default is false) (useful when several changes go one by * one) * } * * Only one of "atKey", "atRowId", "atRow", "afterKey", "afterRowId" and * "afterRow" properties should be defined. If none of them is defined, new rows * will be added to the end of grid. * * Several input objects can be passed in an array. This is useful when several * changes must be done simultaneously. * * If several objects are passed in an array, "noRefresh" property is ignored * for all objects except the last. * </pre> * * <span class="attrib">@param</span> {object} aData Array of objects or single object in above shown format * <span class="attrib">@return</span> Array with replaced or removed row objects. Number of replaced or * removed rows can be accessed through the length property of this array. If * error occured, returns undefined. * <span class="attrib">@type</span> object */</span> Zapatec.Grid.<span class="reserved">prototype</span>.splice = <span class="reserved">function</span>(aData) { <span class="comment">// Check arguments</span> <span class="reserved">if</span> (!aData) { <span class="reserved">return</span>; } <span class="reserved">if</span> (!(aData instanceof Array)) { aData = [aData]; } <span class="comment">// Fire event</span> <span class="reserved">this</span>.fireEvent(<span class="literal">'gridPrepareModify'</span>); <span class="comment">// Will hold removed rows</span> var aRemoved = []; <span class="comment">// Process arguments</span> var iDataLen = aData.length; var oData; <span class="reserved">for</span> (var iData = 0; iData < iDataLen; iData++) { <span class="comment">// Get arguments</span> oData = aData[iData]; <span class="comment">// Get insert position</span> var iInsertPos = null; <span class="comment">// Transform primary key into id</span> <span class="reserved">if</span> (typeof oData.atKey != <span class="literal">'undefined'</span>) { var iRowId = <span class="reserved">this</span>.getRowIdByPrimaryKey(oData.atKey); <span class="reserved">if</span> (typeof iRowId != <span class="literal">'undefined'</span>) { oData.atRowId = iRowId; } } <span class="comment">// Find row number by id</span> <span class="reserved">if</span> ((typeof oData.atRowId == <span class="literal">'string'</span> && oData.atRowId.length) || typeof oData.atRowId == <span class="literal">'number'</span>) { iInsertPos = <span class="reserved">this</span>.getRowIndexById(oData.atRowId); } <span class="reserved">if</span> (typeof iInsertPos != <span class="literal">'number'</span>) { <span class="reserved">if</span> ((typeof oData.atRow == <span class="literal">'string'</span> && oData.atRow.length) || typeof oData.atRow == <span class="literal">'number'</span>) { var iRowNum = oData.atRow * 1; <span class="reserved">if</span> (typeof <span class="reserved">this</span>.rows[iRowNum] != <span class="literal">'undefined'</span>) { <span class="comment">// Before specified row</span> iInsertPos = iRowNum; } } } <span class="reserved">if</span> (typeof iInsertPos != <span class="literal">'number'</span>) { <span class="comment">// Transform primary key into id</span> <span class="reserved">if</span> (typeof oData.afterKey != <span class="literal">'undefined'</span>) { var iRowId = <span class="reserved">this</span>.getRowIdByPrimaryKey(oData.afterKey); <span class="reserved">if</span> (typeof iRowId != <span class="literal">'undefined'</span>) { oData.afterRowId = iRowId; } } <span class="comment">// Find row number by id</span> <span class="reserved">if</span> ((typeof oData.afterRowId == <span class="literal">'string'</span> && oData.afterRowId.length) || typeof oData.afterRowId == <span class="literal">'number'</span>) { iInsertPos = <span class="reserved">this</span>.getRowIndexById(oData.afterRowId); <span class="reserved">if</span> (typeof iInsertPos == <span class="literal">'number'</span>) { iInsertPos++; } } } <span class="reserved">if</span> (typeof iInsertPos != <span class="literal">'number'</span>) { <span class="reserved">if</span> ((typeof oData.afterRow == <span class="literal">'string'</span> && oData.afterRow.length) || typeof oData.afterRow == <span class="literal">'number'</span>) { var iRowNum = oData.afterRow * 1; <span class="reserved">if</span> (typeof <span class="reserved">this</span>.rows[iRowNum] != <span class="literal">'undefined'</span>) { <span class="comment">// After specified row</span> iInsertPos = iRowNum + 1; } } } <span class="comment">// Default is end of the grid</span> <span class="reserved">if</span> (typeof iInsertPos != <span class="literal">'number'</span>) { iInsertPos = <span class="reserved">this</span>.rows.length; } <span class="comment">// Correct rows argument</span> <span class="reserved">if</span> (!(oData.rows instanceof Array)) { oData.rows = []; } <span class="comment">// Correct howMany argument</span> var iHowManyToRemove = parseInt(oData.howMany); <span class="reserved">if</span> (isNaN(iHowManyToRemove)) { iHowManyToRemove = 0; } <span class="comment">// Prevent rebuilding of primary key after each remove</span> var oPrimaryKey = <span class="reserved">this</span>.primaryKey; <span class="reserved">this</span>.primaryKey = null; <span class="comment">// Indicates that primay key must be rebuilt</span> var bRebuildPrimaryKey = false; <span class="comment">// Update rows</span> var iRow = 0; var iRemoved = 0; <span class="reserved">while</span> (iRemoved < iHowManyToRemove && iRow < oData.rows.length) { var oGridRow = <span class="reserved">this</span>.rows[iInsertPos]; <span class="reserved">if</span> (typeof oGridRow == <span class="literal">'undefined'</span>) { <span class="comment">// Trying to remove more rows than there are in the grid</span> break; } <span class="comment">// Save old row object</span> aRemoved.push(Zapatec.Utils.clone(oGridRow)); <span class="comment">// Replace row</span> var oRow = <span class="reserved">this</span>.prepareRow(oData.rows[iRow]); <span class="comment">// Replace row cells</span> <span class="reserved">for</span> (var iCol = 0; iCol < oGridRow.cells.length; iCol++) { <span class="comment">// Get cell</span> var oCell = oRow.cells[iCol]; <span class="reserved">if</span> (!oCell) { continue; } var oGridCell = oGridRow.cells[iCol]; <span class="comment">// Check if primary key value has changed</span> <span class="reserved">if</span> (<span class="reserved">this</span>.primaryKeyColumn == iCol && oGridCell.c != oCell.c) { bRebuildPrimaryKey = true; } <span class="comment">// Replace cell values</span> oGridCell.v = oCell.v; oGridCell.c = oCell.c; oGridCell.o = oCell.o; <span class="comment">// Replace cell style</span> oGridCell.style = oCell.style; } <span class="comment">// Replace row style</span> oGridRow.style = oRow.style; <span class="comment">// Next row</span> iInsertPos++; iRow++; iRemoved++; } <span class="comment">// Delete rows</span> <span class="reserved">for</span> (; iRemoved < iHowManyToRemove; iRemoved++) { <span class="reserved">if</span> (typeof <span class="reserved">this</span>.rows[iInsertPos] == <span class="literal">'undefined'</span>) { <span class="comment">// Trying to remove more rows than there are in the grid</span> break; } var oRow = <span class="reserved">this</span>.removeRow(iInsertPos); <span class="reserved">if</span> (oRow) { aRemoved.push(oRow); } <span class="comment">// Will need to rebuild primary key</span> bRebuildPrimaryKey = true; } <span class="comment">// Insert rows</span> <span class="reserved">for</span> (; iRow < oData.rows.length; iRow++) { var oRow = oData.rows[iRow]; oRow.i = <span class="reserved">this</span>.rowsIndex.length; oRow = <span class="reserved">this</span>.prepareRow(oRow); <span class="comment">// Insert row</span> <span class="reserved">this</span>.rows.splice(iInsertPos++, 0, oRow); <span class="reserved">this</span>.rowsIndex.push(oRow); <span class="comment">// Will need to rebuild primary key</span> bRebuildPrimaryKey = true; } <span class="comment">// Rebuild or restore primary key</span> <span class="reserved">if</span> (bRebuildPrimaryKey) { oPrimaryKey = null; <span class="comment">// Rebuild</span> <span class="reserved">this</span>.buildPrimaryKey(); } <span class="reserved">else</span> { <span class="comment">// Restore</span> <span class="reserved">this</span>.primaryKey = oPrimaryKey; oPrimaryKey = null; } } <span class="comment">// Show updates</span> <span class="reserved">if</span> (!oData.noRefresh) { <span class="reserved">this</span>.modify(); } <span class="comment">// Return removed rows</span> <span class="reserved">return</span> aRemoved; }; <span class="comment">/** * Removes specified row from the grid. * * <span class="attrib">@private</span> * <span class="attrib">@param</span> {number} iRow Row index in rows array * <span class="attrib">@return</span> Removed row * <span class="attrib">@type</span> object */</span> Zapatec.Grid.<span class="reserved">prototype</span>.removeRow = <span class="reserved">function</span>(iRow) { var oRow = <span class="reserved">this</span>.rows[iRow]; <span class="reserved">if</span> (!oRow) { <span class="reserved">return</span>; } var undef; <span class="reserved">this</span>.rowsIndex[oRow.i] = undef; var aRows = <span class="reserved">this</span>.rows.splice(iRow, 1); <span class="reserved">this</span>.rebuildPrimaryKey(); <span class="reserved">return</span> aRows[0]; }; <span class="comment">/** * Changes the content of the grid, replacing, adding or removing columns. * * <pre> * Input object format: * { * atColumnId: [number, optional] id of column at which to start changing * the grid, * afterColumnId: [number, optional] id of column after which to start * changing the grid, * howMany: [number, optional] number of columns to replace or remove * (default is 0), * fields: * [ * { * i: [number] zero-based column number, <b>dataPrepared</b> specific, * title: [string, optional] column title, * dataType: [string, optional] defines which standard or custom data type * to use for cell conversion (if not specified, no conversion is done), * columnWidth: [string, optional] column width, e.g. "10px", "10em", * style: [string, optional] header table cell style attribute, * ... * }, * ... * ], * rows: * [ * { * cells: * [ * { * v: [any] cell value to display, * c: [any, optional] cell value to compare, * o: [any, optional] original cell value, * style: [string, optional] table cell style attribute, * ... * }, * ... * ] * }, * ... * ], * noRefresh: [boolean, optional] indicates that grid should not be refreshed * after changing (default is false) (useful when several changes go one by * one) * } * * Only one of "atColumnId" and "afterColumnId" properties should be defined. If * none of them is defined, new columns will be added to the end of the grid. * * Several input objects can be passed in an array. This is useful when several * changes must be done simultaneously. * * If several objects are passed in an array, "noRefresh" property is ignored * for all objects except the last. * </pre> * * <span class="attrib">@param</span> {object} aData Array of objects or single object in above shown format * <span class="attrib">@return</span> Number of deleted columns. * <span class="attrib">@type</span> number */</span> Zapatec.Grid.<span class="reserved">prototype</span>.spliceColumns = <span class="reserved">function</span>(aData) { <span class="comment">// Check arguments</span> <span class="reserved">if</span> (!aData) { <span class="reserved">return</span> 0; } <span class="comment">// Fire event</span> <span class="reserved">this</span>.fireEvent(<span class="literal">'gridPrepareModify'</span>); <span class="comment">// Process arguments</span> var aFields = <span class="reserved">this</span>.fields; var iFields = aFields.length; var aRows = <span class="reserved">this</span>.rows; var iRows = aRows.length; var iPrimaryKey = <span class="reserved">this</span>.primaryKeyColumn; var bRebuildPrimaryKey = false; <span class="reserved">if</span> (!(aData instanceof Array)) { aData = [aData]; } var iRemoved = 0; var iDataLen = aData.length; var iData, oData, iInsertPos, iHowManyToRemove, aSpliceArgs, aColumns, iColumns, aRemoved, aUpdates, iRow, aCells, oUpdates, aNewCells; <span class="reserved">for</span> (iData = 0; iData < iDataLen; iData++) { <span class="comment">// Get arguments</span> oData = aData[iData]; <span class="comment">// Get insert position</span> iInsertPos = parseInt(oData.atColumnId); <span class="reserved">if</span> (isNaN(iInsertPos)) { iInsertPos = parseInt(oData.afterColumnId); <span class="reserved">if</span> (!isNaN(iInsertPos)) { iInsertPos++; } <span class="reserved">else</span> { <span class="comment">// Default is after last column</span> iInsertPos = iFields; } } <span class="comment">// Correct howMany argument</span> iHowManyToRemove = parseInt(oData.howMany); <span class="reserved">if</span> (isNaN(iHowManyToRemove)) { iHowManyToRemove = 0; } <span class="comment">// Arguments for splice method</span> aSpliceArgs = [iInsertPos, iHowManyToRemove]; <span class="comment">// Replace fields</span> aColumns = oData.fields; <span class="reserved">if</span> (!(aColumns instanceof Array)) { aColumns = [aColumns]; } iColumns = aColumns.length; aRemoved = aFields.splice.apply(aFields, aSpliceArgs.concat(aColumns)); <span class="reserved">if</span> (aRemoved && aRemoved.length) { iRemoved += aRemoved.length; } <span class="comment">// Change rows</span> aUpdates = oData.rows; <span class="reserved">if</span> (!(aUpdates instanceof Array)) { aUpdates = []; } <span class="reserved">for</span> (iRow = 0; iRow < iRows; iRow++) { <span class="comment">// Get cells array</span> aCells = aRows[iRow].cells; <span class="comment">// Get updates and check correctness of passed data</span> oUpdates = aUpdates[iRow]; <span class="reserved">if</span> (!oUpdates) { oUpdates = {}; } aNewCells = oUpdates.cells; <span class="reserved">if</span> (!(aNewCells instanceof Array)) { aNewCells = new Array(iColumns); } <span class="reserved">else</span> <span class="reserved">if</span> (aNewCells.length < iColumns) { aNewCells = aNewCells.concat(new Array(iColumns - aNewCells.length)); } <span class="reserved">else</span> <span class="reserved">if</span> (aNewCells.length > iColumns) { aNewCells.splice(iColumns, aNewCells.length - iColumns); } <span class="comment">// Replace cells</span> aCells.splice.apply(aCells, aSpliceArgs.concat(aNewCells)); } <span class="comment">// Check if primary key needs to be rebuilt</span> <span class="reserved">if</span> (typeof iPrimaryKey == <span class="literal">'number'</span> && iPrimaryKey >= iInsertPos) { <span class="reserved">if</span> (iPrimaryKey < iInsertPos + iHowManyToRemove) { <span class="reserved">this</span>.primaryKeyColumn = null; <span class="reserved">this</span>.primaryKey = null; bRebuildPrimaryKey = false; } <span class="reserved">else</span> { <span class="reserved">this</span>.primaryKeyColumn += iColumns - iHowManyToRemove; <span class="reserved">if</span> (<span class="reserved">this</span>.primaryKeyColumn < 0) { <span class="reserved">this</span>.primaryKeyColumn = null; <span class="reserved">this</span>.primaryKey = null; bRebuildPrimaryKey = false; } <span class="reserved">else</span> { bRebuildPrimaryKey = true; } } } } <span class="comment">// Check and correct input data</span> <span class="reserved">this</span>.prepareData(); <span class="comment">// Rebuild primary key</span> <span class="reserved">if</span> (bRebuildPrimaryKey) { <span class="reserved">this</span>.rebuildPrimaryKey(); } <span class="comment">// Show updates</span> <span class="reserved">if</span> (!oData.noRefresh) { <span class="reserved">this</span>.modify(); } <span class="reserved">return</span> iRemoved; }; <span class="comment">/** * Deletes specified columns. * * <pre> * Argument object format: * { * columns: [object or number] Array of zero-based column numbers or single * zero-based column number, * noRefresh: [boolean] If true, grid is not refreshed. Useful when you need * to delete some columns and to insert other columns * } * </pre> * * <span class="attrib">@param</span> {object} oArg Argument object * <span class="attrib">@return</span> Number of deleted columns * <span class="attrib">@type</span> number */</span> Zapatec.Grid.<span class="reserved">prototype</span>.deleteColumns = <span class="reserved">function</span>(oArg) { <span class="comment">// Check arguments</span> var aColumns = oArg.columns; <span class="reserved">if</span> (!(aColumns instanceof Array)) { <span class="reserved">if</span> (typeof aColumns == <span class="literal">'undefined'</span>) { <span class="reserved">return</span> 0; } aColumns = [aColumns]; } <span class="comment">// Delete columns</span> var iDeleted = 0; var aFields = <span class="reserved">this</span>.fields; var iColumns = aColumns.length; var aRows = <span class="reserved">this</span>.rows; var iRows = aRows.length; var iPrimaryKey = <span class="reserved">this</span>.primaryKeyColumn; var bRebuildPrimaryKey = false; var iCol, iColumn, aDeleted, iRow; <span class="reserved">for</span> (iCol = 0; iCol < iColumns; iCol++) { iColumn = parseInt(aColumns[iCol]); <span class="reserved">if</span> (!isNaN(iColumn)) { aDeleted = aFields.splice(iColumn, 1); <span class="reserved">for</span> (iRow = 0; iRow < iRows; iRow++) { aRows[iRow].cells.splice(iColumn, 1); } <span class="reserved">if</span> (aDeleted && aDeleted.length) { iDeleted++; <span class="comment">// Check if primary key needs to be rebuilt</span> <span class="reserved">if</span> (typeof iPrimaryKey == <span class="literal">'number'</span>) { <span class="reserved">if</span> (iPrimaryKey == iColumn) { <span class="reserved">this</span>.primaryKeyColumn = null; <span class="reserved">this</span>.primaryKey = null; bRebuildPrimaryKey = false; } <span class="reserved">else</span> <span class="reserved">if</span> (iPrimaryKey > iColumn) { <span class="reserved">this</span>.primaryKeyColumn--; <span class="reserved">if</span> (<span class="reserved">this</span>.primaryKeyColumn < 0) { <span class="reserved">this</span>.primaryKeyColumn = null; <span class="reserved">this</span>.primaryKey = null; bRebuildPrimaryKey = false; } <span class="reserved">else</span> { bRebuildPrimaryKey = true; } } } } } } <span class="comment">// Check and correct input data</span> <span class="reserved">this</span>.prepareData(); <span class="comment">// Rebuild primary key</span> <span class="reserved">if</span> (bRebuildPrimaryKey) { <span class="reserved">this</span>.rebuildPrimaryKey(); } <span class="comment">// Refresh grid</span> <span class="reserved">if</span> (!oArg.noRefresh) { <span class="reserved">this</span>.refresh(); } <span class="reserved">return</span> iDeleted; }; <span class="comment">/** * Displays grid after modification of data like splice or query. Updates * filters, refreshes the grid and fires gridModified event. Note: To redraw * grid if data were not modified, use {<span class="attrib">@link</span> Zapatec.Grid#refresh} method * instead. */</span> Zapatec.Grid.<span class="reserved">prototype</span>.modify = <span class="reserved">function</span>() { <span class="comment">// Display grid</span> <span class="reserved">this</span>.setFilters(); <span class="comment">// Display filter out forms</span> <span class="reserved">this</span>.displayFilterOut(); <span class="comment">// Fire event</span> <span class="reserved">this</span>.fireEvent(<span class="literal">'gridModified'</span>); }; <span class="comment">/** * Sorts the grid. You can pass single column or an array of columns to sort by * several columns simultaneously. This works as follows: Grid is sorted by * primary column (first column in the array). If there are equal values, * sorting is done by next column in the array and so on. When single column is * passed instead of an array, it becomes primary column and in case of equal * values sorting is done by other columns from most left column to most right * column in ascending order. If column is not specified (no argument is passed * or passed an empty array), primary column and order from the last sorting are * used. * * <pre> * Argument object format: * [ * { * column: [number or string, optional] number of column to sort * (default is value of sortColumn config option), * desc: [boolean, optional] sort in descending order (default is false) * }, * ... * ] * * Also accepted following format: * { * column: [number or string, optional] number of column to sort * (default is value of sortColumn config option), * desc: [boolean, optional] sort in descending order (default is false) * } * </pre> * * <span class="attrib">@param</span> {object} oArg Optional. Argument object */</span> Zapatec.Grid.<span class="reserved">prototype</span>.sort = <span class="reserved">function</span>(aArg) { <span class="comment">// Process argument</span> <span class="reserved">if</span> (aArg) { <span class="comment">// Correct argument</span> <span class="reserved">if</span> (!(aArg instanceof Array)) { aArg = [aArg]; } <span class="comment">// Form sorting order from argument</span> <span class="reserved">this</span>.order = []; <span class="reserved">for</span> (var iArg = 0; iArg < aArg.length; iArg++) { var oArg = aArg[iArg]; <span class="reserved">if</span> (!oArg) { break; } <span class="reserved">this</span>.order.push({ col: oArg.column * 1, desc: oArg.desc, lt: oArg.desc ? 1 : -1, gt: oArg.desc ? -1 : 1 }); } } <span class="comment">// Complete sorting order array with the rest of columns</span> <span class="reserved">if</span> (<span class="reserved">this</span>.order.length && <span class="reserved">this</span>.order.length < <span class="reserved">this</span>.fields.length) { <span class="comment">// Get already used columns</span> var oUsed = {}; <span class="reserved">for</span> (var iPos = 0; iPos < <span class="reserved">this</span>.order.length; iPos++) { oUsed[<span class="reserved">this</span>.order[iPos].col] = true; } <span class="comment">// Complete array</span> <span class="reserved">for</span> (var iCol = 0; iCol < <span class="reserved">this</span>.fields.length && <span class="reserved">this</span>.order.length < <span class="reserved">this</span>.fields.length; iCol++) { <span class="reserved">if</span> (oUsed[iCol]) { continue; } <span class="reserved">this</span>.order.push({ col: iCol, <span class="comment">// Ascending by default</span> lt: -1, gt: 1 }); } } <span class="comment">// Set sorted flag</span> <span class="reserved">for</span> (var iCol = 0; iCol < <span class="reserved">this</span>.fields.length; iCol++) { var oField = <span class="reserved">this</span>.fields[iCol]; <span class="reserved">if</span> (oField) { <span class="comment">// Unset flags</span> var undef; oField.sorted = undef; oField.sortedDesc = undef; <span class="comment">// Set flag</span> <span class="reserved">if</span> (<span class="reserved">this</span>.order.length && iCol == <span class="reserved">this</span>.order[0].col) { <span class="reserved">if</span> (<span class="reserved">this</span>.order[0].desc) { oField.sortedDesc = true; } <span class="reserved">else</span> { oField.sorted = true; } } } } <span class="comment">// Check if we need to sort</span> <span class="reserved">if</span> (!<span class="reserved">this</span>.order.length) { <span class="reserved">return</span>; } <span class="comment">// Correct column numbers</span> <span class="reserved">for</span> (var iPos = 0; iPos < <span class="reserved">this</span>.order.length; iPos++) { var iCol = <span class="reserved">this</span>.order[iPos].col; <span class="reserved">if</span> (<span class="reserved">this</span>.fields[iCol] && typeof <span class="reserved">this</span>.fields[iCol].sortByColumn != <span class="literal">'undefined'</span>) { <span class="reserved">this</span>.order[iPos].col = <span class="reserved">this</span>.fields[iCol].sortByColumn * 1; } } <span class="comment">// When dataOnDemand, sorting is done on server</span> <span class="reserved">if</span> (!<span class="reserved">this</span>.config.dataOnDemand) { <span class="comment">// Display "Updating"</span> <span class="reserved">if</span> (<span class="reserved">this</span>.displayUpdating) { <span class="reserved">this</span>.displayUpdating(); } <span class="comment">// Sort grid</span> var oGrid = <span class="reserved">this</span>; <span class="comment">// Timeout to let browser display "Updating"</span> setTimeout(<span class="reserved">function</span>() { oGrid.filteredRows.sort(<span class="reserved">function</span>(oLeft, oRight) { <span class="reserved">for</span> (var iCol = 0; iCol < oGrid.order.length; iCol++) { var iColNum = oGrid.order[iCol].col; var leftVal = oGrid.getCellValueCompare(oLeft.cells[iColNum]); var rightVal = oGrid.getCellValueCompare(oRight.cells[iColNum]); <span class="reserved">if</span> (leftVal == rightVal) { continue; } <span class="reserved">if</span> (leftVal < rightVal) { <span class="reserved">return</span> oGrid.order[iCol].lt; } <span class="reserved">return</span> oGrid.order[iCol].gt; } <span class="reserved">return</span> 0; }); <span class="comment">// We don't need this any more</span> oGrid = null; }, 0); } }; <span class="comment">/** * Unsorts the grid. * * <span class="attrib">@param</span> {object} oArg Argument object */</span> Zapatec.Grid.<span class="reserved">prototype</span>.unsort = <span class="reserved">function</span>() { <span class="comment">// Remove sorting order</span> <span class="reserved">this</span>.order = []; <span class="comment">// Redraw grid</span> <span class="reserved">this</span>.applyFilters(); }; <span class="comment">/** * Sorts column in ascending (if it is sorted descending) or descending * (if it is sorted ascending) order. * * <span class="attrib">@param</span> {number} iGridId Id of the grid * <span class="attrib">@param</span> {number} iCol Number of column to sort */</span> Zapatec.Grid.sort = <span class="reserved">function</span>(iGridId, iCol) { <span class="comment">// Check arguments</span> var oGrid = Zapatec.Widget.getWidgetById(iGridId); <span class="reserved">if</span> (!oGrid || !oGrid.fields[iCol]) { <span class="reserved">return</span>; } <span class="comment">// Sort grid</span> <span class="reserved">if</span> (!oGrid.fields[iCol].sorted) { <span class="comment">// Sort in ascending order</span> oGrid.sort({ column: iCol }); } <span class="reserved">else</span> { <span class="comment">// Sort in descending order</span> oGrid.sort({ column: iCol, desc: true }); } <span class="reserved">if</span> (oGrid.config.dataOnDemand) { <span class="comment">// Sort on server</span> oGrid.loadData(); } <span class="reserved">else</span> { <span class="comment">// Redraw grid</span> oGrid.refresh(); } }; <span class="comment">/** * Returns current page number. * * <span class="attrib">@return</span> Current page number * <span class="attrib">@type</span> number */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getCurrentPageNumber = <span class="reserved">function</span>() { <span class="reserved">return</span> <span class="reserved">this</span>.currentPage + 1; }; <span class="comment">/** * Returns total number of pages. * * <span class="attrib">@return</span> Total number of pages in the grid * <span class="attrib">@type</span> number */</span> Zapatec.Grid.<span class="reserved">prototype</span>.totalPages = <span class="reserved">function</span>() { var iRecords = <span class="reserved">this</span>.recordsDisplayed(); var iRowsPerPage; <span class="reserved">if</span> (<span class="reserved">this</span>.fitInto) { <span class="comment">// Autoresizing</span> var oAutoresizeFrame = <span class="reserved">this</span>.autoresizeFrame; iRowsPerPage = oAutoresizeFrame.visibleRows; } <span class="reserved">else</span> { iRowsPerPage = <span class="reserved">this</span>.config.rowsPerPage; } <span class="reserved">if</span> (iRowsPerPage <= 0 || iRecords <= 0) { <span class="reserved">return</span> 1; } <span class="reserved">return</span> Math.ceil(iRecords / iRowsPerPage); }; <span class="comment">/** * Sets current page. Only sets private variable without grid refreshing. * * <span class="attrib">@param</span> {number} iPage Zero-based number of page */</span> Zapatec.Grid.<span class="reserved">prototype</span>.setCurrentPage = <span class="reserved">function</span>(iPage) { <span class="comment">// Get number of pages</span> <span class="reserved">if</span> (iPage < 0 || iPage >= <span class="reserved">this</span>.totalPages()) { <span class="reserved">return</span>; } var iDirection = iPage - <span class="reserved">this</span>.currentPage; <span class="reserved">if</span> (!iDirection) { <span class="comment">// No changes</span> <span class="reserved">return</span>; } <span class="reserved">if</span> (<span class="reserved">this</span>.fitInto) { <span class="comment">// Autoresizing</span> var oAutoresizeFrame = <span class="reserved">this</span>.autoresizeFrame; <span class="reserved">if</span> (Math.abs(iDirection) == 1) { <span class="comment">// Next or previous page</span> oAutoresizeFrame.direction = iDirection; oAutoresizeFrame.currentRow += oAutoresizeFrame.visibleRows * iDirection; } <span class="reserved">else</span> { <span class="comment">// Random page</span> oAutoresizeFrame.direction = 0; oAutoresizeFrame.currentRow = iPage * oAutoresizeFrame.visibleRows; } <span class="reserved">if</span> (oAutoresizeFrame.currentRow < 0) { <span class="comment">// Fix 1st page</span> oAutoresizeFrame.direction = 0; oAutoresizeFrame.visibleRows += oAutoresizeFrame.currentRow; oAutoresizeFrame.currentRow = 0; } <span class="reserved">else</span> { var iRecords = <span class="reserved">this</span>.recordsDisplayed(); <span class="reserved">if</span> (oAutoresizeFrame.currentRow + oAutoresizeFrame.visibleRows > iRecords) { <span class="comment">// Fix last page</span> oAutoresizeFrame.direction = -1; oAutoresizeFrame.currentRow = iRecords - oAutoresizeFrame.visibleRows; } } <span class="comment">// Go to page</span> <span class="reserved">this</span>.currentPage = Math.ceil(oAutoresizeFrame.currentRow / oAutoresizeFrame.visibleRows); } <span class="reserved">else</span> { <span class="comment">// Go to page</span> <span class="reserved">this</span>.currentPage = iPage; } }; <span class="comment">/** * Displays specified page. * * <span class="attrib">@param</span> {number} iPage Zero-based number of page */</span> Zapatec.Grid.<span class="reserved">prototype</span>.gotoPage = <span class="reserved">function</span>(iPage) { <span class="comment">// Set current page</span> <span class="reserved">this</span>.setCurrentPage(iPage); <span class="comment">// Refresh grid</span> <span class="reserved">if</span> (<span class="reserved">this</span>.config.dataOnDemand) { <span class="comment">// Get page from server</span> <span class="reserved">this</span>.loadData(); } <span class="reserved">else</span> { <span class="comment">// Redraw grid</span> <span class="reserved">this</span>.refresh(); } }; <span class="comment">/** * Goes to the specified page. * * <span class="attrib">@param</span> {number} iGridId Id of the grid * <span class="attrib">@param</span> {number} iPage Number of page */</span> Zapatec.Grid.gotoPage = <span class="reserved">function</span>(iGridId, iPage) { var oGrid = Zapatec.Widget.getWidgetById(iGridId); <span class="reserved">if</span> (oGrid) { oGrid.gotoPage(iPage - 1); } }; <span class="comment">/** * Goes to the next page. * * <span class="attrib">@param</span> {number} iGridId Id of the grid */</span> Zapatec.Grid.nextPage = <span class="reserved">function</span>(iGridId) { var oGrid = Zapatec.Widget.getWidgetById(iGridId); <span class="reserved">if</span> (oGrid) { oGrid.gotoPage(oGrid.currentPage + 1); } }; <span class="comment">/** * Goes to the last page. * * <span class="attrib">@param</span> {number} iGridId Id of the grid */</span> Zapatec.Grid.lastPage = <span class="reserved">function</span>(iGridId) { var oGrid = Zapatec.Widget.getWidgetById(iGridId); <span class="reserved">if</span> (oGrid) { oGrid.gotoPage(oGrid.totalPages() - 1); } }; <span class="comment">/** * Goes to the previous page. * * <span class="attrib">@param</span> {number} iGridId Id of the grid */</span> Zapatec.Grid.previousPage = <span class="reserved">function</span>(iGridId) { var oGrid = Zapatec.Widget.getWidgetById(iGridId); <span class="reserved">if</span> (oGrid) { oGrid.gotoPage(oGrid.currentPage - 1); } }; <span class="comment">/** * Goes to the first page. * * <span class="attrib">@param</span> {number} iGridId Id of the grid */</span> Zapatec.Grid.firstPage = <span class="reserved">function</span>(iGridId) { var oGrid = Zapatec.Widget.getWidgetById(iGridId); <span class="reserved">if</span> (oGrid) { oGrid.gotoPage(0); } }; <span class="comment">/** * Sets current vertical scroll. Only sets private variable without grid * refreshing. * * <pre> * Arguments format: * { * rowId: [number, optional] zero-based row id * row: [object, optional] row object * } * * Only one of <i>rowId</i> and <i>row</i> properties should be defined. * </pre> * * <span class="attrib">@param</span> {object} oArg Arguments */</span> Zapatec.Grid.<span class="reserved">prototype</span>.setCurrentVerticalOffset = <span class="reserved">function</span>(oArg) { <span class="comment">// Get row id</span> var iRowId; <span class="reserved">if</span> (typeof oArg == <span class="literal">'number'</span>) { <span class="comment">// For backwar compatibility with previous versions where this function</span> <span class="comment">// accepted single numeric argument</span> iRowId = oArg; } <span class="reserved">else</span> { <span class="reserved">if</span> (!oArg) { <span class="reserved">return</span>; } iRowId = oArg.rowId; <span class="reserved">if</span> (typeof iRowId != <span class="literal">'number'</span>) { iRowId = <span class="reserved">this</span>.getRowId(oArg.row); <span class="reserved">if</span> (typeof iRowId != <span class="literal">'number'</span>) { <span class="reserved">return</span>; } } } <span class="comment">// Fix offset</span> <span class="reserved">if</span> (iRowId < 0) { iRowId = 0; } <span class="comment">// Certain number of rows must be always visible</span> var iRows = <span class="reserved">this</span>.recordsDisplayed() - 1; <span class="reserved">if</span> (iRowId > iRows) { iRowId = iRows; } <span class="comment">// Set offset</span> <span class="reserved">this</span>.currentVerticalOffset = iRowId; }; <span class="comment">/** * Scrolls grid to the specified row. * * <pre> * Arguments format: * { * rowId: [number, optional] zero-based row id * row: [object, optional] row object * } * * Only one of <i>rowId</i> and <i>row</i> properties should be defined. * </pre> * * <span class="attrib">@param</span> {object} oArg Arguments */</span> Zapatec.Grid.<span class="reserved">prototype</span>.gotoVerticalOffset = <span class="reserved">function</span>(oArg) { <span class="comment">// Set current offset</span> <span class="reserved">this</span>.setCurrentVerticalOffset(oArg); <span class="comment">// Refresh grid</span> <span class="reserved">if</span> (<span class="reserved">this</span>.config.dataOnDemand) { <span class="comment">// Get page from server</span> <span class="reserved">this</span>.loadData(); } <span class="reserved">else</span> { <span class="comment">// Redraw grid</span> <span class="reserved">this</span>.refresh(); } }; <span class="comment">/** * Sets current horizontal scroll. Only sets private variable without grid * refreshing. * * <pre> * Arguments format: * { * fieldId: [number, optional] zero-based field (column) id, * field: [object, optional] field object * } * * Only one of <i>fieldId</i> and <i>field</i> properties should be defined. * </pre> * * <span class="attrib">@param</span> {object} oArg Arguments */</span> Zapatec.Grid.<span class="reserved">prototype</span>.setCurrentHorizontalOffset = <span class="reserved">function</span>(oArg) { <span class="comment">// Get field id</span> var iFieldId; <span class="reserved">if</span> (typeof oArg == <span class="literal">'number'</span>) { <span class="comment">// For backwar compatibility with previous versions where this function</span> <span class="comment">// accepted single numeric argument</span> iFieldId = oArg; } <span class="reserved">else</span> { <span class="reserved">if</span> (!oArg) { <span class="reserved">return</span>; } iFieldId = oArg.fieldId; <span class="reserved">if</span> (typeof iFieldId != <span class="literal">'number'</span>) { iFieldId = <span class="reserved">this</span>.getFieldId(oArg.field); <span class="reserved">if</span> (typeof iFieldId != <span class="literal">'number'</span>) { <span class="reserved">return</span>; } } } <span class="comment">// Set offset</span> <span class="reserved">if</span> (<span class="reserved">this</span>.fields[iFieldId]) { <span class="reserved">this</span>.currentHorizontalOffset = iFieldId; } }; <span class="comment">/** * Scrolls grid to the specified column. * * <pre> * Arguments format: * { * fieldId: [number, optional] zero-based field (column) id, * field: [object, optional] field object * } * * Only one of <i>fieldId</i> and <i>field</i> properties should be defined. * </pre> * * <span class="attrib">@param</span> {object} oArg Arguments */</span> Zapatec.Grid.<span class="reserved">prototype</span>.gotoHorizontalOffset = <span class="reserved">function</span>(oArg) { <span class="comment">// Set current offset</span> <span class="reserved">this</span>.setCurrentHorizontalOffset(oArg); <span class="comment">// Refresh grid</span> <span class="reserved">if</span> (<span class="reserved">this</span>.config.dataOnDemand) { <span class="comment">// Get page from server</span> <span class="reserved">this</span>.loadData(); } <span class="reserved">else</span> { <span class="comment">// Redraw grid</span> <span class="reserved">this</span>.refresh(); } }; <span class="comment">/** * Displays page with specified row. * * <span class="attrib">@param</span> {number} iRowId Row id */</span> Zapatec.Grid.<span class="reserved">prototype</span>.gotoRowId = <span class="reserved">function</span>(iRowId) { <span class="comment">// Get row number</span> var aRows = <span class="reserved">this</span>.getFilteredRows(); <span class="reserved">for</span> (var iRow = 0; iRow < aRows.length; iRow++) { <span class="reserved">if</span> (<span class="reserved">this</span>.getRowId(aRows[iRow]) == iRowId) { <span class="comment">// Go to the page</span> <span class="reserved">this</span>.gotoPage(Math.floor(iRow / <span class="reserved">this</span>.config.rowsPerPage)); <span class="reserved">return</span>; } } }; <span class="comment">/** * Applies filters to the grid. * <span class="attrib">@private</span> */</span> Zapatec.Grid.<span class="reserved">prototype</span>.applyFilters = <span class="reserved">function</span>() { <span class="comment">// Fire event</span> <span class="reserved">this</span>.fireEvent(<span class="literal">'gridPrepareFilter'</span>); <span class="comment">// Check if data is filtered on server</span> <span class="reserved">if</span> (<span class="reserved">this</span>.config.dataOnDemand) { <span class="comment">// Go to the first page</span> <span class="reserved">this</span>.setCurrentPage(0); <span class="comment">// Filter on server</span> <span class="reserved">this</span>.loadData(); <span class="comment">// Fire event</span> <span class="reserved">this</span>.fireEvent(<span class="literal">'gridFiltered'</span>); } <span class="reserved">else</span> { <span class="comment">// Display "Updating"</span> <span class="reserved">if</span> (<span class="reserved">this</span>.displayUpdating) { <span class="reserved">this</span>.displayUpdating(); } <span class="comment">// Set filters</span> var oGrid = <span class="reserved">this</span>; <span class="comment">// Timeout to let browser display "Updating"</span> setTimeout(<span class="reserved">function</span>() { oGrid.setFilters(); <span class="comment">// Fire event</span> oGrid.fireEvent(<span class="literal">'gridFiltered'</span>); }, 0); } }; <span class="comment">/** * Sets filters to the array of rows. * <span class="attrib">@private</span> */</span> Zapatec.Grid.<span class="reserved">prototype</span>.setFilters = <span class="reserved">function</span>() { <span class="comment">// Duplicate rows array</span> <span class="reserved">this</span>.filteredRows = <span class="reserved">this</span>.rows.slice(); var aFilteredRows = <span class="reserved">this</span>.filteredRows; <span class="comment">// Columns having regexp filter set</span> var aRegexpFilters = []; <span class="comment">// Columns having text filter set</span> var aTextFilters = []; <span class="comment">// Iterate over columns</span> var aFields = <span class="reserved">this</span>.fields; var iFields = aFields.length; var iCol, oField, aHiddenValues, minValue, maxValue, iRow, oCell; <span class="reserved">for</span> (iCol = 0; iCol < iFields; iCol++) { oField = aFields[iCol]; <span class="reserved">if</span> (!oField) { continue; } <span class="comment">// Apply filters</span> aHiddenValues = oField.hiddenValues; minValue = oField.minValue; maxValue = oField.maxValue; <span class="reserved">if</span> (aHiddenValues instanceof Array || typeof minValue != <span class="literal">'undefined'</span> || typeof maxValue != <span class="literal">'undefined'</span>) { <span class="comment">// Iterate over rows</span> <span class="reserved">for</span> (iRow = aFilteredRows.length - 1; iRow >= 0; iRow--) { <span class="comment">// Get cell</span> oCell = aFilteredRows[iRow].cells[iCol]; <span class="reserved">if</span> (!oCell) { continue; } <span class="comment">// Remove row if value of the cell is hidden</span> <span class="reserved">if</span> (aHiddenValues instanceof Array && Zapatec.Utils.arrIndexOf(aHiddenValues, <span class="reserved">this</span>.getCellValueString(oCell)) >= 0) { aFilteredRows.splice(iRow, 1); continue; } <span class="comment">// Remove row if value of the cell is lesser than min value</span> <span class="reserved">if</span> (minValue > <span class="reserved">this</span>.getCellValueCompare(oCell)) { aFilteredRows.splice(iRow, 1); continue; } <span class="comment">// Remove row if value of the cell is greater than max value</span> <span class="reserved">if</span> (maxValue < <span class="reserved">this</span>.getCellValueCompare(oCell)) { aFilteredRows.splice(iRow, 1); continue; } } } <span class="comment">// Check regexp filter</span> <span class="reserved">if</span> (oField.regexpFilter) { aRegexpFilters.push(iCol); } <span class="comment">// Check text filter</span> <span class="reserved">if</span> (oField.textFilter) { aTextFilters.push(iCol); } } <span class="comment">// Apply regexp filters</span> var bRemove, iFilter, sSearchValue, oRegExp; var iRegexpFilters = aRegexpFilters.length; <span class="reserved">if</span> (iRegexpFilters) { <span class="comment">// Iterate over rows</span> <span class="reserved">for</span> (iRow = aFilteredRows.length - 1; iRow >= 0; iRow--) { <span class="comment">// Indicates that row should be removed</span> bRemove = true; <span class="comment">// Iterate over filters</span> <span class="reserved">for</span> (iFilter = 0; iFilter < iRegexpFilters; iFilter++) { <span class="comment">// Column number</span> iCol = aRegexpFilters[iFilter]; <span class="comment">// Get field</span> oField = aFields[iCol]; <span class="comment">// Get cell</span> oCell = aFilteredRows[iRow].cells[iCol]; <span class="reserved">if</span> (!oCell) { continue; } <span class="comment">// Get cell value</span> sSearchValue = <span class="reserved">this</span>.getCellValueString(oCell); sSearchValue = sSearchValue.replace(/<[^>]*>/g, <span class="literal">''</span>); <span class="comment">// Search text fragment</span> oRegExp = typeof oField.regexpFilter == <span class="literal">'string'</span> ? new RegExp(oField.regexpFilter) : oField.regexpFilter; <span class="reserved">if</span> (oRegExp.test && oRegExp.test(sSearchValue)) { bRemove = false; break; } } <span class="comment">// Remove row if text fragment not found</span> <span class="reserved">if</span> (bRemove) { aFilteredRows.splice(iRow, 1); } } } <span class="comment">// Apply text filters</span> var iTextFilters = aTextFilters.length; <span class="reserved">if</span> (iTextFilters) { <span class="comment">// Iterate over rows</span> <span class="reserved">for</span> (iRow = aFilteredRows.length - 1; iRow >= 0; iRow--) { <span class="comment">// Indicates that row should be removed</span> bRemove = true; <span class="comment">// Iterate over filters</span> <span class="reserved">for</span> (iFilter = 0; iFilter < iTextFilters; iFilter++) { <span class="comment">// Column number</span> iCol = aTextFilters[iFilter]; <span class="comment">// Get field</span> oField = aFields[iCol]; <span class="comment">// Get cell</span> oCell = aFilteredRows[iRow].cells[iCol]; <span class="reserved">if</span> (!oCell) { continue; } <span class="comment">// Search text fragment</span> <span class="reserved">if</span> (<span class="reserved">this</span>.searchCell({ cell: oCell, searchValue: oField.textFilter }) >= 0) { bRemove = false; break; } } <span class="comment">// Remove row if text fragment was not found</span> <span class="reserved">if</span> (bRemove) { aFilteredRows.splice(iRow, 1); } } } <span class="comment">// Sort if needed</span> <span class="reserved">this</span>.sort(); <span class="comment">// Go to the first page</span> <span class="reserved">this</span>.setCurrentPage(0); <span class="comment">// Redraw grid</span> <span class="reserved">this</span>.refresh(); }; <span class="comment">/** * Searches specified value in the specified cell. * * <pre> * Arguments format: * { * cell: [object] cell object, * searchValue: [string] value to search for * } * </pre> * * <span class="attrib">@private</span> * <span class="attrib">@param</span> {object} oArg Arguments * <span class="attrib">@return</span> The index within the cell string representation of the first * occurrence of the specified value, or -1 if the value is not found, or * undefined in case of invalid arguments * <span class="attrib">@type</span> number */</span> Zapatec.Grid.<span class="reserved">prototype</span>.searchCell = <span class="reserved">function</span>(oArg) { <span class="reserved">if</span> (!oArg) { <span class="reserved">return</span>; } var oCell = oArg.cell; <span class="comment">// Search text fragment</span> <span class="reserved">if</span> (typeof <span class="reserved">this</span>.getSearchByType == <span class="literal">'function'</span>) { <span class="comment">// Try to use specific search method</span> var oField = <span class="reserved">this</span>.getFieldByCell(oCell); <span class="reserved">if</span> (!oField) { <span class="reserved">return</span>; } var sSearchFunc = <span class="reserved">this</span>.getSearchByType(oField.dataType); <span class="reserved">if</span> (sSearchFunc) { <span class="reserved">return</span> <span class="reserved">this</span>[sSearchFunc](oArg); } } <span class="comment">// Default</span> <span class="comment">// Get string to search in</span> var sText = <span class="reserved">this</span>.getCellValueString(oCell); <span class="comment">// Remove HTML tags</span> sText = sText.replace(/<[^>]*>/g, <span class="literal">''</span>); <span class="comment">// Search</span> <span class="reserved">return</span> sText.indexOf(oArg.searchValue); }; <span class="comment">/** * Filters out rows with the specified value in the specified column or set * of columns. * * <pre> * Arguments format: * { * column: [object or number] array of zero-based column numbers or single * zero-based column number to filter, * value: [object or string] array of values or single value to filter out, * show: [boolean] show rows having this value or not * } * </pre> * * <span class="attrib">@param</span> {object} oArg Arguments */</span> Zapatec.Grid.<span class="reserved">prototype</span>.filterOut = <span class="reserved">function</span>(oArg) { <span class="comment">// Filter out columns</span> <span class="reserved">if</span> (<span class="reserved">this</span>.filterOutColumn(oArg)) { <span class="comment">// Apply filters</span> <span class="reserved">this</span>.applyFilters(); } }; <span class="comment">/** * Filters out rows with the specified value in the specified columns. Only sets * a hidden value without applying it to the grid. * * <pre> * Argument object format: * * { * column: [object or number] array of zero-based column numbers or single * zero-based column number to filter, * value: [object or string] array of values or single value to filter out, * show: [boolean] show rows having this value or not * } * </pre> * * <span class="attrib">@private</span> * <span class="attrib">@param</span> {object} oArg Argument object * <span class="attrib">@return</span> True if the hidden values were set * <span class="attrib">@type</span> boolean */</span> Zapatec.Grid.<span class="reserved">prototype</span>.filterOutColumn = <span class="reserved">function</span>(oArg) { <span class="comment">// Check arguments</span> <span class="reserved">if</span> (!oArg || typeof oArg.value == <span class="literal">'undefined'</span>) { <span class="comment">// Error</span> <span class="reserved">return</span> false; } var aVals = oArg.value; <span class="reserved">if</span> (!(aVals instanceof Array)) { aVals = [aVals]; } var aCols = oArg.column; <span class="reserved">if</span> (!(aCols instanceof Array)) { aCols = [aCols]; } <span class="comment">// Will indicate that hidden values are set</span> var bApply = false; <span class="comment">// Filter out columns</span> <span class="reserved">for</span> (var iCol = 0; iCol < aCols.length; iCol++) { <span class="comment">// Get column</span> var oField = <span class="reserved">this</span>.fields[aCols[iCol]]; <span class="reserved">if</span> (!oField) { continue; } <span class="comment">// Setup hidden values</span> <span class="reserved">if</span> (!(oField.hiddenValues instanceof Array)) { oField.hiddenValues = []; } <span class="reserved">if</span> (oArg.show) { <span class="comment">// Remove from hiddenValues</span> <span class="reserved">for</span> (var iVal = 0; iVal < aVals.length; iVal++) { <span class="reserved">for</span> (var iHv = oField.hiddenValues.length - 1; iHv >= 0; iHv--) { <span class="reserved">if</span> (oField.hiddenValues[iHv] == aVals[iVal]) { oField.hiddenValues.splice(iHv, 1); } } } } <span class="reserved">else</span> { <span class="comment">// Add to hiddenValues</span> <span class="reserved">for</span> (var iVal = 0; iVal < aVals.length; iVal++) { oField.hiddenValues.push(aVals[iVal]); } } bApply = true; } <span class="reserved">return</span> bApply; }; <span class="comment">/** * Removes all hidden values from the specified columns. * * <pre> * Argument object format: * * { * column: [object or number] array of zero-based column numbers or single * zero-based column number to remove hidden values from * } * </pre> * * <span class="attrib">@param</span> {object} oArg Argument object */</span> Zapatec.Grid.<span class="reserved">prototype</span>.unfilterOut = <span class="reserved">function</span>(oArg) { <span class="comment">// Reset hidden values</span> <span class="reserved">if</span> (<span class="reserved">this</span>.unfilterOutColumn(oArg)) { <span class="comment">// Apply filters</span> <span class="reserved">this</span>.applyFilters(); } }; <span class="comment">/** * Removes all hidden values from the specified columns. Only resets hidden * values without applying them to the grid. * * <pre> * Argument object format: * * { * column: [object or number] array of zero-based column numbers or single * zero-based column number to remove hidden values from * } * </pre> * * <span class="attrib">@private</span> * <span class="attrib">@param</span> {object} oArg Argument object * <span class="attrib">@return</span> True if hidden values were reset and must be applied to the grid * <span class="attrib">@type</span> boolean */</span> Zapatec.Grid.<span class="reserved">prototype</span>.unfilterOutColumn = <span class="reserved">function</span>(oArg) { <span class="comment">// Check arguments</span> <span class="reserved">if</span> (!oArg) { <span class="comment">// Error</span> <span class="reserved">return</span> false; } var aCols = oArg.column; <span class="reserved">if</span> (!(aCols instanceof Array)) { aCols = [aCols]; } <span class="comment">// Will indicate that hidden values were reset</span> var bApply = false; <span class="comment">// Reset hidden values</span> var undef; <span class="reserved">for</span> (var iCol = 0; iCol < aCols.length; iCol++) { <span class="comment">// Get field</span> var oField = <span class="reserved">this</span>.fields[aCols[iCol]]; <span class="reserved">if</span> (!oField) { continue; } <span class="reserved">if</span> ((oField.hiddenValues instanceof Array) && oField.hiddenValues.length) { oField.hiddenValues = undef; bApply = true; } } <span class="reserved">return</span> bApply; }; <span class="comment">/** * Limits range of values of the specified column. * * <pre> * Argument object format: * * { * column: [number] zero-based number of column to filter, * min [any, optional] minimum cell value to compare, * minValue [any, optional] minimum cell value, * max [any, optional] mamximum cell value to compare, * maxValue [any, optional] mamximum cell value * } * * If <b>min</b> property is defined, <b>minValue</b> is ignored. * If <b>max</b> property is defined, <b>maxValue</b> is ignored. * </pre> * * <span class="attrib">@param</span> {object} oArg Argument object */</span> Zapatec.Grid.<span class="reserved">prototype</span>.limitRange = <span class="reserved">function</span>(oArg) { <span class="comment">// Check arguments</span> <span class="reserved">if</span> (!oArg) { <span class="reserved">return</span>; } <span class="comment">// Get column</span> var oField = <span class="reserved">this</span>.fields[oArg.column]; <span class="reserved">if</span> (!oField) { <span class="reserved">return</span>; } <span class="comment">// Setup min value</span> <span class="reserved">if</span> (typeof oArg.min != <span class="literal">'undefined'</span>) { oField.minValue = oArg.min; } <span class="reserved">else</span> { <span class="reserved">if</span> (typeof oArg.minValue == <span class="literal">'undefined'</span>) { oField.minValue = oArg.minValue; } <span class="reserved">else</span> { <span class="comment">// Get compare value</span> var oCell = { i: oField.i, v: oArg.minValue }; oCell = <span class="reserved">this</span>.convertCell(oCell); oField.minValue = <span class="reserved">this</span>.getCellValueCompare(oCell); } } <span class="comment">// Setup max value</span> <span class="reserved">if</span> (typeof oArg.max != <span class="literal">'undefined'</span>) { oField.maxValue = oArg.max; } <span class="reserved">else</span> { <span class="reserved">if</span> (typeof oArg.maxValue == <span class="literal">'undefined'</span>) { oField.maxValue = oArg.maxValue; } <span class="reserved">else</span> { <span class="comment">// Get compare value</span> var oCell = { i: oField.i, v: oArg.maxValue }; oCell = <span class="reserved">this</span>.convertCell(oCell); oField.maxValue = <span class="reserved">this</span>.getCellValueCompare(oCell); } } <span class="comment">// Apply filters</span> <span class="reserved">this</span>.applyFilters(); }; <span class="comment">/** * Limits the result set by doing a search. Only rows having specified text * fragment will be shown. JavaScript regular expression can be used instead or * in addition to the text fragment. If you use both regexp and text, regexp is * applied first. * * <pre> * Argument object format: * { * regexp: [object or string, optional] RegExp object or regular expression * string to match, * text: [string, optional] text fragment to search, * columns: [object, optional] array with zero-based column numbers to search * (by default all columns are searched) * } * </pre> * * <span class="attrib">@param</span> {object} oArg Argument object */</span> Zapatec.Grid.<span class="reserved">prototype</span>.setFilter = <span class="reserved">function</span>(oArg) { <span class="comment">// Check arguments</span> <span class="reserved">if</span> (!oArg) { oArg = {}; } <span class="comment">// Set text filter</span> var aFields = <span class="reserved">this</span>.fields; var aColumns = oArg.columns; var oRegExp = oArg.regexp; var sText = oArg.text; var iCol, oField; <span class="reserved">if</span> (aColumns instanceof Array) { var iColumns = aColumns.length; <span class="reserved">for</span> (iCol = 0; iCol < iColumns; iCol++) { oField = aFields[aColumns[iCol]]; <span class="reserved">if</span> (oField) { oField.regexpFilter = oRegExp; oField.textFilter = sText; } } } <span class="reserved">else</span> { var iFields = aFields.length; <span class="reserved">for</span> (iCol = 0; iCol < iFields; iCol++) { oField = aFields[iCol]; <span class="reserved">if</span> (!(oField instanceof Object)) { aFields[iCol] = {}; oField = aFields[iCol]; } oField.regexpFilter = oRegExp; oField.textFilter = sText; } } <span class="comment">// Apply filters</span> <span class="reserved">this</span>.applyFilters(); }; <span class="comment">/** * Removes filter from the specified columns. * * <pre> * Argument object format: * * { * columns: [object, optional] array with column numbers to remove filter from * } * * If oArg or columns are not defined or empty, filter is removed from all * columns. * </pre> * * <span class="attrib">@param</span> {object} oArg Optional. Argument object */</span> Zapatec.Grid.<span class="reserved">prototype</span>.removeFilter = <span class="reserved">function</span>(oArg) { <span class="comment">// Check arguments</span> <span class="reserved">if</span> (!oArg) { oArg = {}; } <span class="comment">// Remove text filter</span> <span class="reserved">this</span>.setFilter({ columns: oArg.columns }); }; <span class="comment">/** * Resets all filterouts, ranges and text filters. */</span> Zapatec.Grid.<span class="reserved">prototype</span>.resetFilters = <span class="reserved">function</span>() { <span class="comment">// Remove filters</span> <span class="reserved">for</span> (var iCol = 0; iCol < <span class="reserved">this</span>.fields.length; iCol++) { var oField = <span class="reserved">this</span>.fields[iCol]; <span class="reserved">if</span> (oField) { var undef; <span class="comment">// Remove filterout</span> oField.hiddenValues = undef; <span class="comment">// Remove range</span> oField.minValue = undef; oField.maxValue = undef; <span class="comment">// Remove regexp filter</span> oField.regexpFilter = undef; <span class="comment">// Remove text filter</span> oField.textFilter = undef; } } <span class="comment">// Apply filters</span> <span class="reserved">this</span>.applyFilters(); <span class="comment">// Display filter out forms</span> <span class="reserved">this</span>.displayFilterOut(); }; <span class="comment">/** * Returns array of rows that are or must be (depending on context) displayed * on the current page. * * <span class="attrib">@return</span> Array of rows on the current page * <span class="attrib">@type</span> object */</span> Zapatec.Grid.<span class="reserved">prototype</span>.applyPaging = <span class="reserved">function</span>() { var oConfig = <span class="reserved">this</span>.config; var aFilteredRows = <span class="reserved">this</span>.filteredRows; <span class="reserved">if</span> (<span class="reserved">this</span>.currentVerticalOffset < 0) { <span class="reserved">this</span>.currentVerticalOffset = 0; } var iOffset = <span class="reserved">this</span>.currentVerticalOffset; var iVisibleRows = oConfig.visibleRows; var iRowsPerPage = oConfig.rowsPerPage; <span class="reserved">if</span> (iRowsPerPage <= 0 || oConfig.dataOnDemand) { <span class="comment">// No pagination</span> <span class="reserved">if</span> (iVisibleRows <= 0) { <span class="comment">// No scrolling</span> <span class="reserved">return</span> aFilteredRows; } <span class="comment">// Scrolling</span> <span class="reserved">return</span> aFilteredRows.slice(iOffset, iOffset + iVisibleRows); } <span class="reserved">if</span> (<span class="reserved">this</span>.fitInto) { <span class="comment">// Autoresizing</span> var oAutoresizeFrame = <span class="reserved">this</span>.autoresizeFrame; var iFirst = oAutoresizeFrame.currentRow; var iLast = iFirst + oAutoresizeFrame.visibleRows; <span class="reserved">return</span> aFilteredRows.slice(iFirst, iLast); } <span class="comment">// Get frame</span> var iFirst = <span class="reserved">this</span>.currentPage * iRowsPerPage; <span class="reserved">if</span> (iFirst && iFirst >= aFilteredRows.length) { <span class="reserved">this</span>.setCurrentPage(<span class="reserved">this</span>.currentPage - 1); iFirst = <span class="reserved">this</span>.currentPage * iRowsPerPage; } var iLast = iFirst + iRowsPerPage; <span class="comment">// No scrolling</span> <span class="reserved">if</span> (iVisibleRows <= 0) { <span class="reserved">return</span> aFilteredRows.slice(iFirst, iLast); } <span class="comment">// Scrolling</span> iFirst += iOffset; var iLastVisible = iFirst + iVisibleRows; <span class="reserved">if</span> (iLastVisible < iLast) { iLast = iLastVisible; } <span class="reserved">return</span> aFilteredRows.slice(iFirst, iLast); }; <span class="comment">/** * Refreshes grid after sorting or filtering. Note: After modification of data * like splice or query, use {<span class="attrib">@link</span> Zapatec.Grid.modify} method instead to * update filters properly. * * <pre> * Defines internal property <b>refreshState</b>. * </pre> */</span> Zapatec.Grid.<span class="reserved">prototype</span>.refresh = <span class="reserved">function</span>() { <span class="comment">// Fire event</span> <span class="reserved">this</span>.fireEvent(<span class="literal">'gridPrepareRefresh'</span>); <span class="comment">// Indicates number of running refresh processes</span> <span class="reserved">if</span> (!<span class="reserved">this</span>.refreshState) { <span class="reserved">this</span>.refreshState = 0; } <span class="reserved">this</span>.refreshState++; <span class="comment">// Refresh grid</span> <span class="reserved">if</span> (!<span class="reserved">this</span>.config.visibleRows && <span class="reserved">this</span>.displayUpdating) { <span class="reserved">this</span>.displayUpdating(); } var oGrid = <span class="reserved">this</span>; <span class="comment">// Timeout to let browser display "Updating"</span> setTimeout(<span class="reserved">function</span>() { <span class="reserved">if</span> (!oGrid.visualize) { oGrid.refreshCallback(); } <span class="reserved">else</span> <span class="reserved">if</span> (oGrid.refreshContainer) { oGrid.refreshContainer(); } }, 0); }; <span class="comment">/** * Displays grid using callback functions. * * <pre> * callbackHeaderDisplay function called to display header row. * * If callbackRowDisplay is defined, it is called to display data rows. * * If callbackDataDisplay is defined, it is called to display data instead of * callbackRowDisplay (callbackRowDisplay is ignored in this case). * * If callbackTotalDisplay is defined, it is called to display total rows. * * If callbackTotalsDisplay is defined, it is called to display totals instead * of callbackTotalDisplay (callbackTotalDisplay is ignored in this case). * * If callbackPaginationDisplay is defined, it is called to display pagination. * </pre> * * <span class="attrib">@private</span> */</span> Zapatec.Grid.<span class="reserved">prototype</span>.refreshCallback = <span class="reserved">function</span>() { <span class="comment">// Display header</span> <span class="reserved">this</span>.config.callbackHeaderDisplay(<span class="reserved">this</span>); <span class="comment">// Get rows to display</span> var aRows = <span class="reserved">this</span>.applyPaging(); <span class="comment">// Display rows</span> <span class="reserved">if</span> (typeof <span class="reserved">this</span>.config.callbackDataDisplay == <span class="literal">'function'</span>) { <span class="reserved">this</span>.config.callbackDataDisplay(<span class="reserved">this</span>, aRows); } <span class="reserved">else</span> { <span class="reserved">for</span> (var iRow = 0; iRow < aRows.length; iRow++) { <span class="reserved">this</span>.config.callbackRowDisplay(<span class="reserved">this</span>, aRows[iRow]); } } <span class="comment">// Display totals</span> <span class="reserved">if</span> (typeof <span class="reserved">this</span>.config.callbackTotalsDisplay == <span class="literal">'function'</span> || typeof <span class="reserved">this</span>.config.callbackTotalDisplay == <span class="literal">'function'</span>) { <span class="comment">// Get totals</span> var aTotals; <span class="reserved">if</span> (<span class="reserved">this</span>.getTotals) { aTotals = <span class="reserved">this</span>.getTotals(); } <span class="comment">// Display totals</span> <span class="reserved">if</span> (typeof <span class="reserved">this</span>.config.callbackTotalsDisplay == <span class="literal">'function'</span>) { <span class="reserved">this</span>.config.callbackTotalsDisplay(<span class="reserved">this</span>, aTotals); } <span class="reserved">else</span> <span class="reserved">if</span> (aTotals) { var iTotals = aTotals.length; <span class="reserved">for</span> (var iRow = 0; iRow < iTotals; iRow++) { <span class="reserved">this</span>.config.callbackTotalDisplay(<span class="reserved">this</span>, aTotals[iRow]); } } } <span class="comment">// Display pagination</span> <span class="reserved">if</span> (<span class="reserved">this</span>.config.rowsPerPage > 0) { <span class="reserved">if</span> (typeof <span class="reserved">this</span>.config.callbackPaginationDisplay == <span class="literal">'function'</span>) { <span class="comment">// Using callback</span> <span class="reserved">this</span>.config.callbackPaginationDisplay(<span class="reserved">this</span>); } <span class="reserved">else</span> <span class="reserved">if</span> (<span class="reserved">this</span>.paginationContainers.length && <span class="reserved">this</span>.outputPagination) { <span class="comment">// Using container</span> <span class="reserved">for</span> (var iEl = 0; iEl < <span class="reserved">this</span>.paginationContainers.length; iEl++) { var aHtml = []; <span class="reserved">this</span>.outputPagination(aHtml, iEl + 1); <span class="reserved">this</span>.paginationContainers[iEl].innerHTML = aHtml.join(<span class="literal">''</span>); } } } <span class="comment">// Finish refresh</span> <span class="reserved">this</span>.onRefresh(); }; <span class="comment">/** * Selects a row. If callbackCellSelect is not defined, calls callbackRowSelect * function. * * <span class="attrib">@private</span> * <span class="attrib">@param</span> {object} oRow Row object */</span> Zapatec.Grid.<span class="reserved">prototype</span>.selectRow = <span class="reserved">function</span>(oRow) { <span class="comment">// Check arguments</span> <span class="reserved">if</span> (!oRow || oRow.selected) { <span class="reserved">return</span>; } <span class="comment">// Select callback</span> <span class="reserved">if</span> (typeof <span class="reserved">this</span>.config.callbackCellSelect != <span class="literal">'function'</span> && typeof <span class="reserved">this</span>.config.callbackRowSelect == <span class="literal">'function'</span>) { <span class="reserved">this</span>.config.callbackRowSelect(<span class="reserved">this</span>, oRow); } <span class="comment">// Display updates if we are responsible for visualisation</span> <span class="reserved">if</span> (<span class="reserved">this</span>.visualizeSelectRow && <span class="reserved">this</span>.config.selectRows && <span class="reserved">this</span>.visualize) { <span class="reserved">this</span>.visualizeSelectRow(oRow); } <span class="comment">// Select row</span> oRow.selected = true; }; <span class="comment">/** * Unselects a row. If callbackCellUnselect is not defined, calls * callbackRowUnselect function. * * <span class="attrib">@private</span> * <span class="attrib">@param</span> {object} oRow Row object */</span> Zapatec.Grid.<span class="reserved">prototype</span>.unselectRow = <span class="reserved">function</span>(oRow) { <span class="comment">// Check arguments</span> <span class="reserved">if</span> (!oRow || !oRow.selected) { <span class="reserved">return</span>; } <span class="comment">// Unselect row</span> var undef; oRow.selected = undef; <span class="comment">// Display updates if we are responsible for visualisation</span> <span class="reserved">if</span> (<span class="reserved">this</span>.visualizeUnselectRow && <span class="reserved">this</span>.config.selectRows && <span class="reserved">this</span>.visualize) { <span class="reserved">this</span>.visualizeUnselectRow(oRow); } <span class="comment">// Unselect callback</span> <span class="reserved">if</span> (typeof <span class="reserved">this</span>.config.callbackCellUnselect != <span class="literal">'function'</span> && typeof <span class="reserved">this</span>.config.callbackRowUnselect == <span class="literal">'function'</span>) { <span class="reserved">this</span>.config.callbackRowUnselect(<span class="reserved">this</span>, oRow); } }; <span class="comment">/** * Selects a cell. Calls callbackCellSelect function. * * <span class="attrib">@private</span> * <span class="attrib">@param</span> {object} oCell Cell object */</span> Zapatec.Grid.<span class="reserved">prototype</span>.selectCell = <span class="reserved">function</span>(oCell) { <span class="comment">// Check arguments</span> <span class="reserved">if</span> (!oCell || oCell.selected) { <span class="reserved">return</span>; } <span class="comment">// Select callback</span> <span class="reserved">if</span> (typeof <span class="reserved">this</span>.config.callbackCellSelect == <span class="literal">'function'</span>) { <span class="reserved">this</span>.config.callbackCellSelect(<span class="reserved">this</span>, oCell); } <span class="comment">// Display updates if we are responsible for visualisation</span> <span class="reserved">if</span> (<span class="reserved">this</span>.visualizeSelectCell && <span class="reserved">this</span>.config.selectCells && <span class="reserved">this</span>.visualize) { <span class="reserved">this</span>.visualizeSelectCell(oCell); } <span class="comment">// Select cell</span> oCell.selected = true; }; <span class="comment">/** * Unselects a cell. Calls callbackCellUnselect function. * * <span class="attrib">@private</span> * <span class="attrib">@param</span> {object} oCell Cell object */</span> Zapatec.Grid.<span class="reserved">prototype</span>.unselectCell = <span class="reserved">function</span>(oCell) { <span class="comment">// Check arguments</span> <span class="reserved">if</span> (!oCell || !oCell.selected) { <span class="reserved">return</span>; } <span class="comment">// Unselect cell</span> var undef; oCell.selected = undef; <span class="comment">// Display updates if we are responsible for visualisation</span> <span class="reserved">if</span> (<span class="reserved">this</span>.visualizeUnselectCell && <span class="reserved">this</span>.config.selectCells && <span class="reserved">this</span>.visualize) { <span class="reserved">this</span>.visualizeUnselectCell(oCell); } <span class="comment">// Unselect callback</span> <span class="reserved">if</span> (typeof <span class="reserved">this</span>.config.callbackCellUnselect == <span class="literal">'function'</span>) { <span class="reserved">this</span>.config.callbackCellUnselect(<span class="reserved">this</span>, oCell); } }; <span class="comment">/** * Selects clicked row. Supports multiple selections with "Shift" and "Ctrl" * clicking. Calls callbackCellOnClick function. If callbackCellOnClick is not * defined, calls callbackRowOnClick function. * * <span class="attrib">@private</span> * <span class="attrib">@param</span> {number} iRowId Id of row that was clicked * <span class="attrib">@param</span> {number} iCellId Optional. Id of cell that was clicked */</span> Zapatec.Grid.<span class="reserved">prototype</span>.rowOnClick = <span class="reserved">function</span>(iRowId, iCellId) { <span class="comment">// Get clicked row and cell</span> var oRow = <span class="reserved">this</span>.getRowById(iRowId); <span class="reserved">if</span> (!oRow) { <span class="reserved">return</span>; } var oCell = null; <span class="reserved">if</span> (typeof iCellId != <span class="literal">'undefined'</span>) { oCell = <span class="reserved">this</span>.getCellById(iRowId, iCellId); <span class="reserved">if</span> (!oCell) { <span class="reserved">return</span>; } } <span class="comment">// Process Alt + click in Opera as right click because it doesn't allow to</span> <span class="comment">// turn off context menu programmatically</span> <span class="comment">// Process Meta + click in Safary as right click because it doesn't support</span> <span class="comment">// right click</span> var oEvent = window.event; <span class="reserved">if</span> (oEvent.metaKey || (window.opera && oEvent.altKey)) { <span class="reserved">return</span>; } <span class="comment">// Get modifiers</span> var bShift = false; var bCtrl = false; <span class="reserved">if</span> (<span class="reserved">this</span>.config.multipleSelect) { <span class="comment">// There should be at least one item selected to use "Shift"</span> <span class="reserved">if</span> (<span class="reserved">this</span>.lastSelection) { bShift = oEvent.shiftKey; } <span class="comment">// metaKey for Safari</span> bCtrl = oEvent.ctrlKey || oEvent.metaKey; } <span class="comment">// Unselect rows and cells</span> <span class="reserved">if</span> (!bShift && !bCtrl) { <span class="comment">// Unselect all rows except clicked if "Shift" or "Ctrl" is not holded</span> <span class="reserved">for</span> (var iRow = 0; iRow < <span class="reserved">this</span>.rows.length; iRow++) { var oCurrRow = <span class="reserved">this</span>.rows[iRow]; <span class="reserved">if</span> (!oCurrRow || !oCurrRow.selected) { continue; } <span class="comment">// Unselect all cells except clicked</span> <span class="reserved">if</span> (oCell) { <span class="reserved">for</span> (var iCol = 0; iCol < <span class="reserved">this</span>.fields.length; iCol++) { var oCurrCell = oCurrRow.cells[iCol]; <span class="reserved">if</span> (!oCurrCell) { continue; } <span class="reserved">if</span> (!(oCurrRow.i == iRowId && oCurrCell.i == iCellId)) { <span class="comment">// Unselect cell</span> <span class="reserved">this</span>.unselectCell(oCurrCell); } } } <span class="comment">// Unselect row</span> <span class="reserved">if</span> (oCurrRow.i != iRowId) { <span class="reserved">this</span>.unselectRow(oCurrRow); } } } <span class="reserved">else</span> <span class="reserved">if</span> (bShift) { <span class="comment">// Unselect previous multiple selection</span> <span class="comment">// Unselect rows</span> <span class="reserved">if</span> (<span class="reserved">this</span>.lastSelection.rows instanceof Array) { <span class="reserved">for</span> (var iRow = 0; iRow < <span class="reserved">this</span>.lastSelection.rows.length; iRow++) { <span class="reserved">this</span>.unselectRow(<span class="reserved">this</span>.lastSelection.rows[iRow]); } } <span class="comment">// Unselect cells</span> <span class="reserved">if</span> (<span class="reserved">this</span>.lastSelection.cells instanceof Array) { <span class="reserved">for</span> (var iCell = 0; iCell < <span class="reserved">this</span>.lastSelection.cells.length; iCell++) { <span class="reserved">this</span>.unselectCell(<span class="reserved">this</span>.lastSelection.cells[iCell]); } } } <span class="comment">// OnClick callback</span> <span class="reserved">if</span> (oCell && typeof <span class="reserved">this</span>.config.callbackCellOnClick == <span class="literal">'function'</span>) { <span class="reserved">this</span>.config.callbackCellOnClick(<span class="reserved">this</span>, oCell); } <span class="reserved">else</span> <span class="reserved">if</span> (typeof <span class="reserved">this</span>.config.callbackRowOnClick == <span class="literal">'function'</span>) { <span class="reserved">this</span>.config.callbackRowOnClick(<span class="reserved">this</span>, oRow); } <span class="comment">// Select rows and cells</span> <span class="reserved">if</span> (!bShift) { <span class="comment">// Select row</span> <span class="reserved">this</span>.selectRow(oRow); <span class="reserved">this</span>.lastSelection = { rowId: iRowId }; <span class="comment">// Select cell</span> <span class="reserved">if</span> (oCell) { <span class="reserved">this</span>.selectCell(oCell); <span class="reserved">this</span>.lastSelection.cellId = iCellId; } } <span class="reserved">else</span> { <span class="comment">// Multiple selection</span> var iSelectionStartRowId = <span class="reserved">this</span>.lastSelection.rowId; var iSelectionStartCellId = <span class="reserved">this</span>.lastSelection.cellId; <span class="reserved">this</span>.lastSelection.rows = []; <span class="reserved">this</span>.lastSelection.cells = []; var aSelectedRows = <span class="reserved">this</span>.lastSelection.rows; var aSelectedCells = <span class="reserved">this</span>.lastSelection.cells; <span class="comment">// Get first and last row of the selection</span> var iRow = 0; var iLastRow = 0; <span class="reserved">while</span> (<span class="reserved">this</span>.filteredRows[iRow]) { var iCurrRowId = <span class="reserved">this</span>.filteredRows[iRow].i; <span class="reserved">if</span> (iCurrRowId == iRowId) { iLastRow = iSelectionStartRowId; break; } <span class="reserved">else</span> <span class="reserved">if</span> (iCurrRowId == iSelectionStartRowId) { iLastRow = iRowId; break; } iRow++; } <span class="comment">// Get first and last cell of the selection</span> var iFirstCell = 0; var iLastCell = 0; <span class="reserved">if</span> (oCell && typeof iSelectionStartCellId != <span class="literal">'undefined'</span>) { <span class="reserved">if</span> (iCellId < iSelectionStartCellId) { iFirstCell = iCellId; iLastCell = iSelectionStartCellId; } <span class="reserved">else</span> { iFirstCell = iSelectionStartCellId; iLastCell = iCellId; } } <span class="comment">// Select rows and cells</span> <span class="reserved">while</span> (<span class="reserved">this</span>.filteredRows[iRow]) { var oCurrRow = <span class="reserved">this</span>.filteredRows[iRow]; <span class="comment">// Select row</span> <span class="reserved">if</span> (!oCurrRow.selected) { <span class="reserved">this</span>.selectRow(oCurrRow); aSelectedRows.push(oCurrRow); } <span class="comment">// Select cells</span> <span class="reserved">if</span> (oCell) { <span class="reserved">for</span> (var iCell = iFirstCell; iCell <= iLastCell; iCell++) { var oCurrCell = oCurrRow.cells[iCell]; <span class="comment">// Select cell</span> <span class="reserved">if</span> (!oCurrCell.selected) { <span class="reserved">this</span>.selectCell(oCurrCell); aSelectedCells.push(oCurrCell); } } } <span class="reserved">if</span> (oCurrRow.i == iLastRow) { <span class="comment">// Last row in the selection</span> break; } iRow++; } } }; <span class="comment">/** * Handles click on the row. * * <span class="attrib">@private</span> * <span class="attrib">@param</span> {number} iGridId Id of the grid * <span class="attrib">@param</span> {number} iRowId Id of row that was clicked * <span class="attrib">@param</span> {number} iCellId Optional. Id of cell that was clicked */</span> Zapatec.Grid.rowOnClick = <span class="reserved">function</span>(iGridId, iRowId, iCellId) { <span class="comment">// Get grid object</span> var oGrid = Zapatec.Widget.getWidgetById(iGridId); <span class="reserved">if</span> (oGrid && oGrid.rowOnClick) { <span class="comment">// Call method</span> oGrid.rowOnClick(iRowId, iCellId); } }; <span class="comment">/** * Calls callbackCellOnDblClick function. If callbackCellOnDblClick is not * defined, calls callbackRowOnDblClick function. * * <span class="attrib">@private</span> * <span class="attrib">@param</span> {number} iRowId Id of row that was clicked * <span class="attrib">@param</span> {number} iCellId Optional. Id of cell that was clicked */</span> Zapatec.Grid.<span class="reserved">prototype</span>.rowOnDblClick = <span class="reserved">function</span>(iRowId, iCellId) { <span class="comment">// Get double clicked row and cell</span> var oRow = <span class="reserved">this</span>.getRowById(iRowId); <span class="reserved">if</span> (!oRow) { <span class="reserved">return</span>; } var oCell = null; <span class="reserved">if</span> (typeof iCellId != <span class="literal">'undefined'</span>) { oCell = <span class="reserved">this</span>.getCellById(iRowId, iCellId); <span class="reserved">if</span> (!oCell) { <span class="reserved">return</span>; } } <span class="comment">// OnDblClick callback</span> <span class="reserved">if</span> (oCell && typeof <span class="reserved">this</span>.config.callbackCellOnDblClick == <span class="literal">'function'</span>) { <span class="reserved">this</span>.config.callbackCellOnDblClick(<span class="reserved">this</span>, oCell); } <span class="reserved">else</span> <span class="reserved">if</span> (typeof <span class="reserved">this</span>.config.callbackRowOnDblClick == <span class="literal">'function'</span>) { <span class="reserved">this</span>.config.callbackRowOnDblClick(<span class="reserved">this</span>, oRow); } }; <span class="comment">/** * Handles double click on the row. * * <span class="attrib">@private</span> * <span class="attrib">@param</span> {number} iGridId Id of the grid * <span class="attrib">@param</span> {number} iRowId Id of row that was clicked * <span class="attrib">@param</span> {number} iCellId Optional. Id of cell that was clicked */</span> Zapatec.Grid.rowOnDblClick = <span class="reserved">function</span>(iGridId, iRowId, iCellId) { <span class="comment">// Get grid object</span> var oGrid = Zapatec.Widget.getWidgetById(iGridId); <span class="reserved">if</span> (oGrid && oGrid.rowOnDblClick) { <span class="comment">// Call method</span> oGrid.rowOnDblClick(iRowId, iCellId); } }; <span class="comment">/** * Unselects all selected rows and cells. */</span> Zapatec.Grid.<span class="reserved">prototype</span>.clearSelection = <span class="reserved">function</span>() { <span class="comment">// Unselect all rows</span> <span class="reserved">for</span> (var iRow = 0; iRow < <span class="reserved">this</span>.rows.length; iRow++) { var oCurrRow = <span class="reserved">this</span>.rows[iRow]; <span class="reserved">if</span> (oCurrRow.selected) { <span class="comment">// Unselect all cells</span> <span class="reserved">for</span> (var iCol = 0; iCol < oCurrRow.cells.length; iCol++) { <span class="reserved">this</span>.unselectCell(oCurrRow.cells[iCol]); } <span class="comment">// Unselect row</span> <span class="reserved">this</span>.unselectRow(oCurrRow); } } }; <span class="comment">/** * Returns selected rows in an array. * * <span class="attrib">@return</span> Array of row objects * <span class="attrib">@type</span> object */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getSelectedRows = <span class="reserved">function</span>() { var aSelected = []; <span class="reserved">for</span> (var iRow = 0; iRow < <span class="reserved">this</span>.rows.length; iRow++) { var oCurrRow = <span class="reserved">this</span>.rows[iRow]; <span class="reserved">if</span> (oCurrRow.selected) { aSelected.push(oCurrRow); } } <span class="reserved">return</span> aSelected; }; <span class="comment">/** * Returns selected cells in an array. * * <span class="attrib">@return</span> Array of cell objects * <span class="attrib">@type</span> object */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getSelectedCells = <span class="reserved">function</span>() { var aSelected = []; <span class="reserved">for</span> (var iRow = 0; iRow < <span class="reserved">this</span>.rows.length; iRow++) { var oCurrRow = <span class="reserved">this</span>.rows[iRow]; <span class="reserved">if</span> (oCurrRow.selected) { <span class="reserved">for</span> (var iCol = 0; iCol < <span class="reserved">this</span>.fields.length; iCol++) { var oCurrCell = oCurrRow.cells[iCol]; <span class="reserved">if</span> (oCurrCell.selected) { aSelected.push(oCurrCell); } } } } <span class="reserved">return</span> aSelected; }; <span class="comment">/** * Returns rows with cells having invalid value in an array. * * <span class="attrib">@return</span> Array of row objects * <span class="attrib">@type</span> object */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getInvalidRows = <span class="reserved">function</span>() { var aInvalid = []; <span class="reserved">for</span> (var iRow = 0; iRow < <span class="reserved">this</span>.rows.length; iRow++) { var oCurrRow = <span class="reserved">this</span>.rows[iRow]; <span class="reserved">if</span> (oCurrRow.invalid) { aInvalid.push(oCurrRow); } } <span class="reserved">return</span> aInvalid; }; <span class="comment">/** * Returns cells having invalid value in an array. * * <span class="attrib">@return</span> Array of cell objects * <span class="attrib">@type</span> object */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getInvalidCells = <span class="reserved">function</span>() { var aInvalid = []; <span class="reserved">for</span> (var iRow = 0; iRow < <span class="reserved">this</span>.rows.length; iRow++) { var oCurrRow = <span class="reserved">this</span>.rows[iRow]; <span class="reserved">if</span> (oCurrRow.invalid) { <span class="reserved">for</span> (var iCol = 0; iCol < <span class="reserved">this</span>.fields.length; iCol++) { var oCurrCell = oCurrRow.cells[iCol]; <span class="reserved">if</span> (oCurrCell.invalid) { aInvalid.push(oCurrCell); } } } } <span class="reserved">return</span> aInvalid; }; <span class="comment">/** * Handles the click on filter out checkbox. Filters out rows if checkbox is * unchecked. Shows rows if checkbox is checked. * * <span class="attrib">@private</span> * <span class="attrib">@param</span> {string} iGridId Grid id * <span class="attrib">@param</span> {object} aCols Array of zero-based column numbers or single zero * based column number to filter * <span class="attrib">@param</span> {string} sVal Value to filter out * <span class="attrib">@param</span> {boolean} bChecked Show rows having this value or not */</span> Zapatec.Grid.checkboxOnClick = <span class="reserved">function</span>(iGridId, aCols, sVal, bChecked) { <span class="comment">// Get grid object</span> var oGrid = Zapatec.Widget.getWidgetById(iGridId); <span class="reserved">if</span> (oGrid && oGrid.filterOut) { <span class="comment">// Filter out grid</span> oGrid.filterOut({ column: aCols, value: sVal, show: bChecked }); } }; <span class="comment">/** * Handles the click on "Select all" link inside filter out form. Removes all * hidden values from the specified columns. * * <span class="attrib">@private</span> * <span class="attrib">@param</span> {string} iGridId Grid id * <span class="attrib">@param</span> {object} aCols Array of zero-based column numbers or single zero * based column number to remove hidden values from */</span> Zapatec.Grid.checkboxSelectAllOnClick = <span class="reserved">function</span>(iGridId, aCols) { <span class="comment">// Get grid object</span> var oGrid = Zapatec.Widget.getWidgetById(iGridId); <span class="reserved">if</span> (!oGrid || !oGrid.unfilterOutColumn || !oGrid.applyFilters || !oGrid.displayFilterOut) { <span class="reserved">return</span> } <span class="comment">// Remove hidden values</span> var bApply = oGrid.unfilterOutColumn({ column: aCols }); <span class="comment">// Apply filters</span> <span class="reserved">if</span> (bApply) { oGrid.applyFilters(); <span class="comment">// Refresh filter out forms</span> oGrid.displayFilterOut(); } }; <span class="comment">/** * Handles the click on "Clear all" link inside filter out form. Hides rows by * making all values of the specified columns hidden. * * <span class="attrib">@private</span> * <span class="attrib">@param</span> {string} iGridId Grid id * <span class="attrib">@param</span> {object} aCols Array of zero-based column numbers or single zero * based column number to filter */</span> Zapatec.Grid.checkboxClearAllOnClick = <span class="reserved">function</span>(iGridId, aCols) { <span class="comment">// Get grid object</span> var oGrid = Zapatec.Widget.getWidgetById(iGridId); <span class="reserved">if</span> (!oGrid || !oGrid.getColumnRange || !oGrid.filterOutColumn || !oGrid.applyFilters || !oGrid.displayFilterOut) { <span class="reserved">return</span>; } <span class="comment">// Get column range</span> var oRange = oGrid.getColumnRange({ column: aCols }); <span class="reserved">if</span> (!oRange) { <span class="reserved">return</span>; } <span class="comment">// Get unique values</span> var aVals = []; <span class="reserved">for</span> (var iVal = 0; iVal < oRange.values.length; iVal++) { aVals.push(oRange.values[iVal].v + <span class="literal">''</span>); } <span class="comment">// Filter out grid</span> var bApply = oGrid.filterOutColumn({ column: aCols, value: aVals, show: false }); <span class="comment">// Apply filters</span> <span class="reserved">if</span> (bApply) { oGrid.applyFilters(); <span class="comment">// Refresh filter out forms</span> oGrid.displayFilterOut(); } }; <span class="comment">/** * Handles the click on filter out link. Filters out all rows that don't have * specified value in the specified columns. * * <span class="attrib">@private</span> * <span class="attrib">@param</span> {string} iGridId Grid id * <span class="attrib">@param</span> {object} aCols Array of zero-based column numbers or single zero * based column number to filter * <span class="attrib">@param</span> {string} sVal Selected value to show */</span> Zapatec.Grid.checkboxLinkOnClick = <span class="reserved">function</span>(iGridId, aCols, sVal) { <span class="comment">// Get grid object</span> var oGrid = Zapatec.Widget.getWidgetById(iGridId); <span class="reserved">if</span> (!oGrid || !oGrid.getColumnRange || !oGrid.filterOutColumn || !oGrid.applyFilters || !oGrid.displayFilterOut) { <span class="reserved">return</span>; } <span class="comment">// Get column range</span> var oRange = oGrid.getColumnRange({ column: aCols }); <span class="reserved">if</span> (!oRange) { <span class="reserved">return</span>; } <span class="comment">// Get unique values</span> var aVals = []; <span class="reserved">for</span> (var iVal = 0; iVal < oRange.values.length; iVal++) { aVals.push(oRange.values[iVal].v + <span class="literal">''</span>); } <span class="comment">// Clear all</span> var bClear = oGrid.filterOutColumn({ column: aCols, value: aVals, show: false }); <span class="comment">// Show selected value</span> var bShow = oGrid.filterOutColumn({ column: aCols, value: sVal, show: true }); <span class="comment">// Apply filters</span> <span class="reserved">if</span> (bClear || bShow) { oGrid.applyFilters(); <span class="comment">// Refresh filter out forms</span> oGrid.displayFilterOut(); } }; <span class="comment">/** * Adds filter out to the Grid. See <b>filterOut</b> config option for details. * * <span class="attrib">@param</span> {object} oArg Argument object (see <b>filterOut</b> config option for * description) */</span> Zapatec.Grid.<span class="reserved">prototype</span>.addFilterOut = <span class="reserved">function</span>(oArg) { <span class="reserved">this</span>.filterOutRules.push(oArg); }; <span class="comment">/** * Displays filter out forms. Useful after {<span class="attrib">@link</span> Zapatec.Grid#addFilterOut}. */</span> Zapatec.Grid.<span class="reserved">prototype</span>.displayFilterOut = <span class="reserved">function</span>() { <span class="comment">// Go through all filterOut arguments</span> var aFilterOutRules = <span class="reserved">this</span>.filterOutRules; var iFilterOutRules = aFilterOutRules.length; <span class="reserved">for</span> (var iFo = 0; iFo < iFilterOutRules; iFo++) { var oFilterOut = aFilterOutRules[iFo]; <span class="comment">// Get column range</span> var oRange = <span class="reserved">this</span>.getColumnRange(oFilterOut); <span class="reserved">if</span> (!oRange) { continue; } <span class="comment">// Get unique values</span> var aVals = oRange.values; <span class="comment">// Sort in descending order if needed</span> <span class="reserved">if</span> (oFilterOut.sortDesc) { aVals.sort(<span class="reserved">function</span>(leftVal, rightVal) { <span class="reserved">if</span> (leftVal.c < rightVal.c) { <span class="reserved">return</span> 1; } <span class="reserved">if</span> (leftVal.c > rightVal.c) { <span class="reserved">return</span> -1; } <span class="reserved">return</span> 0; }); } <span class="comment">// Display form</span> <span class="reserved">if</span> (typeof oFilterOut.callback == <span class="literal">'function'</span>) { <span class="comment">// Get columns</span> var aCols = oFilterOut.column; <span class="reserved">if</span> (!(aCols instanceof Array)) { aCols = [aCols]; } <span class="comment">// Get fields</span> var aFields = []; <span class="reserved">for</span> (var iCol = 0; iCol < aCols.length; iCol++) { var oField = <span class="reserved">this</span>.fields[aCols[iCol]]; <span class="reserved">if</span> (!oField) { continue; } aFields.push(oField); } <span class="reserved">if</span> (!aFields.length) { continue; } <span class="comment">// Join column numbers</span> var sCols = aCols.join(<span class="literal">','</span>); <span class="comment">// Use callback function</span> var aChoices = []; <span class="reserved">for</span> (var iVal = 0; iVal < aVals.length; iVal++) { var sVal = aVals[iVal].v + <span class="literal">''</span>; var sEscaped = escape(sVal); var oChoice = {}; oChoice.value = sVal; oChoice.onclick = <span class="literal">"Zapatec.Grid.checkboxOnClick('"</span> + <span class="reserved">this</span>.id + <span class="literal">"',["</span> + sCols + <span class="literal">"],unescape('"</span> + sEscaped + <span class="literal">"'),this.checked)"</span>; <span class="comment">// Check if this value is hidden</span> oChoice.checked = false; <span class="reserved">for</span> (var iField = 0; iField < aFields.length; iField++) { var oField = aFields[iField]; <span class="reserved">if</span> (!(oField.hiddenValues instanceof Array) || Zapatec.Utils.arrIndexOf(oField.hiddenValues, sVal) < 0) { oChoice.checked = true; break; } } oChoice.link = <span class="literal">"Zapatec.Grid.checkboxLinkOnClick('"</span> + <span class="reserved">this</span>.id + <span class="literal">"',["</span> + sCols + <span class="literal">"],unescape('"</span> + sEscaped + <span class="literal">"'))"</span>; <span class="reserved">if</span> (iVal == 0) { oChoice.selectall = <span class="literal">"Zapatec.Grid.checkboxSelectAllOnClick('"</span> + <span class="reserved">this</span>.id + <span class="literal">"',["</span> + sCols + <span class="literal">"])"</span>; oChoice.clearall = <span class="literal">"Zapatec.Grid.checkboxClearAllOnClick('"</span> + <span class="reserved">this</span>.id + <span class="literal">"',["</span> + sCols + <span class="literal">"])"</span>; } aChoices.push(oChoice); } oFilterOut.callback(aChoices); } <span class="reserved">else</span> <span class="reserved">if</span> (<span class="reserved">this</span>.visualizeFilterOut) { <span class="comment">// Use container</span> <span class="reserved">this</span>.visualizeFilterOut(oFilterOut, aVals); } } }; <span class="comment">/** * Returns range of values of the specified column. If field property * "columnRange" of the column is defined, it is returned instead. If array of * column numbers is passed, concatenates all specified columns and returns * range of values of the result. * * <pre> * Argument object format: * { * column: [object or number] array of zero-based column numbers or single * zero-based column number, * filtered: [boolean] use only filtered rows * } * * Return object format: * { * min: [any] min value to compare, * minValue: [string] min value to display, * minOrig: [any] min original value, * max: [any] max value to compare, * maxValue: [string] max value to display, * maxOrig: [any] max original value, * values: [object] array of unique column values in the following format: * [ * { * c: [any] value to compare, * v: [string] value to display, * o: [any] original value * }, * ... * ] * } * </pre> * * <span class="attrib">@param</span> {object} oArg Argument object * <span class="attrib">@return</span> Range of column values or null * <span class="attrib">@type</span> object */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getColumnRange = <span class="reserved">function</span>(oArg) { <span class="comment">// Check arguments</span> <span class="reserved">if</span> (!oArg || typeof oArg.column == <span class="literal">'undefined'</span>) { <span class="reserved">return</span> null; } <span class="comment">// Get columns</span> var aCols = oArg.column; <span class="reserved">if</span> (!(aCols instanceof Array)) { <span class="comment">// Single column number was passed</span> var oField = <span class="reserved">this</span>.fields[oArg.column]; <span class="reserved">if</span> (!oField) { <span class="reserved">return</span> null; } <span class="comment">// Get range defined by user</span> <span class="reserved">if</span> (typeof oField.columnRange != <span class="literal">'undefined'</span>) { <span class="reserved">return</span> oField.columnRange; } <span class="comment">// Form array</span> aCols = [oArg.column]; } <span class="comment">// Get array of keys</span> var aKeys = []; <span class="comment">// Auxiliary associative array</span> var oKeys = {}; var aRows = oArg.filtered ? <span class="reserved">this</span>.filteredRows : <span class="reserved">this</span>.rows; <span class="reserved">for</span> (var iRow = 0; iRow < aRows.length; iRow++) { <span class="comment">// Get row</span> var oRow = aRows[iRow]; <span class="reserved">if</span> (!oRow) { continue; } <span class="comment">// For each passed column</span> <span class="reserved">for</span> (var iCol = 0; iCol < aCols.length; iCol++) { <span class="comment">// Get cell</span> var oCell = oRow.cells[aCols[iCol]]; <span class="reserved">if</span> (!oCell) { continue; } <span class="comment">// Get cell value</span> var sKey = <span class="reserved">this</span>.getCellValueString(oCell); <span class="reserved">if</span> (sKey.length && typeof oKeys[sKey] == <span class="literal">'undefined'</span>) { aKeys.push({ v: sKey, c: <span class="reserved">this</span>.getCellValueCompare(oCell), o: <span class="reserved">this</span>.getCellValueOriginal(oCell) }); oKeys[sKey] = true; } } } <span class="reserved">if</span> (!aKeys.length) { <span class="comment">// Empty array</span> <span class="reserved">return</span> null; } <span class="comment">// Sort array of keys</span> aKeys.sort(<span class="reserved">function</span>(leftVal, rightVal) { <span class="reserved">if</span> (leftVal.c < rightVal.c) { <span class="reserved">return</span> -1; } <span class="reserved">if</span> (leftVal.c > rightVal.c) { <span class="reserved">return</span> 1; } <span class="reserved">return</span> 0; }); <span class="comment">// Return range of column values</span> var iLastKey = aKeys.length - 1; <span class="reserved">return</span> { min: aKeys[0].c, minValue: aKeys[0].v, minOrig: aKeys[0].o, max: aKeys[iLastKey].c, maxValue: aKeys[iLastKey].v, maxOrig: aKeys[iLastKey].o, values: aKeys }; }; <span class="comment">/** * Returns number of rows that are currently displayed. * * <span class="attrib">@return</span> How many rows are currently displayed * <span class="attrib">@type</span> number */</span> Zapatec.Grid.<span class="reserved">prototype</span>.recordsDisplayed = <span class="reserved">function</span>() { <span class="reserved">if</span> (<span class="reserved">this</span>.config.dataOnDemand && typeof <span class="reserved">this</span>.data.displayedRows != <span class="literal">'undefined'</span>) { <span class="reserved">return</span> <span class="reserved">this</span>.data.displayedRows * 1; } <span class="reserved">return</span> <span class="reserved">this</span>.filteredRows.length; }; <span class="comment">/** * Sets number of currently displayed rows. Effective only when dataOnDemand * config option is used. * * <span class="attrib">@param</span> {number} iRows Number of currently displayed rows */</span> Zapatec.Grid.<span class="reserved">prototype</span>.setDisplayedRows = <span class="reserved">function</span>(iRows) { <span class="reserved">if</span> (<span class="reserved">this</span>.config.dataOnDemand) { <span class="reserved">this</span>.data.displayedRows = iRows; } }; <span class="comment">/** * Returns total number of rows. * * <span class="attrib">@return</span> Total number of rows * <span class="attrib">@type</span> number */</span> Zapatec.Grid.<span class="reserved">prototype</span>.totalRecords = <span class="reserved">function</span>() { <span class="reserved">if</span> (<span class="reserved">this</span>.config.dataOnDemand && typeof <span class="reserved">this</span>.data.totalRows != <span class="literal">'undefined'</span>) { <span class="reserved">return</span> <span class="reserved">this</span>.data.totalRows * 1; } <span class="reserved">return</span> <span class="reserved">this</span>.rows.length; }; <span class="comment">/** * Sets total number of rows. Effective only when dataOnDemand config option is * used. * * <span class="attrib">@param</span> {number} iRows Total number of rows */</span> Zapatec.Grid.<span class="reserved">prototype</span>.setTotalRows = <span class="reserved">function</span>(iRows) { <span class="reserved">if</span> (<span class="reserved">this</span>.config.dataOnDemand) { <span class="reserved">this</span>.data.totalRows = iRows; } }; <span class="comment">/** * Returns grid id. * * <span class="attrib">@return</span> Grid id * <span class="attrib">@type</span> number */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getId = <span class="reserved">function</span>() { <span class="reserved">return</span> <span class="reserved">this</span>.id; }; <span class="comment">/** * Returns grid style defined by user. * * <span class="attrib">@return</span> Grid style * <span class="attrib">@type</span> string */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getStyle = <span class="reserved">function</span>() { <span class="reserved">if</span> (<span class="reserved">this</span>.data && <span class="reserved">this</span>.data.style) { <span class="reserved">return</span> <span class="reserved">this</span>.data.style; } <span class="reserved">return</span> <span class="literal">''</span>; }; <span class="comment">/** * Returns grid header style defined by user. * * <span class="attrib">@return</span> Grid header style * <span class="attrib">@type</span> string */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getHeaderStyle = <span class="reserved">function</span>() { <span class="reserved">if</span> (<span class="reserved">this</span>.data && <span class="reserved">this</span>.data.headerStyle) { <span class="reserved">return</span> <span class="reserved">this</span>.data.headerStyle; } <span class="reserved">return</span> <span class="literal">''</span>; }; <span class="comment">/** * Returns reference to private array containing grid rows. * * <span class="attrib">@return</span> Grid rows array * <span class="attrib">@type</span> object */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getRows = <span class="reserved">function</span>() { <span class="reserved">return</span> <span class="reserved">this</span>.rows; }; <span class="comment">/** * Returns reference to private array containing filtered rows. Note: to get * currently displayed rows use {<span class="attrib">@link</span> Zapatec.Grid#applyPaging} method instead. * * <span class="attrib">@return</span> Filtered rows array * <span class="attrib">@type</span> object */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getFilteredRows = <span class="reserved">function</span>() { <span class="reserved">return</span> <span class="reserved">this</span>.filteredRows; }; <span class="comment">/** * Returns row id. * * <span class="attrib">@param</span> {object} oRow Row object * <span class="attrib">@return</span> Row id or undefined if not found * <span class="attrib">@type</span> number */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getRowId = <span class="reserved">function</span>(oRow) { <span class="reserved">if</span> (oRow) { <span class="reserved">return</span> oRow.i; } }; <span class="comment">/** * Finds row id by primary key value. * * <span class="attrib">@private</span> * <span class="attrib">@param</span> {string} sKey primary key value * <span class="attrib">@return</span> Row id or undefined if not found * <span class="attrib">@type</span> number */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getRowIdByPrimaryKey = <span class="reserved">function</span>(sKey) { <span class="reserved">return</span> <span class="reserved">this</span>.getRowId(<span class="reserved">this</span>.getRowByPrimaryKey(sKey)); }; <span class="comment">/** * Returns visible row number. * * <span class="attrib">@param</span> {object} oRow Row object * <span class="attrib">@return</span> Row number or undefined if not found * <span class="attrib">@type</span> number */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getRowNumber = <span class="reserved">function</span>(oRow) { <span class="reserved">if</span> (oRow) { var iRowId = <span class="reserved">this</span>.getRowId(oRow); var aRows = <span class="reserved">this</span>.applyPaging(); <span class="reserved">for</span> (var iRow = 0; iRow < aRows.length; iRow++) { <span class="reserved">if</span> (<span class="reserved">this</span>.getRowId(aRows[iRow]) == iRowId) { <span class="reserved">return</span> iRow; } } } }; <span class="comment">/** * Returns row index in the internal rows array. * * <span class="attrib">@private</span> * <span class="attrib">@param</span> {number} iRowId Row id * <span class="attrib">@return</span> Row number or undefined if not found * <span class="attrib">@type</span> number */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getRowIndexById = <span class="reserved">function</span>(iRowId) { <span class="reserved">for</span> (var iRow = 0; iRow < <span class="reserved">this</span>.rows.length; iRow++) { <span class="reserved">if</span> (<span class="reserved">this</span>.getRowId(<span class="reserved">this</span>.rows[iRow]) == iRowId) { <span class="reserved">return</span> iRow; } } }; <span class="comment">/** * Returns row style defined by user. * * <span class="attrib">@param</span> {object} oRow Row object * <span class="attrib">@return</span> Row style * <span class="attrib">@type</span> string */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getRowStyle = <span class="reserved">function</span>(oRow) { <span class="reserved">if</span> (oRow && oRow.style) { <span class="reserved">return</span> oRow.style; } <span class="reserved">return</span> <span class="literal">''</span>; }; <span class="comment">/** * Returns true if row is selected. * * <span class="attrib">@param</span> {object} oRow Row object * <span class="attrib">@return</span> true if row is selected * <span class="attrib">@type</span> boolean */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getRowSelected = <span class="reserved">function</span>(oRow) { <span class="reserved">return</span> (oRow && oRow.selected); }; <span class="comment">/** * Finds row by its id. * * <span class="attrib">@param</span> {number} iRowId Row id * <span class="attrib">@return</span> Row object or undefined if not found * <span class="attrib">@type</span> object */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getRowById = <span class="reserved">function</span>(iRowId) { <span class="reserved">return</span> <span class="reserved">this</span>.rowsIndex[iRowId]; }; <span class="comment">/** * Finds row by primary key value. * * <span class="attrib">@private</span> * <span class="attrib">@param</span> {string} sKey primary key value * <span class="attrib">@return</span> Row object or undefined if not found * <span class="attrib">@type</span> object */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getRowByPrimaryKey = <span class="reserved">function</span>(sKey) { <span class="reserved">if</span> (<span class="reserved">this</span>.primaryKey) { <span class="reserved">return</span> <span class="reserved">this</span>.primaryKey[sKey]; } }; <span class="comment">/** * Finds row by cell. * * <span class="attrib">@param</span> {object} oCell Cell object * <span class="attrib">@return</span> Row object or undefined if not found * <span class="attrib">@type</span> object */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getRowByCell = <span class="reserved">function</span>(oCell) { <span class="reserved">if</span> (oCell) { <span class="reserved">return</span> <span class="reserved">this</span>.getRowById(oCell.r); } }; <span class="comment">/** * Returns cells array of the row. * * <span class="attrib">@param</span> {object} oRow Row object * <span class="attrib">@return</span> Array of cell objects or undefined if not found * <span class="attrib">@type</span> object */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getRowCells = <span class="reserved">function</span>(oRow) { <span class="reserved">if</span> (oRow && oRow.cells instanceof Array) { <span class="reserved">return</span> oRow.cells; } }; <span class="comment">/** * Sets row style. * * <span class="attrib">@param</span> {object} oRow Row object * <span class="attrib">@param</span> {string} sStyle New row style * <span class="attrib">@return</span> Updated row object * <span class="attrib">@type</span> object */</span> Zapatec.Grid.<span class="reserved">prototype</span>.setRowStyle = <span class="reserved">function</span>(oRow, sStyle) { <span class="reserved">if</span> (oRow instanceof Object) { oRow.style = sStyle; } <span class="reserved">return</span> oRow; }; <span class="comment">/** * Returns reference to private array containing grid fields. * * <pre> * Arguments format: * { * visible: [boolean, optional] if true, result array will contain only * visible fields * } * </pre> * * <span class="attrib">@param</span> {object} oArg Arguments * <span class="attrib">@return</span> Grid fields array * <span class="attrib">@type</span> object */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getFields = <span class="reserved">function</span>(oArg) { var aFields = <span class="reserved">this</span>.fields; <span class="reserved">if</span> (oArg && oArg.visible) { <span class="comment">// Create new array with only visible fields</span> var aVisibleFields = []; var iFields = aFields.length; var oField; <span class="reserved">for</span> (var iField = 0; iField < iFields; iField++) { oField = aFields[iField]; <span class="reserved">if</span> (!oField.hidden) { aVisibleFields.push(oField); } } aFields = aVisibleFields; } <span class="reserved">return</span> aFields; }; <span class="comment">/** * Returns field id. * * <span class="attrib">@param</span> {object} oField Field object * <span class="attrib">@return</span> Field id or undefined if not found * <span class="attrib">@type</span> number */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getFieldId = <span class="reserved">function</span>(oField) { <span class="reserved">if</span> (oField) { <span class="reserved">return</span> oField.i; } }; <span class="comment">/** * Returns column title. * * <span class="attrib">@param</span> {object} oField Field object * <span class="attrib">@return</span> Column title * <span class="attrib">@type</span> string */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getFieldTitle = <span class="reserved">function</span>(oField) { <span class="reserved">if</span> (oField && oField.title) { <span class="reserved">return</span> oField.title; } <span class="reserved">return</span> <span class="literal">''</span>; }; <span class="comment">/** * Returns field data type. * * <span class="attrib">@param</span> {object} oField Field object * <span class="attrib">@return</span> Field data type or undefined if not found * <span class="attrib">@type</span> string */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getFieldType = <span class="reserved">function</span>(oField) { <span class="reserved">if</span> (oField) { <span class="reserved">return</span> oField.dataType; } }; <span class="comment">/** * Returns column width defined by user. * * <span class="attrib">@param</span> {object} oField Field object * <span class="attrib">@return</span> Column width * <span class="attrib">@type</span> string */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getFieldWidth = <span class="reserved">function</span>(oField) { <span class="reserved">if</span> (oField && oField.columnWidth) { <span class="reserved">return</span> oField.columnWidth; } <span class="reserved">return</span> <span class="literal">''</span>; }; <span class="comment">/** * Returns field style defined by user. * * <span class="attrib">@param</span> {object} oField Field object * <span class="attrib">@return</span> Field style * <span class="attrib">@type</span> string */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getFieldStyle = <span class="reserved">function</span>(oField) { <span class="reserved">if</span> (oField && oField.style) { <span class="reserved">return</span> oField.style; } <span class="reserved">return</span> <span class="literal">''</span>; }; <span class="comment">/** * Returns spanned columns number and spanned fields array. If there is no span, * returns undefined. * * <pre> * Format of returned object: * { * spanned: [number] spanned columns number, * fields: [object] array of spanned field objects * } * </pre> * * <span class="attrib">@param</span> {object} oField Field object * <span class="attrib">@return</span> Span properties * <span class="attrib">@type</span> object */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getFieldSpanned = <span class="reserved">function</span>(oField) { <span class="reserved">if</span> (!oField) { <span class="reserved">return</span>; } <span class="comment">// Get span start field</span> var iSpan = parseInt(oField.span); <span class="reserved">if</span> (isNaN(iSpan)) { var iId = oField.i; <span class="reserved">for</span> (var iOffset = 1; iOffset <= iId; iOffset++) { oField = <span class="reserved">this</span>.fields[iId - iOffset]; <span class="reserved">if</span> (!oField || !oField.hidden) { <span class="reserved">return</span>; } iSpan = parseInt(oField.span); <span class="reserved">if</span> (!isNaN(iSpan)) { break; } } } <span class="reserved">if</span> (isNaN(iSpan) || iSpan <= 0) { <span class="reserved">return</span>; } <span class="comment">// Prevent invalid spans and remove hidden fields from span</span> var aFields = []; var iSpanned = 0; <span class="reserved">for</span> (var iOffset = 0; iOffset < iSpan; iOffset++) { var oF = <span class="reserved">this</span>.fields[oField.i + iOffset]; <span class="reserved">if</span> (!oF) { continue; } <span class="reserved">if</span> (iOffset > 0 && !isNaN(parseInt(oF.span))) { break; } aFields.push(oF); <span class="reserved">if</span> (!oF.hidden) { iSpanned++; } } <span class="reserved">if</span> (!iSpanned) { <span class="reserved">return</span>; } <span class="comment">// Form result</span> <span class="reserved">return</span> { spanned: iSpanned, fields: aFields }; }; <span class="comment">/** * Returns field span value. * * <span class="attrib">@param</span> {object} oField Field object * <span class="attrib">@return</span> Span title * <span class="attrib">@type</span> string */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getFieldSpan = <span class="reserved">function</span>(oField) { <span class="reserved">if</span> (oField) { var iSpan = parseInt(oField.span); <span class="reserved">if</span> (!isNaN(iSpan)) { <span class="reserved">return</span> Math.max(iSpan, 0); } } <span class="reserved">return</span> 0; }; <span class="comment">/** * Returns field span title. * * <span class="attrib">@param</span> {object} oField Field object * <span class="attrib">@return</span> Span title * <span class="attrib">@type</span> string */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getFieldSpanTitle = <span class="reserved">function</span>(oField) { <span class="reserved">if</span> (oField && oField.spanTitle) { <span class="reserved">return</span> oField.spanTitle; } <span class="reserved">return</span> <span class="literal">''</span>; }; <span class="comment">/** * Returns field span style defined by user. * * <span class="attrib">@param</span> {object} oField Field object * <span class="attrib">@return</span> Span style * <span class="attrib">@type</span> string */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getFieldSpanStyle = <span class="reserved">function</span>(oField) { <span class="reserved">if</span> (oField && oField.spanStyle) { <span class="reserved">return</span> oField.spanStyle; } <span class="reserved">return</span> <span class="literal">''</span>; }; <span class="comment">/** * Returns true if field is hidden. * * <span class="attrib">@param</span> {object} oField Field object * <span class="attrib">@return</span> True if field is hidden * <span class="attrib">@type</span> boolean */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getFieldHidden = <span class="reserved">function</span>(oField) { <span class="reserved">if</span> (oField) { <span class="reserved">return</span> oField.hidden; } }; <span class="comment">/** * Returns true if it is not allowed to sort the field. * * <span class="attrib">@param</span> {object} oField Field object * <span class="attrib">@return</span> True if it is not allowed to sort the field * <span class="attrib">@type</span> boolean */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getFieldNosort = <span class="reserved">function</span>(oField) { <span class="reserved">if</span> (oField) { <span class="reserved">return</span> oField.nosort; } }; <span class="comment">/** * Returns true if the field is sorted ascending. * * <span class="attrib">@param</span> {object} oField Field object * <span class="attrib">@return</span> True if the field is sorted ascending * <span class="attrib">@type</span> boolean */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getFieldSorted = <span class="reserved">function</span>(oField) { <span class="reserved">if</span> (oField) { <span class="reserved">return</span> oField.sorted; } }; <span class="comment">/** * Returns true if the field is sorted descending. * * <span class="attrib">@param</span> {object} oField Field object * <span class="attrib">@return</span> True if the field is sorted descending * <span class="attrib">@type</span> boolean */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getFieldSortedDesc = <span class="reserved">function</span>(oField) { <span class="reserved">if</span> (oField) { <span class="reserved">return</span> oField.sortedDesc; } }; <span class="comment">/** * Forms field onclick attribute value. * * <span class="attrib">@param</span> {object} oField Field object * <span class="attrib">@return</span> Field onclick attribute value * <span class="attrib">@type</span> string */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getFieldOnclick = <span class="reserved">function</span>(oField) { <span class="reserved">if</span> (oField && !oField.nosort) { <span class="reserved">return</span> <span class="literal">"Zapatec.Grid.sort('"</span> + <span class="reserved">this</span>.id + <span class="literal">"','"</span> + oField.i + <span class="literal">"')"</span>; } <span class="reserved">return</span> <span class="literal">''</span>; }; <span class="comment">/** * Finds field by its id. * * <span class="attrib">@param</span> {number} iFieldId Field id * <span class="attrib">@return</span> Field object or undefined if not found * <span class="attrib">@type</span> object */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getFieldById = <span class="reserved">function</span>(iFieldId) { <span class="reserved">return</span> <span class="reserved">this</span>.fields[iFieldId]; }; <span class="comment">/** * Finds field by cell. * * <span class="attrib">@param</span> {object} oCell Cell object * <span class="attrib">@return</span> Field object or undefined if not found * <span class="attrib">@type</span> object */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getFieldByCell = <span class="reserved">function</span>(oCell) { <span class="reserved">if</span> (oCell) { <span class="reserved">return</span> <span class="reserved">this</span>.getFieldById(oCell.i); } }; <span class="comment">/** * Returns cell id. * * <span class="attrib">@param</span> {object} oCell Cell object * <span class="attrib">@return</span> Cell id or undefined if not found * <span class="attrib">@type</span> number */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getCellId = <span class="reserved">function</span>(oCell) { <span class="reserved">if</span> (oCell) { <span class="reserved">return</span> oCell.i; } }; <span class="comment">/** * Returns cell row id. * * <span class="attrib">@param</span> {object} oCell Cell object * <span class="attrib">@return</span> Cell row id or undefined if not found * <span class="attrib">@type</span> number */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getCellRowId = <span class="reserved">function</span>(oCell) { <span class="reserved">if</span> (oCell) { <span class="reserved">return</span> oCell.r; } }; <span class="comment">/** * Returns cell visible row number. * * <span class="attrib">@param</span> {object} oCell Cell object * <span class="attrib">@return</span> Cell row number or undefined if not found * <span class="attrib">@type</span> number */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getCellRowNumber = <span class="reserved">function</span>(oCell) { <span class="reserved">if</span> (oCell) { var iRowId = <span class="reserved">this</span>.getCellRowId(oCell); var aRows = <span class="reserved">this</span>.applyPaging(); <span class="reserved">for</span> (var iRow = 0; iRow < aRows.length; iRow++) { <span class="reserved">if</span> (<span class="reserved">this</span>.getRowId(aRows[iRow]) == iRowId) { <span class="reserved">return</span> iRow; } } } }; <span class="comment">/** * Finds cell by its row and cell id. * * <span class="attrib">@param</span> {object} oRow Row object * <span class="attrib">@param</span> {number} iCellId Cell id * <span class="attrib">@return</span> Cell object or undefined if not found * <span class="attrib">@type</span> object */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getCellByRow = <span class="reserved">function</span>(oRow, iCellId) { var aCells = <span class="reserved">this</span>.getRowCells(oRow); <span class="reserved">if</span> (aCells) { <span class="reserved">return</span> aCells[iCellId]; } }; <span class="comment">/** * Finds cell by its row id and cell id. * * <span class="attrib">@param</span> {number} iRowId Row id * <span class="attrib">@param</span> {number} iCellId Cell id * <span class="attrib">@return</span> Cell object or undefined if not found * <span class="attrib">@type</span> object */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getCellById = <span class="reserved">function</span>(iRowId, iCellId) { <span class="reserved">return</span> <span class="reserved">this</span>.getCellByRow(<span class="reserved">this</span>.getRowById(iRowId), iCellId); }; <span class="comment">/** * Returns cell value to display. * * <span class="attrib">@param</span> {object} oCell Cell object * <span class="attrib">@return</span> Cell value to display * <span class="attrib">@type</span> any */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getCellValue = <span class="reserved">function</span>(oCell) { <span class="reserved">if</span> (!oCell) { <span class="reserved">return</span>; } <span class="reserved">return</span> oCell.v; }; <span class="comment">/** * Returns cell value to display as string. * * <span class="attrib">@param</span> {object} oCell Cell object * <span class="attrib">@return</span> Cell value to display * <span class="attrib">@type</span> string */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getCellValueString = <span class="reserved">function</span>(oCell) { <span class="reserved">return</span> <span class="reserved">this</span>.getCellValue(oCell) + <span class="literal">''</span>; }; <span class="comment">/** * Returns cell value to compare. * * <span class="attrib">@param</span> {object} oCell Cell object * <span class="attrib">@return</span> Cell value to compare * <span class="attrib">@type</span> any */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getCellValueCompare = <span class="reserved">function</span>(oCell) { <span class="reserved">if</span> (!oCell) { <span class="reserved">return</span> <span class="literal">''</span>; } <span class="reserved">if</span> (typeof oCell.c != <span class="literal">'undefined'</span>) { <span class="reserved">return</span> oCell.c; } <span class="reserved">return</span> <span class="reserved">this</span>.getCellValue(oCell); }; <span class="comment">/** * Returns original cell value. * * <span class="attrib">@param</span> {object} oCell Cell object * <span class="attrib">@return</span> Original cell value * <span class="attrib">@type</span> any */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getCellValueOriginal = <span class="reserved">function</span>(oCell) { <span class="reserved">if</span> (!oCell) { <span class="reserved">return</span> <span class="literal">''</span>; } <span class="reserved">if</span> (typeof oCell.o != <span class="literal">'undefined'</span>) { <span class="reserved">return</span> oCell.o; } <span class="reserved">return</span> <span class="reserved">this</span>.getCellValue(oCell); }; <span class="comment">/** * Returns cell style defined by user. * * <span class="attrib">@param</span> {object} oCell Cell object * <span class="attrib">@param</span> {number} iRow Row number passed to funcStyle * <span class="attrib">@return</span> User defined cell style * <span class="attrib">@type</span> string */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getCellStyle = <span class="reserved">function</span>(oCell, iRow) { <span class="comment">// Check arguments</span> <span class="reserved">if</span> (!oCell) { <span class="reserved">return</span> <span class="literal">''</span>; } <span class="comment">// Get style defined by user</span> var sStyle = <span class="literal">''</span>; <span class="comment">// Try funcStyle</span> <span class="reserved">if</span> (typeof <span class="reserved">this</span>.config.funcStyle == <span class="literal">'function'</span>) { sStyle = <span class="reserved">this</span>.config.funcStyle(<span class="reserved">this</span>, oCell, iRow); } <span class="comment">// Try value got from source</span> <span class="reserved">if</span> (!sStyle) { sStyle = oCell.style; } <span class="reserved">return</span> sStyle; }; <span class="comment">/** * Returns true if cell is selected. * * <span class="attrib">@param</span> {object} oCell Cell object * <span class="attrib">@return</span> true if cell is selected * <span class="attrib">@type</span> boolean */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getCellSelected = <span class="reserved">function</span>(oCell) { <span class="reserved">return</span> (oCell && oCell.selected); }; <span class="comment">/** * Returns cell data type. * * <span class="attrib">@param</span> {object} oCell Cell object * <span class="attrib">@return</span> Cell data type or undefined if not found * <span class="attrib">@type</span> string */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getCellDataType = <span class="reserved">function</span>(oCell) { var oField = <span class="reserved">this</span>.getFieldByCell(oCell); <span class="reserved">if</span> (oField) { <span class="reserved">return</span> oField.dataType; } }; <span class="comment">/** * Returns data to be displayed in grid cell. * * <span class="attrib">@param</span> {object} oCell Cell object * <span class="attrib">@param</span> {number} iMode Optional. Mode for show as is: 1 = check show_asis, * 2 = show converted, 3 = show as is with any conversion, 4 = original value. * Default: 1. * <span class="attrib">@return</span> Data to display for this cell * <span class="attrib">@type</span> string */</span> Zapatec.Grid.<span class="reserved">prototype</span>.getCellData = <span class="reserved">function</span>(oCell, iMode) { <span class="comment">// Check arguments</span> <span class="reserved">if</span> (!oCell) { <span class="reserved">return</span> <span class="literal">'undefined'</span>; } <span class="reserved">if</span> (!iMode) { iMode = 1; } <span class="comment">// Check show_asis</span> <span class="reserved">if</span> ((iMode == 1 && !<span class="reserved">this</span>.config.show_asis) || iMode == 2) { <span class="comment">// Default representation</span> <span class="reserved">return</span> <span class="reserved">this</span>.getCellValueString(oCell); } <span class="comment">// Form value</span> var sData = <span class="reserved">this</span>.getCellValueOriginal(oCell) + <span class="literal">''</span>; <span class="reserved">if</span> (iMode == 4) { <span class="comment">// Original value</span> <span class="reserved">return</span> sData; } <span class="comment">// iMode == 3</span> <span class="reserved">if</span> (typeof <span class="reserved">this</span>.config.show_asis == <span class="literal">'object'</span>) { <span class="comment">// Call function to create presentable data for grid cell</span> <span class="reserved">if</span> (typeof <span class="reserved">this</span>.config.show_asis.funcShow == <span class="literal">'function'</span>) { sData = <span class="reserved">this</span>.config.show_asis.funcShow(<span class="reserved">this</span>, oCell); } <span class="comment">// Show both</span> <span class="reserved">if</span> (<span class="reserved">this</span>.config.show_asis.bBoth) { sData = <span class="literal">'<u>'</span> + sData + <span class="literal">'</u><br>'</span> + <span class="reserved">this</span>.getCellValueString(oCell); } } <span class="reserved">return</span> sData; }; <span class="comment">/** * Sets column title and visualizes changes immediately without refreshing whole * grid. * * <span class="attrib">@param</span> {object} oField Field object * <span class="attrib">@param</span> {string} sTitle New column title * <span class="attrib">@return</span> Number of renamed columns (0 or 1) * <span class="attrib">@type</span> number */</span> Zapatec.Grid.<span class="reserved">prototype</span>.setFieldTitle = <span class="reserved">function</span>(oField, sTitle) { <span class="comment">// Change title</span> <span class="reserved">if</span> (!oField) { <span class="reserved">return</span> 0; } oField.title = sTitle; <span class="comment">// Visualize change</span> var oSpan = document.getElementById([<span class="literal">'zpGrid'</span>, <span class="reserved">this</span>.id, <span class="literal">'Col'</span>, oField.i, <span class="literal">'TitleSpan'</span>].join(<span class="literal">''</span>)); <span class="reserved">if</span> (oSpan) { oSpan.innerHTML = sTitle; } <span class="reserved">return</span> 1; }; <span class="comment">/** * Sets cell value. Saves previous value in the private property. * * <span class="attrib">@param</span> {object} oCell Cell object * <span class="attrib">@param</span> {any} value New cell value * <span class="attrib">@return</span> Updated cell object * <span class="attrib">@type</span> object */</span> Zapatec.Grid.<span class="reserved">prototype</span>.setCellValue = <span class="reserved">function</span>(oCell, value) { <span class="reserved">if</span> (!oCell) { oCell = {}; } <span class="reserved">else</span> { <span class="comment">// Remove old previous state</span> oCell.previousState = null; <span class="comment">// Save previous state of the cell</span> oCell.previousState = Zapatec.Utils.clone(oCell); } oCell.v = value; <span class="reserved">return</span> <span class="reserved">this</span>.convertCell(oCell); }; <span class="comment">/** * Reverts previous cell value. Current cell value becomes previous. If there is * no previous value, leaves the cell without changes. * * <pre> * Format of the argument: * { * rowId: [number, optional] zero-based row id, * row: [object, optional] row object, * cellId: [number, optional] zero-based column id, * cell: [object, optional] cell object * } * * Only one of the following combinations is expected: * 1) row, cellId * 2) rowId, cellId * 3) cell * </pre> * * <span class="attrib">@private</span> * <span class="attrib">@param</span> {object} oArg Argument object * <span class="attrib">@return</span> Updated cell object or null if cell is not found * <span class="attrib">@type</span> object */</span> Zapatec.Grid.<span class="reserved">prototype</span>.revertCell = <span class="reserved">function</span>(oArg) { <span class="comment">// Check arguments</span> var iRowId = parseInt(oArg.rowId); var oRow = oArg.row; var iCellId = parseInt(oArg.cellId); var oCell = oArg.cell; <span class="reserved">if</span> (!oRow) { <span class="reserved">if</span> (!isNaN(iRowId)) { oRow = <span class="reserved">this</span>.getRowById(iRowId); } <span class="reserved">else</span> <span class="reserved">if</span> (oCell) { oRow = <span class="reserved">this</span>.getRowByCell(oCell); } <span class="reserved">if</span> (!oRow) { <span class="comment">// Invalid argument</span> <span class="reserved">return</span> null; } } <span class="reserved">if</span> (isNaN(iCellId)) { iCellId = <span class="reserved">this</span>.getCellId(oCell); <span class="reserved">if</span> (typeof iCellId != <span class="literal">'number'</span>) { <span class="comment">// Invalid argument</span> <span class="reserved">return</span> null; } } <span class="comment">// Get cell and revert it</span> var aCells = oRow.cells; <span class="reserved">if</span> (aCells) { oCell = aCells[iCellId]; <span class="reserved">if</span> (oCell) { var oPrevState = oCell.previousState; <span class="reserved">if</span> (oPrevState) { <span class="comment">// Remove old previous state</span> oCell.previousState = null; <span class="comment">// Save previous state of the cell</span> oPrevState.previousState = Zapatec.Utils.clone(oCell); <span class="comment">// Revert cell</span> aCells[iCellId] = oCell = oPrevState; } <span class="reserved">return</span> oCell; } } <span class="comment">// Invalid cell</span> <span class="reserved">return</span> null; }; <span class="comment">/** * Reverts previous values of all cells in the row. Calls * {<span class="attrib">@link</span> Zapatec.Grid#revertCell} for each cell in the row. * * <pre> * Format of the argument: * { * rowId: [number, optional] zero-based row id, * row: [object, optional] row object * } * * Only one of rowId and row is expected. * </pre> * * <span class="attrib">@private</span> * <span class="attrib">@param</span> {object} oArg Argument object * <span class="attrib">@return</span> Updated row object or null if row is not found * <span class="attrib">@type</span> object */</span> Zapatec.Grid.<span class="reserved">prototype</span>.revertRow = <span class="reserved">function</span>(oArg) { <span class="comment">// Check arguments</span> var iRowId = parseInt(oArg.rowId); var oRow = oArg.row; <span class="reserved">if</span> (!oRow) { <span class="reserved">if</span> (!isNaN(iRowId)) { oRow = <span class="reserved">this</span>.getRowById(iRowId); } <span class="reserved">if</span> (!oRow) { <span class="comment">// Invalid argument</span> <span class="reserved">return</span> null; } } <span class="comment">// Revert cells</span> var aCells = oRow.cells; <span class="reserved">if</span> (!(aCells instanceof Array)) { <span class="comment">// Invalid row</span> <span class="reserved">return</span> null; } var iCells = aCells.length; <span class="reserved">for</span> (var iCell = 0; iCell < iCells; iCell++) { <span class="reserved">this</span>.revertCell({ row: oRow, cellId: iCell }); } <span class="reserved">return</span> oRow; }; <span class="comment">/** * Sets cell style. * * <span class="attrib">@param</span> {object} oCell Cell object * <span class="attrib">@param</span> {string} sStyle New cell style * <span class="attrib">@return</span> Updated cell object * <span class="attrib">@type</span> object */</span> Zapatec.Grid.<span class="reserved">prototype</span>.setCellStyle = <span class="reserved">function</span>(oCell, sStyle) { <span class="reserved">if</span> (oCell instanceof Object) { oCell.style = sStyle; } <span class="reserved">return</span> oCell; }; <span class="comment">/** * Hides specified columns. * * <pre> * Argument object format: * { * columns: [object or number] Array of zero-based column numbers or single * zero-based column number, * noRefresh: [boolean] If true, grid is not refreshed. Useful when you need * to hide some columns and to show other columns * } * </pre> * * <span class="attrib">@param</span> {object} oArg Argument object */</span> Zapatec.Grid.<span class="reserved">prototype</span>.hideColumns = <span class="reserved">function</span>(oArg) { <span class="comment">// Check arguments</span> var aColumns = oArg.columns; <span class="reserved">if</span> (!(aColumns instanceof Array)) { <span class="reserved">if</span> (typeof aColumns == <span class="literal">'undefined'</span>) { <span class="reserved">return</span>; } aColumns = [aColumns]; } <span class="comment">// Hide columns</span> var iColumns = aColumns.length; var iColumn, oColumn; <span class="reserved">for</span> (iColumn = 0; iColumn < iColumns; iColumn++) { oColumn = <span class="reserved">this</span>.getFieldById(aColumns[iColumn]); <span class="reserved">if</span> (oColumn) { oColumn.hidden = true; } } <span class="comment">// Refresh</span> <span class="reserved">if</span> (!oArg.noRefresh) { <span class="reserved">this</span>.refresh(); } }; <span class="comment">/** * Unhides specified columns. * * <pre> * Argument object format: * { * columns: [object or number] Array of zero-based column numbers or single * zero-based column number, * noRefresh: [boolean] If true, grid is not refreshed. Useful when you need * to show some columns and to hide other columns * } * </pre> * * <span class="attrib">@param</span> {object} oArg Argument object */</span> Zapatec.Grid.<span class="reserved">prototype</span>.showColumns = <span class="reserved">function</span>(oArg) { <span class="comment">// Check arguments</span> <span class="reserved">if</span> (!(oArg.columns instanceof Array)) { <span class="reserved">if</span> (typeof oArg.columns == <span class="literal">'undefined'</span>) { <span class="reserved">return</span>; } oArg.columns = [oArg.columns]; } <span class="comment">// Unhide columns</span> <span class="reserved">for</span> (var iCol = 0; iCol < oArg.columns.length; iCol++) { var oCol = <span class="reserved">this</span>.getFieldById(oArg.columns[iCol]); <span class="reserved">if</span> (oCol) { oCol.hidden = false; <span class="reserved">if</span> (!oArg.noRefresh) { <span class="reserved">this</span>.refresh(); } } } }; <span class="comment">/** * Loads passed data into already initialized grid to view or edit them. * * <pre> * Arguments object format: * { * data: [object] data in format specific for each widget * } * </pre> * * <span class="attrib">@param</span> {object} oArg Arguments */</span> Zapatec.Grid.<span class="reserved">prototype</span>.receiveData = <span class="reserved">function</span>(oArg) { <span class="comment">// Call parent method</span> Zapatec.Grid.SUPERclass.receiveData.call(<span class="reserved">this</span>, oArg); <span class="comment">// Check arguments</span> <span class="reserved">if</span> (!oArg.data) { <span class="reserved">return</span>; } <span class="comment">// Get data</span> var aRows = oArg.data; <span class="reserved">if</span> (!(aRows instanceof Array)) { aRows = [aRows]; } <span class="comment">// Form rows</span> <span class="reserved">for</span> (var iRow = 0; iRow < aRows.length; iRow++) { var aCells = aRows[iRow]; <span class="comment">// Check if we need to convert data</span> <span class="reserved">if</span> (aCells.cells) { break; } <span class="comment">// Get array of cell values</span> <span class="reserved">if</span> (!(aCells instanceof Array)) { aCells = [aCells]; } <span class="comment">// Convert row</span> var oRow = { cells: [] }; <span class="reserved">for</span> (var iCell = 0; iCell < aCells.length; iCell++) { var oCell = aCells[iCell]; <span class="reserved">if</span> (typeof oCell.v != <span class="literal">'undefined'</span>) { oRow.cells.push(oCell); } <span class="reserved">else</span> { oRow.cells.push({ v: oCell }); } } aRows[iRow] = oRow; } <span class="comment">// Put data into the grid</span> <span class="reserved">this</span>.splice({ atRow: 0, howMany: <span class="reserved">this</span>.totalRecords(), <span class="comment">// Clone array to prevent modification of the original data</span> rows: Zapatec.Utils.clone(aRows) }); }; <span class="comment">/** * Passes array of selected rows to the specified editor. * * <span class="attrib">@param</span> {object} oEditor Widget object used as editor */</span> Zapatec.Grid.<span class="reserved">prototype</span>.editSelectedRows = <span class="reserved">function</span>(oEditor) { <span class="comment">// Check arguments</span> <span class="reserved">if</span> (!oEditor || !oEditor.receiveData) { <span class="reserved">return</span>; } <span class="comment">// Get selected rows</span> var aRows = <span class="reserved">this</span>.getSelectedRows(); <span class="comment">// Check if there are selected rows</span> <span class="reserved">if</span> (!aRows.length) { alert(<span class="reserved">this</span>.getMessage(<span class="literal">'errorSelectRow'</span>)); <span class="reserved">return</span>; } <span class="comment">// Populate editor</span> oEditor.receiveData({ data: aRows }); }; <span class="comment">/** * Passes array of selected cells to the specified editor. * * <span class="attrib">@param</span> {object} oEditor Widget object used as editor */</span> Zapatec.Grid.<span class="reserved">prototype</span>.editSelectedCells = <span class="reserved">function</span>(oEditor) { <span class="comment">// Check arguments</span> <span class="reserved">if</span> (!oEditor || !oEditor.receiveData) { <span class="reserved">return</span>; } <span class="comment">// Get selected rows</span> var aCells = <span class="reserved">this</span>.getSelectedCells(); <span class="comment">// Check if there are selected cells</span> <span class="reserved">if</span> (!aCells.length) { alert(<span class="reserved">this</span>.getMessage(<span class="literal">'errorSelectCell'</span>)); <span class="reserved">return</span>; } <span class="comment">// Populate editor</span> oEditor.receiveData({ data: aCells }); }; <span class="comment">/** * Forms cells for rowspans and colspans or prepares rowspans and colspans for * output. * * <span class="attrib">@private</span> * <span class="attrib">@param</span> {object} aRows Rows array to modify * <span class="attrib">@param</span> {boolean} bOut Optional. If true, instead of forming cells prepares * rowspans and colspans for output. * <span class="attrib">@return</span> Modified rows array * <span class="attrib">@type</span> object */</span> Zapatec.Grid.<span class="reserved">prototype</span>.prepareSpans = <span class="reserved">function</span>(aRows, bOut) { var aFields = <span class="reserved">this</span>.fields; var iFields = aFields.length; var iRows = aRows.length; <span class="reserved">if</span> (iFields && iRows) { <span class="comment">// Rowspan flags</span> var aRF = []; <span class="comment">// Functions used inside loop</span> var fClone = Zapatec.Utils.clone; <span class="comment">// Variables used inside loop</span> var iHorizHiddenStart = <span class="reserved">this</span>.config.fixedLeft; var iHorizHiddenEnd = iHorizHiddenStart + <span class="reserved">this</span>.currentHorizontalOffset; var iRow, oRow, aCells, iCell, iC, oCell, oRF, oC, iRowspan, iColspan; <span class="reserved">for</span> (iRow = 0; iRows--; iRow++) { oRow = aRows[iRow]; <span class="reserved">if</span> (!oRow) { continue; } aCells = oRow.cells; <span class="reserved">if</span> (!aCells) { continue; } <span class="reserved">for</span> (iCell = 0; iCell < iFields; iCell++) { oCell = aCells[iCell]; oRF = aRF[iCell]; <span class="reserved">if</span> (oCell) { <span class="reserved">if</span> (oRF) { <span class="comment">// Check if we are still inside rowspan</span> oC = oRF.cell; <span class="reserved">if</span> (oC.i == oCell.i && oC.r == oCell.r) { <span class="reserved">if</span> (bOut) { <span class="comment">// Remove spanned cell</span> aCells[iCell] = null; <span class="comment">// Mark row as having rowspans</span> oRow.spanned = true; } <span class="comment">// Decrement rowspan flag</span> <span class="reserved">if</span> (!--oRF.rowspan) { <span class="comment">// End of span</span> aRF[iCell] = null; } <span class="reserved">else</span> <span class="reserved">if</span> (!iRows) { <span class="comment">// End of data</span> oC.rowspan -= oRF.rowspan; aRF[iCell] = null; } <span class="comment">// Check colspan</span> <span class="reserved">if</span> (bOut) { iColspan = oCell.colspan; <span class="reserved">if</span> (iColspan > 1) { <span class="reserved">for</span> (iCell++; --iColspan; iCell++) { aCells[iCell] = null; } continue; } } } <span class="reserved">else</span> { <span class="comment">// Some rows in rowspan were filtered out</span> <span class="reserved">if</span> (bOut) { <span class="comment">// Fix rowspan</span> iRowspan = oC.rowspan - oRF.rowspan; <span class="reserved">if</span> (iRowspan < 2) { iRowspan = 0; } oC.rowspan = iRowspan; <span class="comment">// Hide content if controlling cell is not visible</span> <span class="reserved">if</span> (oC.r < <span class="reserved">this</span>.currentVerticalOffset) { oC.v = <span class="literal">''</span>; } iColspan = oC.colspan; <span class="reserved">if</span> (iColspan > 1) { var aSpannedCells = oRF.row.cells; var oSpannedCell; <span class="reserved">for</span> (var iOffset = 1; iOffset < iColspan; iOffset++) { oSpannedCell = aSpannedCells[iCell + iOffset]; <span class="reserved">if</span> (oSpannedCell) { oSpannedCell.rowspan = iRowspan; } } } } aRF[iCell] = null; <span class="comment">// Process this cell again because it can start its own rowspan</span> iCell--; continue; } } <span class="reserved">else</span> { <span class="comment">// Check rowspan</span> iRowspan = oCell.rowspan; <span class="reserved">if</span> (iRowspan > 1) { <span class="reserved">if</span> (iRows) { <span class="comment">// Set rowspan flag</span> aRF[iCell] = { rowspan: --iRowspan, row: oRow, cell: oCell }; <span class="comment">// Mark row as having rowspans</span> oRow.spanned = true; } <span class="reserved">else</span> { <span class="comment">// End of data</span> oCell.rowspan = 0; } } } <span class="comment">// Check colspan</span> iColspan = oCell.colspan; <span class="reserved">if</span> (iColspan > 1) { <span class="reserved">if</span> (bOut) { <span class="comment">// Find the first not hidden</span> <span class="reserved">while</span> (iColspan && aFields[iCell].hidden) { oCell = aCells[++iCell]; iColspan--; } <span class="reserved">while</span> (iColspan && iCell >= iHorizHiddenStart && iCell < iHorizHiddenEnd) { oCell = aCells[++iCell]; <span class="comment">// Hide content if controlling cell is not visible</span> oCell.v = <span class="literal">''</span>; iColspan--; } <span class="reserved">if</span> (oCell) { oCell.colspan = iColspan; } <span class="reserved">if</span> (iColspan > 0) { <span class="comment">// Go to next cell</span> iColspan--; iCell++; <span class="comment">// Remove spanned cells</span> <span class="reserved">while</span> (aFields[iCell] && iColspan--) { <span class="reserved">if</span> (aFields[iCell].hidden) { <span class="reserved">if</span> (oCell) { oCell.colspan--; } } <span class="comment">// Remove spanned cell</span> aCells[iCell] = null; iCell++; } <span class="comment">// Compensate increment in the parent loop</span> iCell--; } } <span class="reserved">else</span> { <span class="reserved">for</span> (iCell++; --iColspan; iCell++) { <span class="comment">// Clone cell for sorting and filtering</span> oC = fClone(oCell); oC.i = iCell; <span class="comment">// Convert cell value according to the column type</span> aCells[iCell] = <span class="reserved">this</span>.convertCell(oC); } <span class="comment">// Compensate increment in the parent loop</span> iCell--; } } } <span class="reserved">else</span> <span class="reserved">if</span> (oRF) { <span class="reserved">if</span> (bOut) { <span class="comment">// Mark row as having rowspans</span> oRow.spanned = true; } <span class="reserved">else</span> { <span class="comment">// Reference cell for sorting and filtering</span> aCells[iCell] = oRF.cell; <span class="comment">// Decrement rowspan flag</span> <span class="reserved">if</span> (!--oRF.rowspan) { <span class="comment">// End of span</span> aRF[iCell] = null; } <span class="reserved">else</span> <span class="reserved">if</span> (!iRows) { <span class="comment">// End of data</span> oRF.cell.rowspan -= oRF.rowspan; aRF[iCell] = null; } <span class="comment">// Check colspan</span> <span class="reserved">if</span> (!bOut) { oCell = aCells[iCell]; iColspan = oCell.colspan; <span class="reserved">if</span> (iColspan > 1) { <span class="reserved">for</span> (iCell++; --iColspan; iCell++) { <span class="comment">// Clone cell for sorting and filtering</span> oC = fClone(oCell); oC.i = iCell; <span class="comment">// Convert cell value according to the column type</span> aCells[iCell] = <span class="reserved">this</span>.convertCell(oC); } } } } } } } } <span class="reserved">return</span> aRows; }; <span class="comment">/** * Standard gridCellMouseup event handler. If right mouse button was clicked, * calls callbackCellOnRightClick function. If callbackCellOnRightClick is not * defined, calls callbackRowOnRightClick function. * * <pre> * Note: * In Opera instead of right click use Alt + left click because it doesn't allow * to turn off context menu programmatically. * Safari doesn't support right mouse button. Use Meta + left click instead. * </pre> * * <span class="attrib">@private</span> * <span class="attrib">@param</span> {number} iRow Row id * <span class="attrib">@param</span> {number} iCell Cell id */</span> Zapatec.Grid.onCellMouseup = <span class="reserved">function</span>(iRow, iCell) { <span class="comment">// Get button</span> var oEvent = window.event; var iButton = oEvent.button || oEvent.which || 1; <span class="reserved">if</span> (iButton == 1 && (oEvent.metaKey || (window.opera && oEvent.altKey))) { iButton = 2; } <span class="comment">// Callback</span> <span class="reserved">if</span> (iButton > 1) { var oConfig = <span class="reserved">this</span>.config; <span class="reserved">if</span> (typeof oConfig.callbackCellOnRightClick == <span class="literal">'function'</span>) { oConfig.callbackCellOnRightClick(<span class="reserved">this</span>, <span class="reserved">this</span>.getCellById(iRow, iCell)); } <span class="reserved">else</span> <span class="reserved">if</span> (typeof oConfig.callbackRowOnRightClick == <span class="literal">'function'</span>) { oConfig.callbackRowOnRightClick(<span class="reserved">this</span>, <span class="reserved">this</span>.getRowById(iRow)); } } }; <span class="comment">/** * Moves column within the grid. Note: Changes ids of the columns. * * <pre> * Arguments format: * { * fieldId: [number] zero-based field id to move, * position: [number] new zero-based column position, * noRefresh: [boolean, optional] indicates that grid should not be refreshed * after changing (default is false) (useful when several changes go one by * one) * } * </pre> * * <span class="attrib">@param</span> {object} oArg Arguments * <span class="attrib">@return</span> True on success, false on attempt to move column into itself, * undefined if arguments are invalid * <span class="attrib">@type</span> boolean */</span> Zapatec.Grid.<span class="reserved">prototype</span>.moveColumn = <span class="reserved">function</span>(oArg) { <span class="comment">// Check arguments</span> <span class="reserved">if</span> (!oArg) { <span class="reserved">return</span>; } var iColumn = parseInt(oArg.fieldId); <span class="reserved">if</span> (isNaN(iColumn)) { <span class="reserved">return</span>; } var aFields = <span class="reserved">this</span>.fields; var iFields = aFields.length; <span class="reserved">if</span> (!aFields[iColumn]) { <span class="reserved">return</span>; } var iPos = parseInt(oArg.position); <span class="reserved">if</span> (isNaN(iPos)) { <span class="reserved">return</span>; } <span class="reserved">if</span> (iPos < 0) { iPos = 0; } <span class="reserved">else</span> <span class="reserved">if</span> (!aFields[iPos]) { iPos = aFields[iFields - 1].i; <span class="reserved">if</span> (isNaN(iPos)) { <span class="reserved">return</span>; } } <span class="reserved">if</span> (iColumn == iPos) { <span class="reserved">return</span> false; } <span class="comment">// Move field</span> var aRemoved; aRemoved = aFields.splice(iColumn, 1); aFields.splice(iPos, 0, aRemoved[0]); <span class="comment">// Fix fields, filter out rules, totals rules</span> var iStart = iColumn; var iEnd = iPos; var iIncrement = -1; <span class="reserved">if</span> (iColumn > iPos) { iStart = iPos; iEnd = iColumn; iIncrement = 1; } var iCol; <span class="comment">// Fields</span> <span class="reserved">for</span> (iCol = iStart; iCol <= iEnd; iCol++) { aFields[iCol].i = iCol; } <span class="comment">// Filter out rules, totals rules</span> var aRules = <span class="reserved">this</span>.filterOutRules; aRules = aRules.concat(<span class="reserved">this</span>.totalsRules); var iRules = aRules.length; var iRule, oRule, aCols, iCols, iFieldId; <span class="reserved">for</span> (iRule = 0; iRule < iRules; iRule++) { oRule = aRules[iRule]; aCols = oRule.column; <span class="reserved">if</span> (aCols instanceof Array) { iCols = aCols.length; <span class="reserved">for</span> (iCol = 0; iCol < iCols; iCol++) { iFieldId = aCols[iCol]; <span class="reserved">if</span> (iFieldId == iColumn) { aCols[iCol] = iPos; } <span class="reserved">else</span> <span class="reserved">if</span> (iFieldId >= iStart && iFieldId <= iEnd) { aCols[iCol] += iIncrement; } } } <span class="reserved">else</span> { iFieldId = aCols; <span class="reserved">if</span> (iFieldId == iColumn) { oRule.column = iPos; } <span class="reserved">else</span> <span class="reserved">if</span> (iFieldId >= iStart && iFieldId <= iEnd) { oRule.column += iIncrement; } } } <span class="comment">// Fix data</span> var aRows = <span class="reserved">this</span>.rows; var iRows = aRows.length; var iRow, oRow, aCells; <span class="reserved">for</span> (iRow = 0; iRow < iRows; iRow++) { oRow = aRows[iRow]; aCells = oRow.cells; <span class="comment">// Move cell</span> aRemoved = aCells.splice(iColumn, 1); aCells.splice(iPos, 0, aRemoved[0]); <span class="comment">// Fix cell ids</span> <span class="reserved">for</span> (iCol = iStart; iCol <= iEnd; iCol++) { aCells[iCol].i = iCol; } } <span class="comment">// Fire event</span> <span class="reserved">this</span>.fireEvent(<span class="literal">'gridMovedColumn'</span>, { fieldId: iColumn, position: iPos }); <span class="comment">// Refresh grid</span> <span class="reserved">if</span> (!oArg.noRefresh) { <span class="reserved">this</span>.refresh(); } <span class="reserved">return</span> true; }; <span class="comment">/** * Converts any column number after column moving. When column is moved, ids of * the fields are changed. This function takes old field id and converts it * to the new id of the same field. Note: static method. * * <pre> * Arguments format: * { * fieldId: [number] old zero-based field id, * move: [object] object received from the <b>gridMovedColumn</b> event * } * </pre> * * <span class="attrib">@param</span> {object} oArg Arguments * <span class="attrib">@return</span> New zero-based field id or undefined in case of invalid arguments * <span class="attrib">@type</span> number */</span> Zapatec.Grid.getNewColumnNumber = <span class="reserved">function</span>(oArg) { <span class="comment">// Check arguments</span> <span class="reserved">if</span> (!oArg) { <span class="reserved">return</span>; } var iFieldId = parseInt(oArg.fieldId); <span class="reserved">if</span> (isNaN(iFieldId)) { <span class="reserved">return</span>; } var oMove = oArg.move; <span class="reserved">if</span> (!oMove) { <span class="reserved">return</span>; } var iColumn = parseInt(oMove.fieldId); <span class="reserved">if</span> (isNaN(iColumn)) { <span class="reserved">return</span>; } var iPos = parseInt(oMove.position); <span class="reserved">if</span> (isNaN(iPos)) { <span class="reserved">return</span>; } <span class="comment">// Get new id</span> <span class="reserved">if</span> (iColumn == iPos) { <span class="comment">// Not changed</span> <span class="reserved">return</span> iFieldId; } var iStart = iColumn; var iEnd = iPos; var iIncrement = -1; <span class="reserved">if</span> (iColumn > iPos) { iStart = iPos; iEnd = iColumn; iIncrement = 1; } <span class="reserved">if</span> (iFieldId == iColumn) { <span class="reserved">return</span> iPos; } <span class="reserved">else</span> <span class="reserved">if</span> (iFieldId >= iStart && iFieldId <= iEnd) { <span class="reserved">return</span> iFieldId + iIncrement; } <span class="comment">// Not changed</span> <span class="reserved">return</span> iFieldId; }; </pre> <hr> <!-- ========== START OF NAVBAR ========== --> <a name="navbar_top"><!-- --></a> <table border="0" width="100%" cellpadding="1" cellspacing="0"> <tr> <td colspan=2 bgcolor="#EEEEFF" class="NavBarCell1"> <a name="navbar_top_firstrow"><!-- --></a> <table border="0" cellpadding="0" cellspacing="3"> <tr align="center" valign="top"> <td bgcolor="#EEEEFF" class="NavBarCell1"> <a href="overview-summary.html"><font class="NavBarFont1"><b>Overview</b></font></a> </td> <td bgcolor="#FFFFFF" class="NavBarCell1Rev"> <font class="NavBarFont1Rev"><b>File</b></font> </td> <td bgcolor="#FFFFFF" class="NavBarCell1"> <font class="NavBarFont1">Class</font> </td> <td bgcolor="#EEEEFF" class="NavBarCell1"> <a href="overview-tree.html"><font class="NavBarFont1"><b>Tree</b></font></a> </td> <td bgcolor="#EEEEFF" class="NavBarCell1"> <a href="index-all.html"--><font class="NavBarFont1"><b>Index</b></font></a> </td> <td bgcolor="#EEEEFF" class="NavBarCell1"> <a href="help-doc.html"><font class="NavBarFont1"><b>Help</b></font></a> </td> </tr> </table> </td> <td bgcolor="#EEEEFF" align="right" valign="top"><em> <b>Zapatec Grid</b></em> </td> </tr> <tr> <td bgcolor="white" class="NavBarCell2"><font size="-2"> PREV NEXT</font></td> <td bgcolor="white" class="NavBarCell2"><font size="-2"> <a href="index.html" target="_top"><b>FRAMES</b></a> <a href="overview-summary.html" target="_top"><b>NO FRAMES</b></a> <script> <!-- if(window==top) { document.writeln('<A HREF="allclasses-noframe.html" TARGET=""><B>All Classes</B></A>'); } //--> </script> <noscript> <a href="allclasses-noframe.html" target=""><b>All Classes</b></a> </noscript> </font></td> </tr> </table> <!-- =========== END OF NAVBAR =========== --> <hr> <font size="-1"> </font> <div class="jsdoc_ctime">Documentation generated by <a href="http://jsdoc.sourceforge.net/" target="_parent">JSDoc</a> on Thu Aug 16 12:18:56 2007</div> </body> </html>