summaryrefslogtreecommitdiff
path: root/js/dojo-1.7.2/dojox/grid
diff options
context:
space:
mode:
Diffstat (limited to 'js/dojo-1.7.2/dojox/grid')
-rw-r--r--js/dojo-1.7.2/dojox/grid/DataGrid.js15
-rw-r--r--js/dojo-1.7.2/dojox/grid/DataGrid.js.uncompressed.js14486
-rw-r--r--js/dojo-1.7.2/dojox/grid/DataSelection.js82
-rw-r--r--js/dojo-1.7.2/dojox/grid/EnhancedGrid.js263
-rw-r--r--js/dojo-1.7.2/dojox/grid/LazyTreeGrid.js837
-rw-r--r--js/dojo-1.7.2/dojox/grid/LazyTreeGridStoreModel.js114
-rw-r--r--js/dojo-1.7.2/dojox/grid/README151
-rw-r--r--js/dojo-1.7.2/dojox/grid/Selection.js267
-rw-r--r--js/dojo-1.7.2/dojox/grid/TreeGrid.js970
-rw-r--r--js/dojo-1.7.2/dojox/grid/TreeSelection.js216
-rw-r--r--js/dojo-1.7.2/dojox/grid/_Builder.js760
-rw-r--r--js/dojo-1.7.2/dojox/grid/_CheckBoxSelector.js4
-rw-r--r--js/dojo-1.7.2/dojox/grid/_EditManager.js259
-rw-r--r--js/dojo-1.7.2/dojox/grid/_Events.js508
-rw-r--r--js/dojo-1.7.2/dojox/grid/_FocusManager.js642
-rw-r--r--js/dojo-1.7.2/dojox/grid/_Grid.js1402
-rw-r--r--js/dojo-1.7.2/dojox/grid/_Layout.js276
-rw-r--r--js/dojo-1.7.2/dojox/grid/_RadioSelector.js4
-rw-r--r--js/dojo-1.7.2/dojox/grid/_RowManager.js64
-rw-r--r--js/dojo-1.7.2/dojox/grid/_RowSelector.js59
-rw-r--r--js/dojo-1.7.2/dojox/grid/_Scroller.js507
-rw-r--r--js/dojo-1.7.2/dojox/grid/_SelectionPreserver.js67
-rw-r--r--js/dojo-1.7.2/dojox/grid/_Selector.js225
-rw-r--r--js/dojo-1.7.2/dojox/grid/_TreeView.js467
-rw-r--r--js/dojo-1.7.2/dojox/grid/_View.js854
-rw-r--r--js/dojo-1.7.2/dojox/grid/_ViewManager.js307
-rw-r--r--js/dojo-1.7.2/dojox/grid/cells.js4
-rw-r--r--js/dojo-1.7.2/dojox/grid/cells/_base.js477
-rw-r--r--js/dojo-1.7.2/dojox/grid/cells/dijit.js256
-rw-r--r--js/dojo-1.7.2/dojox/grid/cells/tree.js75
-rw-r--r--js/dojo-1.7.2/dojox/grid/compatGrid.tar.gzbin0 -> 216813 bytes
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/_Events.js215
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/_FocusManager.js774
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/_Plugin.js172
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/_PluginManager.js275
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/EnhancedGrid.js48
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/Filter.js121
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/Pagination.js56
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/ar/EnhancedGrid.js17
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/ar/Filter.js90
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/ar/Pagination.js24
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/ca/EnhancedGrid.js17
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/ca/Filter.js89
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/ca/Pagination.js24
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/cs/EnhancedGrid.js17
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/cs/Filter.js89
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/cs/Pagination.js25
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/da/EnhancedGrid.js17
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/da/Filter.js89
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/da/Pagination.js24
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/de/EnhancedGrid.js17
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/de/Filter.js89
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/de/Pagination.js25
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/el/EnhancedGrid.js17
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/el/Filter.js89
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/el/Pagination.js24
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/es/EnhancedGrid.js17
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/es/Filter.js89
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/es/Pagination.js25
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/fi/EnhancedGrid.js17
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/fi/Filter.js89
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/fi/Pagination.js24
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/fr/EnhancedGrid.js17
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/fr/Filter.js89
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/fr/Pagination.js25
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/he/EnhancedGrid.js17
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/he/Filter.js90
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/he/Pagination.js24
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/hr/EnhancedGrid.js17
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/hr/Filter.js89
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/hr/Pagination.js25
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/hu/EnhancedGrid.js17
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/hu/Filter.js89
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/hu/Pagination.js25
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/it/EnhancedGrid.js17
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/it/Filter.js89
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/it/Pagination.js25
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/ja/EnhancedGrid.js16
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/ja/Filter.js89
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/ja/Pagination.js24
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/kk/EnhancedGrid.js17
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/kk/Filter.js89
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/kk/Pagination.js24
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/ko/EnhancedGrid.js17
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/ko/Filter.js89
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/ko/Pagination.js25
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/nb/EnhancedGrid.js17
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/nb/Filter.js89
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/nb/Pagination.js24
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/nl/EnhancedGrid.js17
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/nl/Filter.js89
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/nl/Pagination.js25
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/pl/EnhancedGrid.js17
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/pl/Filter.js89
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/pl/Pagination.js25
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/pt-br/EnhancedGrid.js16
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/pt-br/Filter.js89
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/pt-br/Pagination.js36
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/pt-pt/EnhancedGrid.js17
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/pt-pt/Filter.js90
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/pt-pt/Pagination.js24
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/pt/EnhancedGrid.js17
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/pt/Filter.js92
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/pt/Pagination.js24
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/ro/EnhancedGrid.js17
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/ro/Filter.js89
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/ro/Pagination.js24
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/ru/EnhancedGrid.js17
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/ru/Filter.js89
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/ru/Pagination.js25
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/sk/EnhancedGrid.js17
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/sk/Filter.js89
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/sk/Pagination.js24
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/sl/EnhancedGrid.js17
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/sl/Filter.js89
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/sl/Pagination.js25
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/sv/EnhancedGrid.js17
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/sv/Filter.js89
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/sv/Pagination.js24
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/th/EnhancedGrid.js17
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/th/Filter.js89
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/th/Pagination.js24
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/tr/EnhancedGrid.js17
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/tr/Filter.js89
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/tr/Pagination.js24
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/zh-tw/EnhancedGrid.js17
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/zh-tw/Filter.js89
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/zh-tw/Pagination.js25
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/zh/EnhancedGrid.js17
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/zh/Filter.js89
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/nls/zh/Pagination.js25
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/plugins/AutoScroll.js182
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/plugins/CellMerge.js276
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/plugins/Cookie.js362
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/plugins/Dialog.js40
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/plugins/DnD.js1094
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/plugins/Exporter.js243
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/plugins/Filter.js173
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/plugins/GridSource.js155
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/plugins/IndirectSelection.js626
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/plugins/Menu.js134
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/plugins/NestedSorting.js610
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/plugins/Pagination.js974
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/plugins/Printer.js292
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/plugins/Rearrange.js506
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/plugins/Search.js123
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/plugins/Selector.js1477
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/plugins/_RowMapLayer.js207
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/plugins/_SelectionPreserver.js109
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/plugins/_StoreLayer.js395
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/plugins/exporter/CSVWriter.js88
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/plugins/exporter/TableWriter.js160
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/plugins/exporter/_ExportWriter.js269
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/ClearFilterConfirm.js46
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/FilterBar.js386
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/FilterBuilder.js81
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/FilterDefDialog.js1252
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/FilterLayer.js411
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/FilterStatusTip.js148
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/_ConditionExpr.js243
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/_DataExprs.js85
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/_FilterExpr.js248
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/resources/Common.css27
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/resources/Common_rtl.css15
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/resources/DnD.css78
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/resources/DnD_rtl.css12
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/resources/EnhancedGrid.css8
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/resources/EnhancedGrid_rtl.css6
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/resources/Filter.css292
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/resources/Filter_rtl.css84
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/resources/Pagination.css147
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/resources/Pagination_rtl.css68
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/resources/Sorter.css179
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/resources/Sorter_rtl.css78
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/resources/claro/Common.css26
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/resources/claro/EnhancedGrid.css4
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/resources/claro/Filter.css58
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/resources/claroEnhancedGrid.css2
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/resources/images/sprite_icons.pngbin0 -> 2912 bytes
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/resources/tundra/Common.css40
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/resources/tundra/EnhancedGrid.css5
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/resources/tundra/Filter.css38
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/resources/tundra/Sorter.css83
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/resources/tundraEnhancedGrid.css2
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/templates/ClearFilterConfirmPane.html9
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/templates/CriteriaBox.html20
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/templates/FilterBar.html15
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/templates/FilterBoolValueBox.html11
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/templates/FilterDefPane.html27
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/templates/FilterStatusPane.html8
-rw-r--r--js/dojo-1.7.2/dojox/grid/enhanced/templates/Pagination.html18
-rw-r--r--js/dojo-1.7.2/dojox/grid/nls/DataGrid_ar.js13
-rw-r--r--js/dojo-1.7.2/dojox/grid/nls/DataGrid_ca.js14
-rw-r--r--js/dojo-1.7.2/dojox/grid/nls/DataGrid_cs.js13
-rw-r--r--js/dojo-1.7.2/dojox/grid/nls/DataGrid_da.js13
-rw-r--r--js/dojo-1.7.2/dojox/grid/nls/DataGrid_de-de.js16
-rw-r--r--js/dojo-1.7.2/dojox/grid/nls/DataGrid_el.js13
-rw-r--r--js/dojo-1.7.2/dojox/grid/nls/DataGrid_en-gb.js8
-rw-r--r--js/dojo-1.7.2/dojox/grid/nls/DataGrid_en-us.js8
-rw-r--r--js/dojo-1.7.2/dojox/grid/nls/DataGrid_es-es.js16
-rw-r--r--js/dojo-1.7.2/dojox/grid/nls/DataGrid_fi-fi.js16
-rw-r--r--js/dojo-1.7.2/dojox/grid/nls/DataGrid_fr-fr.js16
-rw-r--r--js/dojo-1.7.2/dojox/grid/nls/DataGrid_he-il.js16
-rw-r--r--js/dojo-1.7.2/dojox/grid/nls/DataGrid_hu.js13
-rw-r--r--js/dojo-1.7.2/dojox/grid/nls/DataGrid_it-it.js16
-rw-r--r--js/dojo-1.7.2/dojox/grid/nls/DataGrid_ja-jp.js16
-rw-r--r--js/dojo-1.7.2/dojox/grid/nls/DataGrid_ko-kr.js16
-rw-r--r--js/dojo-1.7.2/dojox/grid/nls/DataGrid_nb.js13
-rw-r--r--js/dojo-1.7.2/dojox/grid/nls/DataGrid_nl-nl.js16
-rw-r--r--js/dojo-1.7.2/dojox/grid/nls/DataGrid_pl.js13
-rw-r--r--js/dojo-1.7.2/dojox/grid/nls/DataGrid_pt-br.js16
-rw-r--r--js/dojo-1.7.2/dojox/grid/nls/DataGrid_pt-pt.js24
-rw-r--r--js/dojo-1.7.2/dojox/grid/nls/DataGrid_ru.js13
-rw-r--r--js/dojo-1.7.2/dojox/grid/nls/DataGrid_sk.js14
-rw-r--r--js/dojo-1.7.2/dojox/grid/nls/DataGrid_sl.js13
-rw-r--r--js/dojo-1.7.2/dojox/grid/nls/DataGrid_sv.js13
-rw-r--r--js/dojo-1.7.2/dojox/grid/nls/DataGrid_th.js14
-rw-r--r--js/dojo-1.7.2/dojox/grid/nls/DataGrid_tr.js13
-rw-r--r--js/dojo-1.7.2/dojox/grid/nls/DataGrid_zh-cn.js16
-rw-r--r--js/dojo-1.7.2/dojox/grid/nls/DataGrid_zh-tw.js24
-rw-r--r--js/dojo-1.7.2/dojox/grid/resources/Expando.html5
-rw-r--r--js/dojo-1.7.2/dojox/grid/resources/Grid.css415
-rw-r--r--js/dojo-1.7.2/dojox/grid/resources/Grid_rtl.css15
-rw-r--r--js/dojo-1.7.2/dojox/grid/resources/View.html12
-rw-r--r--js/dojo-1.7.2/dojox/grid/resources/_Grid.html6
-rw-r--r--js/dojo-1.7.2/dojox/grid/resources/claroGrid.css311
-rw-r--r--js/dojo-1.7.2/dojox/grid/resources/images/grid_dx_gradient.gifbin0 -> 267 bytes
-rw-r--r--js/dojo-1.7.2/dojox/grid/resources/images/grid_sort_down.gifbin0 -> 49 bytes
-rw-r--r--js/dojo-1.7.2/dojox/grid/resources/images/grid_sort_up.gifbin0 -> 48 bytes
-rw-r--r--js/dojo-1.7.2/dojox/grid/resources/images/header.pngbin0 -> 3276 bytes
-rw-r--r--js/dojo-1.7.2/dojox/grid/resources/images/header_shadow.pngbin0 -> 197 bytes
-rw-r--r--js/dojo-1.7.2/dojox/grid/resources/images/row_back.pngbin0 -> 3077 bytes
-rw-r--r--js/dojo-1.7.2/dojox/grid/resources/images/tabEnabled_rotated.pngbin0 -> 94 bytes
-rw-r--r--js/dojo-1.7.2/dojox/grid/resources/images/tabHover_rotated.pngbin0 -> 106 bytes
-rw-r--r--js/dojo-1.7.2/dojox/grid/resources/images/td_button_down.pngbin0 -> 3105 bytes
-rw-r--r--js/dojo-1.7.2/dojox/grid/resources/nihiloGrid.css237
-rw-r--r--js/dojo-1.7.2/dojox/grid/resources/soriaGrid.css245
-rw-r--r--js/dojo-1.7.2/dojox/grid/resources/tundraGrid.css268
-rw-r--r--js/dojo-1.7.2/dojox/grid/util.js75
239 files changed, 45108 insertions, 0 deletions
diff --git a/js/dojo-1.7.2/dojox/grid/DataGrid.js b/js/dojo-1.7.2/dojox/grid/DataGrid.js
new file mode 100644
index 0000000..560e12a
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/DataGrid.js
@@ -0,0 +1,15 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+/*
+ This is an optimized version of Dojo, built for deployment and not for
+ development. To get sources and documentation, please visit:
+
+ http://dojotoolkit.org
+*/
+
+//>>built
+require({cache:{"dojo/uacss":function(){define(["./dom-geometry","./_base/lang","./ready","./_base/sniff","./_base/window"],function(_1,_2,_3,_4,_5){var _6=_5.doc.documentElement,ie=_4("ie"),_7=_4("opera"),_8=Math.floor,ff=_4("ff"),_9=_1.boxModel.replace(/-/,""),_a={"dj_ie":ie,"dj_ie6":_8(ie)==6,"dj_ie7":_8(ie)==7,"dj_ie8":_8(ie)==8,"dj_ie9":_8(ie)==9,"dj_quirks":_4("quirks"),"dj_iequirks":ie&&_4("quirks"),"dj_opera":_7,"dj_khtml":_4("khtml"),"dj_webkit":_4("webkit"),"dj_safari":_4("safari"),"dj_chrome":_4("chrome"),"dj_gecko":_4("mozilla"),"dj_ff3":_8(ff)==3};_a["dj_"+_9]=true;var _b="";for(var _c in _a){if(_a[_c]){_b+=_c+" ";}}_6.className=_2.trim(_6.className+" "+_b);_3(90,function(){if(!_1.isBodyLtr()){var _d="dj_rtl dijitRtl "+_b.replace(/ /g,"-rtl ");_6.className=_2.trim(_6.className+" "+_d+"dj_rtl dijitRtl "+_b.replace(/ /g,"-rtl "));}});return _4;});},"dijit/hccss":function(){define("dijit/hccss",["require","dojo/_base/config","dojo/dom-class","dojo/dom-construct","dojo/dom-style","dojo/ready","dojo/_base/sniff","dojo/_base/window"],function(_e,_f,_10,_11,_12,_13,has,win){if(has("ie")||has("mozilla")){_13(90,function(){var div=_11.create("div",{id:"a11yTestNode",style:{cssText:"border: 1px solid;"+"border-color:red green;"+"position: absolute;"+"height: 5px;"+"top: -999px;"+"background-image: url(\""+(_f.blankGif||_e.toUrl("dojo/resources/blank.gif"))+"\");"}},win.body());var cs=_12.getComputedStyle(div);if(cs){var _14=cs.backgroundImage;var _15=(cs.borderTopColor==cs.borderRightColor)||(_14!=null&&(_14=="none"||_14=="url(invalid-url:)"));if(_15){_10.add(win.body(),"dijit_a11y");}if(has("ie")){div.outerHTML="";}else{win.body().removeChild(div);}}});}});},"dojox/grid/_View":function(){require({cache:{"url:dojox/grid/resources/View.html":"<div class=\"dojoxGridView\" role=\"presentation\">\n\t<div class=\"dojoxGridHeader\" dojoAttachPoint=\"headerNode\" role=\"presentation\">\n\t\t<div dojoAttachPoint=\"headerNodeContainer\" style=\"width:9000em\" role=\"presentation\">\n\t\t\t<div dojoAttachPoint=\"headerContentNode\" role=\"row\"></div>\n\t\t</div>\n\t</div>\n\t<input type=\"checkbox\" class=\"dojoxGridHiddenFocus\" dojoAttachPoint=\"hiddenFocusNode\" role=\"presentation\" />\n\t<input type=\"checkbox\" class=\"dojoxGridHiddenFocus\" role=\"presentation\" />\n\t<div class=\"dojoxGridScrollbox\" dojoAttachPoint=\"scrollboxNode\" role=\"presentation\">\n\t\t<div class=\"dojoxGridContent\" dojoAttachPoint=\"contentNode\" hidefocus=\"hidefocus\" role=\"presentation\"></div>\n\t</div>\n</div>\n"}});define("dojox/grid/_View",["dojo","dijit/registry","../main","dojo/_base/declare","dojo/_base/array","dojo/_base/lang","dojo/_base/connect","dojo/_base/sniff","dojo/query","dojo/_base/window","dojo/text!./resources/View.html","dojo/dnd/Source","dijit/_Widget","dijit/_TemplatedMixin","dojox/html/metrics","./util","dojo/_base/html","./_Builder","dojo/dnd/Avatar","dojo/dnd/Manager"],function(_16,_17,_18,_19,_1a,_1b,_1c,has,_1d,win,_1e,_1f,_20,_21,_22,_23,_24,_25,_26){var _27=function(_28,_29){return _28.style.cssText==undefined?_28.getAttribute("style"):_28.style.cssText;};var _2a=_19("dojox.grid._View",[_20,_21],{defaultWidth:"18em",viewWidth:"",templateString:_1e,themeable:false,classTag:"dojoxGrid",marginBottom:0,rowPad:2,_togglingColumn:-1,_headerBuilderClass:_25._HeaderBuilder,_contentBuilderClass:_25._ContentBuilder,postMixInProperties:function(){this.rowNodes={};},postCreate:function(){this.connect(this.scrollboxNode,"onscroll","doscroll");_23.funnelEvents(this.contentNode,this,"doContentEvent",["mouseover","mouseout","click","dblclick","contextmenu","mousedown"]);_23.funnelEvents(this.headerNode,this,"doHeaderEvent",["dblclick","mouseover","mouseout","mousemove","mousedown","click","contextmenu"]);this.content=new this._contentBuilderClass(this);this.header=new this._headerBuilderClass(this);if(!this.grid.isLeftToRight()){this.headerNodeContainer.style.width="";}},destroy:function(){_24.destroy(this.headerNode);delete this.headerNode;for(var i in this.rowNodes){this._cleanupRowWidgets(this.rowNodes[i]);_24.destroy(this.rowNodes[i]);}this.rowNodes={};if(this.source){this.source.destroy();}this.inherited(arguments);},focus:function(){if(has("ie")||has("webkit")||has("opera")){this.hiddenFocusNode.focus();}else{this.scrollboxNode.focus();}},setStructure:function(_2b){var vs=(this.structure=_2b);if(vs.width&&!isNaN(vs.width)){this.viewWidth=vs.width+"em";}else{this.viewWidth=vs.width||(vs.noscroll?"auto":this.viewWidth);}this._onBeforeRow=vs.onBeforeRow||function(){};this._onAfterRow=vs.onAfterRow||function(){};this.noscroll=vs.noscroll;if(this.noscroll){this.scrollboxNode.style.overflow="hidden";}this.simpleStructure=Boolean(vs.cells.length==1);this.testFlexCells();this.updateStructure();},_cleanupRowWidgets:function(_2c){if(_2c){_1a.forEach(_1d("[widgetId]",_2c).map(_17.byNode),function(w){if(w._destroyOnRemove){w.destroy();delete w;}else{if(w.domNode&&w.domNode.parentNode){w.domNode.parentNode.removeChild(w.domNode);}}});}},onBeforeRow:function(_2d,_2e){this._onBeforeRow(_2d,_2e);if(_2d>=0){this._cleanupRowWidgets(this.getRowNode(_2d));}},onAfterRow:function(_2f,_30,_31){this._onAfterRow(_2f,_30,_31);var g=this.grid;_1a.forEach(_1d(".dojoxGridStubNode",_31),function(n){if(n&&n.parentNode){var lw=n.getAttribute("linkWidget");var _32=window.parseInt(_24.attr(n,"cellIdx"),10);var _33=g.getCell(_32);var w=_17.byId(lw);if(w){n.parentNode.replaceChild(w.domNode,n);if(!w._started){w.startup();}_16.destroy(n);}else{n.innerHTML="";}}},this);},testFlexCells:function(){this.flexCells=false;for(var j=0,row;(row=this.structure.cells[j]);j++){for(var i=0,_34;(_34=row[i]);i++){_34.view=this;this.flexCells=this.flexCells||_34.isFlex();}}return this.flexCells;},updateStructure:function(){this.header.update();this.content.update();},getScrollbarWidth:function(){var _35=this.hasVScrollbar();var _36=_24.style(this.scrollboxNode,"overflow");if(this.noscroll||!_36||_36=="hidden"){_35=false;}else{if(_36=="scroll"){_35=true;}}return (_35?_22.getScrollbar().w:0);},getColumnsWidth:function(){var h=this.headerContentNode;return h&&h.firstChild?h.firstChild.offsetWidth:0;},setColumnsWidth:function(_37){this.headerContentNode.firstChild.style.width=_37+"px";if(this.viewWidth){this.viewWidth=_37+"px";}},getWidth:function(){return this.viewWidth||(this.getColumnsWidth()+this.getScrollbarWidth())+"px";},getContentWidth:function(){return Math.max(0,_24._getContentBox(this.domNode).w-this.getScrollbarWidth())+"px";},render:function(){this.scrollboxNode.style.height="";this.renderHeader();if(this._togglingColumn>=0){this.setColumnsWidth(this.getColumnsWidth()-this._togglingColumn);this._togglingColumn=-1;}var _38=this.grid.layout.cells;var _39=_1b.hitch(this,function(_3a,_3b){!this.grid.isLeftToRight()&&(_3b=!_3b);var inc=_3b?-1:1;var idx=this.header.getCellNodeIndex(_3a)+inc;var _3c=_38[idx];while(_3c&&_3c.getHeaderNode()&&_3c.getHeaderNode().style.display=="none"){idx+=inc;_3c=_38[idx];}if(_3c){return _3c.getHeaderNode();}return null;});if(this.grid.columnReordering&&this.simpleStructure){if(this.source){this.source.destroy();}var _3d="dojoxGrid_bottomMarker";var _3e="dojoxGrid_topMarker";if(this.bottomMarker){_24.destroy(this.bottomMarker);}this.bottomMarker=_24.byId(_3d);if(this.topMarker){_24.destroy(this.topMarker);}this.topMarker=_24.byId(_3e);if(!this.bottomMarker){this.bottomMarker=_24.create("div",{"id":_3d,"class":"dojoxGridColPlaceBottom"},win.body());this._hide(this.bottomMarker);this.topMarker=_24.create("div",{"id":_3e,"class":"dojoxGridColPlaceTop"},win.body());this._hide(this.topMarker);}this.arrowDim=_24.contentBox(this.bottomMarker);var _3f=_24.contentBox(this.headerContentNode.firstChild.rows[0]).h;this.source=new _1f(this.headerContentNode.firstChild.rows[0],{horizontal:true,accept:["gridColumn_"+this.grid.id],viewIndex:this.index,generateText:false,onMouseDown:_1b.hitch(this,function(e){this.header.decorateEvent(e);if((this.header.overRightResizeArea(e)||this.header.overLeftResizeArea(e))&&this.header.canResize(e)&&!this.header.moveable){this.header.beginColumnResize(e);}else{if(this.grid.headerMenu){this.grid.headerMenu.onCancel(true);}if(e.button===(has("ie")<9?1:0)){_1f.prototype.onMouseDown.call(this.source,e);}}}),onMouseOver:_1b.hitch(this,function(e){var src=this.source;if(src._getChildByEvent(e)){_1f.prototype.onMouseOver.apply(src,arguments);}}),_markTargetAnchor:_1b.hitch(this,function(_40){var src=this.source;if(src.current==src.targetAnchor&&src.before==_40){return;}if(src.targetAnchor&&_39(src.targetAnchor,src.before)){src._removeItemClass(_39(src.targetAnchor,src.before),src.before?"After":"Before");}_1f.prototype._markTargetAnchor.call(src,_40);var _41=_40?src.targetAnchor:_39(src.targetAnchor,src.before);var _42=0;if(!_41){_41=src.targetAnchor;_42=_24.contentBox(_41).w+this.arrowDim.w/2+2;}var pos=_24.position(_41,true);var _43=Math.floor(pos.x-this.arrowDim.w/2+_42);_24.style(this.bottomMarker,"visibility","visible");_24.style(this.topMarker,"visibility","visible");_24.style(this.bottomMarker,{"left":_43+"px","top":(_3f+pos.y)+"px"});_24.style(this.topMarker,{"left":_43+"px","top":(pos.y-this.arrowDim.h)+"px"});if(src.targetAnchor&&_39(src.targetAnchor,src.before)){src._addItemClass(_39(src.targetAnchor,src.before),src.before?"After":"Before");}}),_unmarkTargetAnchor:_1b.hitch(this,function(){var src=this.source;if(!src.targetAnchor){return;}if(src.targetAnchor&&_39(src.targetAnchor,src.before)){src._removeItemClass(_39(src.targetAnchor,src.before),src.before?"After":"Before");}this._hide(this.bottomMarker);this._hide(this.topMarker);_1f.prototype._unmarkTargetAnchor.call(src);}),destroy:_1b.hitch(this,function(){_1c.disconnect(this._source_conn);_1c.unsubscribe(this._source_sub);_1f.prototype.destroy.call(this.source);if(this.bottomMarker){_24.destroy(this.bottomMarker);delete this.bottomMarker;}if(this.topMarker){_24.destroy(this.topMarker);delete this.topMarker;}}),onDndCancel:_1b.hitch(this,function(){_1f.prototype.onDndCancel.call(this.source);this._hide(this.bottomMarker);this._hide(this.topMarker);})});this._source_conn=_1c.connect(this.source,"onDndDrop",this,"_onDndDrop");this._source_sub=_1c.subscribe("/dnd/drop/before",this,"_onDndDropBefore");this.source.startup();}},_hide:function(_44){_24.style(_44,{top:"-10000px","visibility":"hidden"});},_onDndDropBefore:function(_45,_46,_47){if(_16.dnd.manager().target!==this.source){return;}this.source._targetNode=this.source.targetAnchor;this.source._beforeTarget=this.source.before;var _48=this.grid.views.views;var _49=_48[_45.viewIndex];var _4a=_48[this.index];if(_4a!=_49){_49.convertColPctToFixed();_4a.convertColPctToFixed();}},_onDndDrop:function(_4b,_4c,_4d){if(_16.dnd.manager().target!==this.source){if(_16.dnd.manager().source===this.source){this._removingColumn=true;}return;}this._hide(this.bottomMarker);this._hide(this.topMarker);var _4e=function(n){return n?_24.attr(n,"idx"):null;};var w=_24.marginBox(_4c[0]).w;if(_4b.viewIndex!==this.index){var _4f=this.grid.views.views;var _50=_4f[_4b.viewIndex];var _51=_4f[this.index];if(_50.viewWidth&&_50.viewWidth!="auto"){_50.setColumnsWidth(_50.getColumnsWidth()-w);}if(_51.viewWidth&&_51.viewWidth!="auto"){_51.setColumnsWidth(_51.getColumnsWidth());}}var stn=this.source._targetNode;var stb=this.source._beforeTarget;!this.grid.isLeftToRight()&&(stb=!stb);var _52=this.grid.layout;var idx=this.index;delete this.source._targetNode;delete this.source._beforeTarget;_52.moveColumn(_4b.viewIndex,idx,_4e(_4c[0]),_4e(stn),stb);},renderHeader:function(){this.headerContentNode.innerHTML=this.header.generateHtml(this._getHeaderContent);if(this.flexCells){this.contentWidth=this.getContentWidth();this.headerContentNode.firstChild.style.width=this.contentWidth;}_23.fire(this,"onAfterRow",[-1,this.structure.cells,this.headerContentNode]);},_getHeaderContent:function(_53){var n=_53.name||_53.grid.getCellName(_53);if(/^\s+$/.test(n)){n="&nbsp;";}var ret=["<div class=\"dojoxGridSortNode"];if(_53.index!=_53.grid.getSortIndex()){ret.push("\">");}else{ret=ret.concat([" ",_53.grid.sortInfo>0?"dojoxGridSortUp":"dojoxGridSortDown","\"><div class=\"dojoxGridArrowButtonChar\">",_53.grid.sortInfo>0?"&#9650;":"&#9660;","</div><div class=\"dojoxGridArrowButtonNode\" role=\"presentation\"></div>","<div class=\"dojoxGridColCaption\">"]);}ret=ret.concat([n,"</div></div>"]);return ret.join("");},resize:function(){this.adaptHeight();this.adaptWidth();},hasHScrollbar:function(_54){var _55=this._hasHScroll||false;if(this._hasHScroll==undefined||_54){if(this.noscroll){this._hasHScroll=false;}else{var _56=_24.style(this.scrollboxNode,"overflow");if(_56=="hidden"){this._hasHScroll=false;}else{if(_56=="scroll"){this._hasHScroll=true;}else{this._hasHScroll=(this.scrollboxNode.offsetWidth-this.getScrollbarWidth()<this.contentNode.offsetWidth);}}}}if(_55!==this._hasHScroll){this.grid.update();}return this._hasHScroll;},hasVScrollbar:function(_57){var _58=this._hasVScroll||false;if(this._hasVScroll==undefined||_57){if(this.noscroll){this._hasVScroll=false;}else{var _59=_24.style(this.scrollboxNode,"overflow");if(_59=="hidden"){this._hasVScroll=false;}else{if(_59=="scroll"){this._hasVScroll=true;}else{this._hasVScroll=(this.scrollboxNode.scrollHeight>this.scrollboxNode.clientHeight);}}}}if(_58!==this._hasVScroll){this.grid.update();}return this._hasVScroll;},convertColPctToFixed:function(){var _5a=false;this.grid.initialWidth="";var _5b=_1d("th",this.headerContentNode);var _5c=_1a.map(_5b,function(c,_5d){var w=c.style.width;_24.attr(c,"vIdx",_5d);if(w&&w.slice(-1)=="%"){_5a=true;}else{if(w&&w.slice(-2)=="px"){return window.parseInt(w,10);}}return _24.contentBox(c).w;});if(_5a){_1a.forEach(this.grid.layout.cells,function(_5e,idx){if(_5e.view==this){var _5f=_5e.view.getHeaderCellNode(_5e.index);if(_5f&&_24.hasAttr(_5f,"vIdx")){var _60=window.parseInt(_24.attr(_5f,"vIdx"));this.setColWidth(idx,_5c[_60]);_24.removeAttr(_5f,"vIdx");}}},this);return true;}return false;},adaptHeight:function(_61){if(!this.grid._autoHeight){var h=(this.domNode.style.height&&parseInt(this.domNode.style.height.replace(/px/,""),10))||this.domNode.clientHeight;var _62=this;var _63=function(){var v;for(var i in _62.grid.views.views){v=_62.grid.views.views[i];if(v!==_62&&v.hasHScrollbar()){return true;}}return false;};if(_61||(this.noscroll&&_63())){h-=_22.getScrollbar().h;}_23.setStyleHeightPx(this.scrollboxNode,h);}this.hasVScrollbar(true);},adaptWidth:function(){if(this.flexCells){this.contentWidth=this.getContentWidth();this.headerContentNode.firstChild.style.width=this.contentWidth;}var w=this.scrollboxNode.offsetWidth-this.getScrollbarWidth();if(!this._removingColumn){w=Math.max(w,this.getColumnsWidth())+"px";}else{w=Math.min(w,this.getColumnsWidth())+"px";this._removingColumn=false;}var cn=this.contentNode;cn.style.width=w;this.hasHScrollbar(true);},setSize:function(w,h){var ds=this.domNode.style;var hs=this.headerNode.style;if(w){ds.width=w;hs.width=w;}ds.height=(h>=0?h+"px":"");},renderRow:function(_64){var _65=this.createRowNode(_64);this.buildRow(_64,_65);return _65;},createRowNode:function(_66){var _67=document.createElement("div");_67.className=this.classTag+"Row";if(this instanceof _18.grid._RowSelector){_24.attr(_67,"role","presentation");}else{_24.attr(_67,"role","row");if(this.grid.selectionMode!="none"){_67.setAttribute("aria-selected","false");}}_67[_23.gridViewTag]=this.id;_67[_23.rowIndexTag]=_66;this.rowNodes[_66]=_67;return _67;},buildRow:function(_68,_69){this.buildRowContent(_68,_69);this.styleRow(_68,_69);},buildRowContent:function(_6a,_6b){_6b.innerHTML=this.content.generateHtml(_6a,_6a);if(this.flexCells&&this.contentWidth){_6b.firstChild.style.width=this.contentWidth;}_23.fire(this,"onAfterRow",[_6a,this.structure.cells,_6b]);},rowRemoved:function(_6c){if(_6c>=0){this._cleanupRowWidgets(this.getRowNode(_6c));}this.grid.edit.save(this,_6c);delete this.rowNodes[_6c];},getRowNode:function(_6d){return this.rowNodes[_6d];},getCellNode:function(_6e,_6f){var row=this.getRowNode(_6e);if(row){return this.content.getCellNode(row,_6f);}},getHeaderCellNode:function(_70){if(this.headerContentNode){return this.header.getCellNode(this.headerContentNode,_70);}},styleRow:function(_71,_72){_72._style=_27(_72);this.styleRowNode(_71,_72);},styleRowNode:function(_73,_74){if(_74){this.doStyleRowNode(_73,_74);}},doStyleRowNode:function(_75,_76){this.grid.styleRowNode(_75,_76);},updateRow:function(_77){var _78=this.getRowNode(_77);if(_78){_78.style.height="";this.buildRow(_77,_78);}return _78;},updateRowStyles:function(_79){this.styleRowNode(_79,this.getRowNode(_79));},lastTop:0,firstScroll:0,doscroll:function(_7a){var _7b=this.grid.isLeftToRight();if(this.firstScroll<2){if((!_7b&&this.firstScroll==1)||(_7b&&this.firstScroll===0)){var s=_24.marginBox(this.headerNodeContainer);if(has("ie")){this.headerNodeContainer.style.width=s.w+this.getScrollbarWidth()+"px";}else{if(has("mozilla")){this.headerNodeContainer.style.width=s.w-this.getScrollbarWidth()+"px";this.scrollboxNode.scrollLeft=_7b?this.scrollboxNode.clientWidth-this.scrollboxNode.scrollWidth:this.scrollboxNode.scrollWidth-this.scrollboxNode.clientWidth;}}}this.firstScroll++;}this.headerNode.scrollLeft=this.scrollboxNode.scrollLeft;var top=this.scrollboxNode.scrollTop;if(top!==this.lastTop){this.grid.scrollTo(top);}},setScrollTop:function(_7c){this.lastTop=_7c;this.scrollboxNode.scrollTop=_7c;return this.scrollboxNode.scrollTop;},doContentEvent:function(e){if(this.content.decorateEvent(e)){this.grid.onContentEvent(e);}},doHeaderEvent:function(e){if(this.header.decorateEvent(e)){this.grid.onHeaderEvent(e);}},dispatchContentEvent:function(e){return this.content.dispatchEvent(e);},dispatchHeaderEvent:function(e){return this.header.dispatchEvent(e);},setColWidth:function(_7d,_7e){this.grid.setCellWidth(_7d,_7e+"px");},update:function(){if(!this.domNode){return;}this.content.update();this.grid.update();var _7f=this.scrollboxNode.scrollLeft;this.scrollboxNode.scrollLeft=_7f;this.headerNode.scrollLeft=_7f;}});var _80=_19("dojox.grid._GridAvatar",_26,{construct:function(){var dd=win.doc;var a=dd.createElement("table");a.cellPadding=a.cellSpacing="0";a.className="dojoxGridDndAvatar";a.style.position="absolute";a.style.zIndex=1999;a.style.margin="0px";var b=dd.createElement("tbody");var tr=dd.createElement("tr");var td=dd.createElement("td");var img=dd.createElement("td");tr.className="dojoxGridDndAvatarItem";img.className="dojoxGridDndAvatarItemImage";img.style.width="16px";var _81=this.manager.source,_82;if(_81.creator){_82=_81._normalizedCreator(_81.getItem(this.manager.nodes[0].id).data,"avatar").node;}else{_82=this.manager.nodes[0].cloneNode(true);var _83,_84;if(_82.tagName.toLowerCase()=="tr"){_83=dd.createElement("table");_84=dd.createElement("tbody");_84.appendChild(_82);_83.appendChild(_84);_82=_83;}else{if(_82.tagName.toLowerCase()=="th"){_83=dd.createElement("table");_84=dd.createElement("tbody");var r=dd.createElement("tr");_83.cellPadding=_83.cellSpacing="0";r.appendChild(_82);_84.appendChild(r);_83.appendChild(_84);_82=_83;}}}_82.id="";td.appendChild(_82);tr.appendChild(img);tr.appendChild(td);_24.style(tr,"opacity",0.9);b.appendChild(tr);a.appendChild(b);this.node=a;var m=_16.dnd.manager();this.oldOffsetY=m.OFFSET_Y;m.OFFSET_Y=1;},destroy:function(){_16.dnd.manager().OFFSET_Y=this.oldOffsetY;this.inherited(arguments);}});var _85=_16.dnd.manager().makeAvatar;_16.dnd.manager().makeAvatar=function(){var src=this.source;if(src.viewIndex!==undefined&&!_24.hasClass(win.body(),"dijit_a11y")){return new _80(this);}return _85.call(_16.dnd.manager());};return _2a;});},"dijit/_Contained":function(){define("dijit/_Contained",["dojo/_base/declare","./registry"],function(_86,_87){return _86("dijit._Contained",null,{_getSibling:function(_88){var _89=this.domNode;do{_89=_89[_88+"Sibling"];}while(_89&&_89.nodeType!=1);return _89&&_87.byNode(_89);},getPreviousSibling:function(){return this._getSibling("previous");},getNextSibling:function(){return this._getSibling("next");},getIndexInParent:function(){var p=this.getParent();if(!p||!p.getIndexOfChild){return -1;}return p.getIndexOfChild(this);}});});},"dojo/dnd/Selector":function(){define(["../main","./common","./Container"],function(_8a){_8a.declare("dojo.dnd.Selector",_8a.dnd.Container,{constructor:function(_8b,_8c){if(!_8c){_8c={};}this.singular=_8c.singular;this.autoSync=_8c.autoSync;this.selection={};this.anchor=null;this.simpleSelection=false;this.events.push(_8a.connect(this.node,"onmousedown",this,"onMouseDown"),_8a.connect(this.node,"onmouseup",this,"onMouseUp"));},singular:false,getSelectedNodes:function(){var t=new _8a.NodeList();var e=_8a.dnd._empty;for(var i in this.selection){if(i in e){continue;}t.push(_8a.byId(i));}return t;},selectNone:function(){return this._removeSelection()._removeAnchor();},selectAll:function(){this.forInItems(function(_8d,id){this._addItemClass(_8a.byId(id),"Selected");this.selection[id]=1;},this);return this._removeAnchor();},deleteSelectedNodes:function(){var e=_8a.dnd._empty;for(var i in this.selection){if(i in e){continue;}var n=_8a.byId(i);this.delItem(i);_8a.destroy(n);}this.anchor=null;this.selection={};return this;},forInSelectedItems:function(f,o){o=o||_8a.global;var s=this.selection,e=_8a.dnd._empty;for(var i in s){if(i in e){continue;}f.call(o,this.getItem(i),i,this);}},sync:function(){_8a.dnd.Selector.superclass.sync.call(this);if(this.anchor){if(!this.getItem(this.anchor.id)){this.anchor=null;}}var t=[],e=_8a.dnd._empty;for(var i in this.selection){if(i in e){continue;}if(!this.getItem(i)){t.push(i);}}_8a.forEach(t,function(i){delete this.selection[i];},this);return this;},insertNodes:function(_8e,_8f,_90,_91){var _92=this._normalizedCreator;this._normalizedCreator=function(_93,_94){var t=_92.call(this,_93,_94);if(_8e){if(!this.anchor){this.anchor=t.node;this._removeItemClass(t.node,"Selected");this._addItemClass(this.anchor,"Anchor");}else{if(this.anchor!=t.node){this._removeItemClass(t.node,"Anchor");this._addItemClass(t.node,"Selected");}}this.selection[t.node.id]=1;}else{this._removeItemClass(t.node,"Selected");this._removeItemClass(t.node,"Anchor");}return t;};_8a.dnd.Selector.superclass.insertNodes.call(this,_8f,_90,_91);this._normalizedCreator=_92;return this;},destroy:function(){_8a.dnd.Selector.superclass.destroy.call(this);this.selection=this.anchor=null;},onMouseDown:function(e){if(this.autoSync){this.sync();}if(!this.current){return;}if(!this.singular&&!_8a.isCopyKey(e)&&!e.shiftKey&&(this.current.id in this.selection)){this.simpleSelection=true;if(e.button===_8a.mouseButtons.LEFT){_8a.stopEvent(e);}return;}if(!this.singular&&e.shiftKey){if(!_8a.isCopyKey(e)){this._removeSelection();}var c=this.getAllNodes();if(c.length){if(!this.anchor){this.anchor=c[0];this._addItemClass(this.anchor,"Anchor");}this.selection[this.anchor.id]=1;if(this.anchor!=this.current){var i=0;for(;i<c.length;++i){var _95=c[i];if(_95==this.anchor||_95==this.current){break;}}for(++i;i<c.length;++i){var _95=c[i];if(_95==this.anchor||_95==this.current){break;}this._addItemClass(_95,"Selected");this.selection[_95.id]=1;}this._addItemClass(this.current,"Selected");this.selection[this.current.id]=1;}}}else{if(this.singular){if(this.anchor==this.current){if(_8a.isCopyKey(e)){this.selectNone();}}else{this.selectNone();this.anchor=this.current;this._addItemClass(this.anchor,"Anchor");this.selection[this.current.id]=1;}}else{if(_8a.isCopyKey(e)){if(this.anchor==this.current){delete this.selection[this.anchor.id];this._removeAnchor();}else{if(this.current.id in this.selection){this._removeItemClass(this.current,"Selected");delete this.selection[this.current.id];}else{if(this.anchor){this._removeItemClass(this.anchor,"Anchor");this._addItemClass(this.anchor,"Selected");}this.anchor=this.current;this._addItemClass(this.current,"Anchor");this.selection[this.current.id]=1;}}}else{if(!(this.current.id in this.selection)){this.selectNone();this.anchor=this.current;this._addItemClass(this.current,"Anchor");this.selection[this.current.id]=1;}}}}_8a.stopEvent(e);},onMouseUp:function(e){if(!this.simpleSelection){return;}this.simpleSelection=false;this.selectNone();if(this.current){this.anchor=this.current;this._addItemClass(this.anchor,"Anchor");this.selection[this.current.id]=1;}},onMouseMove:function(e){this.simpleSelection=false;},onOverEvent:function(){this.onmousemoveEvent=_8a.connect(this.node,"onmousemove",this,"onMouseMove");},onOutEvent:function(){_8a.disconnect(this.onmousemoveEvent);delete this.onmousemoveEvent;},_removeSelection:function(){var e=_8a.dnd._empty;for(var i in this.selection){if(i in e){continue;}var _96=_8a.byId(i);if(_96){this._removeItemClass(_96,"Selected");}}this.selection={};return this;},_removeAnchor:function(){if(this.anchor){this._removeItemClass(this.anchor,"Anchor");this.anchor=null;}return this;}});return _8a.dnd.Selector;});},"dojo/parser":function(){define(["./_base/kernel","./_base/lang","./_base/array","./_base/html","./_base/window","./_base/url","./_base/json","./aspect","./date/stamp","./query","./on","./ready"],function(_97,_98,_99,_9a,_9b,_9c,_9d,_9e,_9f,_a0,don){new Date("X");var _a1={"dom-attributes-explicit":document.createElement("div").attributes.length<40};function has(_a2){return _a1[_a2];};_97.parser=new function(){var _a3={};function _a4(_a5){var map={};for(var _a6 in _a5){if(_a6.charAt(0)=="_"){continue;}map[_a6.toLowerCase()]=_a6;}return map;};_9e.after(_98,"extend",function(){_a3={};},true);var _a7={};this._functionFromScript=function(_a8,_a9){var _aa="";var _ab="";var _ac=(_a8.getAttribute(_a9+"args")||_a8.getAttribute("args"));if(_ac){_99.forEach(_ac.split(/\s*,\s*/),function(_ad,idx){_aa+="var "+_ad+" = arguments["+idx+"]; ";});}var _ae=_a8.getAttribute("with");if(_ae&&_ae.length){_99.forEach(_ae.split(/\s*,\s*/),function(_af){_aa+="with("+_af+"){";_ab+="}";});}return new Function(_aa+_a8.innerHTML+_ab);};this.instantiate=function(_b0,_b1,_b2){var _b3=[],_b1=_b1||{};_b2=_b2||{};var _b4=(_b2.scope||_97._scopeName)+"Type",_b5="data-"+(_b2.scope||_97._scopeName)+"-",_b6=_b5+"type",_b7=_b5+"props",_b8=_b5+"attach-point",_b9=_b5+"attach-event",_ba=_b5+"id";var _bb={};_99.forEach([_b7,_b6,_b4,_ba,"jsId",_b8,_b9,"dojoAttachPoint","dojoAttachEvent","class","style"],function(_bc){_bb[_bc.toLowerCase()]=_bc.replace(_b2.scope,"dojo");});_99.forEach(_b0,function(obj){if(!obj){return;}var _bd=obj.node||obj,_be=_b4 in _b1?_b1[_b4]:obj.node?obj.type:(_bd.getAttribute(_b6)||_bd.getAttribute(_b4)),_bf=_a7[_be]||(_a7[_be]=_98.getObject(_be)),_c0=_bf&&_bf.prototype;if(!_bf){throw new Error("Could not load class '"+_be);}var _c1={};if(_b2.defaults){_98.mixin(_c1,_b2.defaults);}if(obj.inherited){_98.mixin(_c1,obj.inherited);}var _c2;if(has("dom-attributes-explicit")){_c2=_bd.attributes;}else{var _c3=/^input$|^img$/i.test(_bd.nodeName)?_bd:_bd.cloneNode(false),_c4=_c3.outerHTML.replace(/=[^\s"']+|="[^"]*"|='[^']*'/g,"").replace(/^\s*<[a-zA-Z0-9]*/,"").replace(/>.*$/,"");_c2=_99.map(_c4.split(/\s+/),function(_c5){var _c6=_c5.toLowerCase();return {name:_c5,value:(_bd.nodeName=="LI"&&_c5=="value")||_c6=="enctype"?_bd.getAttribute(_c6):_bd.getAttributeNode(_c6).value,specified:true};});}var i=0,_c7;while(_c7=_c2[i++]){if(!_c7||!_c7.specified){continue;}var _c8=_c7.name,_c9=_c8.toLowerCase(),_ca=_c7.value;if(_c9 in _bb){switch(_bb[_c9]){case "data-dojo-props":var _cb=_ca;break;case "data-dojo-id":case "jsId":var _cc=_ca;break;case "data-dojo-attach-point":case "dojoAttachPoint":_c1.dojoAttachPoint=_ca;break;case "data-dojo-attach-event":case "dojoAttachEvent":_c1.dojoAttachEvent=_ca;break;case "class":_c1["class"]=_bd.className;break;case "style":_c1["style"]=_bd.style&&_bd.style.cssText;break;}}else{if(!(_c8 in _c0)){var map=(_a3[_be]||(_a3[_be]=_a4(_c0)));_c8=map[_c9]||_c8;}if(_c8 in _c0){switch(typeof _c0[_c8]){case "string":_c1[_c8]=_ca;break;case "number":_c1[_c8]=_ca.length?Number(_ca):NaN;break;case "boolean":_c1[_c8]=_ca.toLowerCase()!="false";break;case "function":if(_ca===""||_ca.search(/[^\w\.]+/i)!=-1){_c1[_c8]=new Function(_ca);}else{_c1[_c8]=_98.getObject(_ca,false)||new Function(_ca);}break;default:var _cd=_c0[_c8];_c1[_c8]=(_cd&&"length" in _cd)?(_ca?_ca.split(/\s*,\s*/):[]):(_cd instanceof Date)?(_ca==""?new Date(""):_ca=="now"?new Date():_9f.fromISOString(_ca)):(_cd instanceof _97._Url)?(_97.baseUrl+_ca):_9d.fromJson(_ca);}}else{_c1[_c8]=_ca;}}}if(_cb){try{_cb=_9d.fromJson.call(_b2.propsThis,"{"+_cb+"}");_98.mixin(_c1,_cb);}catch(e){throw new Error(e.toString()+" in data-dojo-props='"+_cb+"'");}}_98.mixin(_c1,_b1);var _ce=obj.node?obj.scripts:(_bf&&(_bf._noScript||_c0._noScript)?[]:_a0("> script[type^='dojo/']",_bd));var _cf=[],_d0=[],_d1=[],on=[];if(_ce){for(i=0;i<_ce.length;i++){var _d2=_ce[i];_bd.removeChild(_d2);var _d3=(_d2.getAttribute(_b5+"event")||_d2.getAttribute("event")),_d4=_d2.getAttribute(_b5+"prop"),_be=_d2.getAttribute("type"),nf=this._functionFromScript(_d2,_b5);if(_d3){if(_be=="dojo/connect"){_cf.push({event:_d3,func:nf});}else{if(_be=="dojo/on"){on.push({event:_d3,func:nf});}else{_c1[_d3]=nf;}}}else{if(_be=="dojo/watch"){_d1.push({prop:_d4,func:nf});}else{_d0.push(nf);}}}}var _d5=_bf.markupFactory||_c0.markupFactory;var _d6=_d5?_d5(_c1,_bd,_bf):new _bf(_c1,_bd);_b3.push(_d6);if(_cc){_98.setObject(_cc,_d6);}for(i=0;i<_cf.length;i++){_9e.after(_d6,_cf[i].event,_97.hitch(_d6,_cf[i].func),true);}for(i=0;i<_d0.length;i++){_d0[i].call(_d6);}for(i=0;i<_d1.length;i++){_d6.watch(_d1[i].prop,_d1[i].func);}for(i=0;i<on.length;i++){don(_d6,on[i].event,on[i].func);}},this);if(!_b1._started){_99.forEach(_b3,function(_d7){if(!_b2.noStart&&_d7&&_98.isFunction(_d7.startup)&&!_d7._started){_d7.startup();}});}return _b3;};this.parse=function(_d8,_d9){var _da;if(!_d9&&_d8&&_d8.rootNode){_d9=_d8;_da=_d9.rootNode;}else{_da=_d8;}_da=_da?_9a.byId(_da):_9b.body();_d9=_d9||{};var _db=(_d9.scope||_97._scopeName)+"Type",_dc="data-"+(_d9.scope||_97._scopeName)+"-",_dd=_dc+"type",_de=_dc+"textdir";var _df=[];var _e0=_da.firstChild;var _e1=_d9&&_d9.inherited;if(!_e1){function _e2(_e3,_e4){return (_e3.getAttribute&&_e3.getAttribute(_e4))||(_e3!==_9b.doc&&_e3!==_9b.doc.documentElement&&_e3.parentNode?_e2(_e3.parentNode,_e4):null);};_e1={dir:_e2(_da,"dir"),lang:_e2(_da,"lang"),textDir:_e2(_da,_de)};for(var key in _e1){if(!_e1[key]){delete _e1[key];}}}var _e5={inherited:_e1};var _e6;var _e7;function _e8(_e9){if(!_e9.inherited){_e9.inherited={};var _ea=_e9.node,_eb=_e8(_e9.parent);var _ec={dir:_ea.getAttribute("dir")||_eb.dir,lang:_ea.getAttribute("lang")||_eb.lang,textDir:_ea.getAttribute(_de)||_eb.textDir};for(var key in _ec){if(_ec[key]){_e9.inherited[key]=_ec[key];}}}return _e9.inherited;};while(true){if(!_e0){if(!_e5||!_e5.node){break;}_e0=_e5.node.nextSibling;_e6=_e5.scripts;_e7=false;_e5=_e5.parent;continue;}if(_e0.nodeType!=1){_e0=_e0.nextSibling;continue;}if(_e6&&_e0.nodeName.toLowerCase()=="script"){_ed=_e0.getAttribute("type");if(_ed&&/^dojo\/\w/i.test(_ed)){_e6.push(_e0);}_e0=_e0.nextSibling;continue;}if(_e7){_e0=_e0.nextSibling;continue;}var _ed=_e0.getAttribute(_dd)||_e0.getAttribute(_db);var _ee=_e0.firstChild;if(!_ed&&(!_ee||(_ee.nodeType==3&&!_ee.nextSibling))){_e0=_e0.nextSibling;continue;}var _ef={node:_e0,scripts:_e6,parent:_e5};var _f0=_ed&&(_a7[_ed]||(_a7[_ed]=_98.getObject(_ed))),_f1=_f0&&!_f0.prototype._noScript?[]:null;if(_ed){_df.push({"type":_ed,node:_e0,scripts:_f1,inherited:_e8(_ef)});}_e0=_ee;_e6=_f1;_e7=_f0&&_f0.prototype.stopParser&&!(_d9&&_d9.template);_e5=_ef;}var _f2=_d9&&_d9.template?{template:true}:null;return this.instantiate(_df,_f2,_d9);};}();if(_97.config.parseOnLoad){_97.ready(100,_97.parser,"parse");}return _97.parser;});},"dojox/grid/DataSelection":function(){define("dojox/grid/DataSelection",["dojo/_base/declare","./_SelectionPreserver","./Selection"],function(_f3,_f4,_f5){return _f3("dojox.grid.DataSelection",_f5,{constructor:function(_f6){if(_f6.keepSelection){this.preserver=new _f4(this);}},destroy:function(){if(this.preserver){this.preserver.destroy();}},getFirstSelected:function(){var idx=_f5.prototype.getFirstSelected.call(this);if(idx==-1){return null;}return this.grid.getItem(idx);},getNextSelected:function(_f7){var _f8=this.grid.getItemIndex(_f7);var idx=_f5.prototype.getNextSelected.call(this,_f8);if(idx==-1){return null;}return this.grid.getItem(idx);},getSelected:function(){var _f9=[];for(var i=0,l=this.selected.length;i<l;i++){if(this.selected[i]){_f9.push(this.grid.getItem(i));}}return _f9;},addToSelection:function(_fa){if(this.mode=="none"){return;}var idx=null;if(typeof _fa=="number"||typeof _fa=="string"){idx=_fa;}else{idx=this.grid.getItemIndex(_fa);}_f5.prototype.addToSelection.call(this,idx);},deselect:function(_fb){if(this.mode=="none"){return;}var idx=null;if(typeof _fb=="number"||typeof _fb=="string"){idx=_fb;}else{idx=this.grid.getItemIndex(_fb);}_f5.prototype.deselect.call(this,idx);},deselectAll:function(_fc){var idx=null;if(_fc||typeof _fc=="number"){if(typeof _fc=="number"||typeof _fc=="string"){idx=_fc;}else{idx=this.grid.getItemIndex(_fc);}_f5.prototype.deselectAll.call(this,idx);}else{this.inherited(arguments);}}});});},"url:dijit/templates/CheckedMenuItem.html":"<tr class=\"dijitReset dijitMenuItem\" data-dojo-attach-point=\"focusNode\" role=\"menuitemcheckbox\" tabIndex=\"-1\"\n\t\tdata-dojo-attach-event=\"onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick\">\n\t<td class=\"dijitReset dijitMenuItemIconCell\" role=\"presentation\">\n\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitMenuItemIcon dijitCheckedMenuItemIcon\" data-dojo-attach-point=\"iconNode\"/>\n\t\t<span class=\"dijitCheckedMenuItemIconChar\">&#10003;</span>\n\t</td>\n\t<td class=\"dijitReset dijitMenuItemLabel\" colspan=\"2\" data-dojo-attach-point=\"containerNode,labelNode\"></td>\n\t<td class=\"dijitReset dijitMenuItemAccelKey\" style=\"display: none\" data-dojo-attach-point=\"accelKeyNode\"></td>\n\t<td class=\"dijitReset dijitMenuArrowCell\" role=\"presentation\">&#160;</td>\n</tr>\n","dojo/dnd/Manager":function(){define(["../main","../Evented","./common","./autoscroll","./Avatar"],function(_fd,_fe){var _ff=_fd.declare("dojo.dnd.Manager",[_fe],{constructor:function(){this.avatar=null;this.source=null;this.nodes=[];this.copy=true;this.target=null;this.canDropFlag=false;this.events=[];},OFFSET_X:16,OFFSET_Y:16,overSource:function(_100){if(this.avatar){this.target=(_100&&_100.targetState!="Disabled")?_100:null;this.canDropFlag=Boolean(this.target);this.avatar.update();}_fd.publish("/dnd/source/over",[_100]);},outSource:function(_101){if(this.avatar){if(this.target==_101){this.target=null;this.canDropFlag=false;this.avatar.update();_fd.publish("/dnd/source/over",[null]);}}else{_fd.publish("/dnd/source/over",[null]);}},startDrag:function(_102,_103,copy){this.source=_102;this.nodes=_103;this.copy=Boolean(copy);this.avatar=this.makeAvatar();_fd.body().appendChild(this.avatar.node);_fd.publish("/dnd/start",[_102,_103,this.copy]);this.events=[_fd.connect(_fd.doc,"onmousemove",this,"onMouseMove"),_fd.connect(_fd.doc,"onmouseup",this,"onMouseUp"),_fd.connect(_fd.doc,"onkeydown",this,"onKeyDown"),_fd.connect(_fd.doc,"onkeyup",this,"onKeyUp"),_fd.connect(_fd.doc,"ondragstart",_fd.stopEvent),_fd.connect(_fd.body(),"onselectstart",_fd.stopEvent)];var c="dojoDnd"+(copy?"Copy":"Move");_fd.addClass(_fd.body(),c);},canDrop:function(flag){var _104=Boolean(this.target&&flag);if(this.canDropFlag!=_104){this.canDropFlag=_104;this.avatar.update();}},stopDrag:function(){_fd.removeClass(_fd.body(),["dojoDndCopy","dojoDndMove"]);_fd.forEach(this.events,_fd.disconnect);this.events=[];this.avatar.destroy();this.avatar=null;this.source=this.target=null;this.nodes=[];},makeAvatar:function(){return new _fd.dnd.Avatar(this);},updateAvatar:function(){this.avatar.update();},onMouseMove:function(e){var a=this.avatar;if(a){_fd.dnd.autoScrollNodes(e);var s=a.node.style;s.left=(e.pageX+this.OFFSET_X)+"px";s.top=(e.pageY+this.OFFSET_Y)+"px";var copy=Boolean(this.source.copyState(_fd.isCopyKey(e)));if(this.copy!=copy){this._setCopyStatus(copy);}}},onMouseUp:function(e){if(this.avatar){if(this.target&&this.canDropFlag){var copy=Boolean(this.source.copyState(_fd.isCopyKey(e))),_105=[this.source,this.nodes,copy,this.target,e];_fd.publish("/dnd/drop/before",_105);_fd.publish("/dnd/drop",_105);}else{_fd.publish("/dnd/cancel");}this.stopDrag();}},onKeyDown:function(e){if(this.avatar){switch(e.keyCode){case _fd.keys.CTRL:var copy=Boolean(this.source.copyState(true));if(this.copy!=copy){this._setCopyStatus(copy);}break;case _fd.keys.ESCAPE:_fd.publish("/dnd/cancel");this.stopDrag();break;}}},onKeyUp:function(e){if(this.avatar&&e.keyCode==_fd.keys.CTRL){var copy=Boolean(this.source.copyState(false));if(this.copy!=copy){this._setCopyStatus(copy);}}},_setCopyStatus:function(copy){this.copy=copy;this.source._markDndStatus(this.copy);this.updateAvatar();_fd.replaceClass(_fd.body(),"dojoDnd"+(this.copy?"Copy":"Move"),"dojoDnd"+(this.copy?"Move":"Copy"));}});_fd.dnd._manager=null;_ff.manager=_fd.dnd.manager=function(){if(!_fd.dnd._manager){_fd.dnd._manager=new _fd.dnd.Manager();}return _fd.dnd._manager;};return _ff;});},"dojox/grid/_RowSelector":function(){define("dojox/grid/_RowSelector",["dojo/_base/declare","./_View"],function(_106,_107){return _106("dojox.grid._RowSelector",_107,{defaultWidth:"2em",noscroll:true,padBorderWidth:2,buildRendering:function(){this.inherited("buildRendering",arguments);this.scrollboxNode.style.overflow="hidden";this.headerNode.style.visibility="hidden";},getWidth:function(){return this.viewWidth||this.defaultWidth;},buildRowContent:function(_108,_109){var w=this.contentWidth||0;_109.innerHTML="<table class=\"dojoxGridRowbarTable\" style=\"width:"+w+"px;height:1px;\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\" role=\"presentation\"><tr><td class=\"dojoxGridRowbarInner\">&nbsp;</td></tr></table>";},renderHeader:function(){},updateRow:function(){},resize:function(){this.adaptHeight();},adaptWidth:function(){if(!("contentWidth" in this)&&this.contentNode){this.contentWidth=this.contentNode.offsetWidth-this.padBorderWidth;}},doStyleRowNode:function(_10a,_10b){var n=["dojoxGridRowbar dojoxGridNonNormalizedCell"];if(this.grid.rows.isOver(_10a)){n.push("dojoxGridRowbarOver");}if(this.grid.selection.isSelected(_10a)){n.push("dojoxGridRowbarSelected");}_10b.className=n.join(" ");},domouseover:function(e){this.grid.onMouseOverRow(e);},domouseout:function(e){if(!this.isIntraRowEvent(e)){this.grid.onMouseOutRow(e);}}});});},"dojox/grid/_Layout":function(){define("dojox/grid/_Layout",["dojo/_base/kernel","../main","dojo/_base/declare","dojo/_base/array","dojo/_base/lang","dojo/dom-geometry","./cells","./_RowSelector"],function(dojo,_10c,_10d,_10e,lang,_10f){return _10d("dojox.grid._Layout",null,{constructor:function(_110){this.grid=_110;},cells:[],structure:null,defaultWidth:"6em",moveColumn:function(_111,_112,_113,_114,_115){var _116=this.structure[_111].cells[0];var _117=this.structure[_112].cells[0];var cell=null;var _118=0;var _119=0;for(var i=0,c;c=_116[i];i++){if(c.index==_113){_118=i;break;}}cell=_116.splice(_118,1)[0];cell.view=this.grid.views.views[_112];for(i=0,c=null;c=_117[i];i++){if(c.index==_114){_119=i;break;}}if(!_115){_119+=1;}_117.splice(_119,0,cell);var _11a=this.grid.getCell(this.grid.getSortIndex());if(_11a){_11a._currentlySorted=this.grid.getSortAsc();}this.cells=[];_113=0;var v;for(i=0;v=this.structure[i];i++){for(var j=0,cs;cs=v.cells[j];j++){for(var k=0;c=cs[k];k++){c.index=_113;this.cells.push(c);if("_currentlySorted" in c){var si=_113+1;si*=c._currentlySorted?1:-1;this.grid.sortInfo=si;delete c._currentlySorted;}_113++;}}}_10e.forEach(this.cells,function(c){var _11b=c.markup[2].split(" ");var _11c=parseInt(_11b[1].substring(5));if(_11c!=c.index){_11b[1]="idx=\""+c.index+"\"";c.markup[2]=_11b.join(" ");}});this.grid.setupHeaderMenu();},setColumnVisibility:function(_11d,_11e){var cell=this.cells[_11d];if(cell.hidden==_11e){cell.hidden=!_11e;var v=cell.view,w=v.viewWidth;if(w&&w!="auto"){v._togglingColumn=_10f.getMarginBox(cell.getHeaderNode()).w||0;}v.update();return true;}else{return false;}},addCellDef:function(_11f,_120,_121){var self=this;var _122=function(_123){var w=0;if(_123.colSpan>1){w=0;}else{w=_123.width||self._defaultCellProps.width||self.defaultWidth;if(!isNaN(w)){w=w+"em";}}return w;};var _124={grid:this.grid,subrow:_11f,layoutIndex:_120,index:this.cells.length};if(_121&&_121 instanceof _10c.grid.cells._Base){var _125=lang.clone(_121);_124.unitWidth=_122(_125._props);_125=lang.mixin(_125,this._defaultCellProps,_121._props,_124);return _125;}var _126=_121.type||_121.cellType||this._defaultCellProps.type||this._defaultCellProps.cellType||_10c.grid.cells.Cell;if(lang.isString(_126)){_126=lang.getObject(_126);}_124.unitWidth=_122(_121);return new _126(lang.mixin({},this._defaultCellProps,_121,_124));},addRowDef:function(_127,_128){var _129=[];var _12a=0,_12b=0,_12c=true;for(var i=0,def,cell;(def=_128[i]);i++){cell=this.addCellDef(_127,i,def);_129.push(cell);this.cells.push(cell);if(_12c&&cell.relWidth){_12a+=cell.relWidth;}else{if(cell.width){var w=cell.width;if(typeof w=="string"&&w.slice(-1)=="%"){_12b+=window.parseInt(w,10);}else{if(w=="auto"){_12c=false;}}}}}if(_12a&&_12c){_10e.forEach(_129,function(cell){if(cell.relWidth){cell.width=cell.unitWidth=((cell.relWidth/_12a)*(100-_12b))+"%";}});}return _129;},addRowsDef:function(_12d){var _12e=[];if(lang.isArray(_12d)){if(lang.isArray(_12d[0])){for(var i=0,row;_12d&&(row=_12d[i]);i++){_12e.push(this.addRowDef(i,row));}}else{_12e.push(this.addRowDef(0,_12d));}}return _12e;},addViewDef:function(_12f){this._defaultCellProps=_12f.defaultCell||{};if(_12f.width&&_12f.width=="auto"){delete _12f.width;}return lang.mixin({},_12f,{cells:this.addRowsDef(_12f.rows||_12f.cells)});},setStructure:function(_130){this.fieldIndex=0;this.cells=[];var s=this.structure=[];if(this.grid.rowSelector){var sel={type:_10c._scopeName+".grid._RowSelector"};if(lang.isString(this.grid.rowSelector)){var _131=this.grid.rowSelector;if(_131=="false"){sel=null;}else{if(_131!="true"){sel["width"]=_131;}}}else{if(!this.grid.rowSelector){sel=null;}}if(sel){s.push(this.addViewDef(sel));}}var _132=function(def){return ("name" in def||"field" in def||"get" in def);};var _133=function(def){if(lang.isArray(def)){if(lang.isArray(def[0])||_132(def[0])){return true;}}return false;};var _134=function(def){return (def!==null&&lang.isObject(def)&&("cells" in def||"rows" in def||("type" in def&&!_132(def))));};if(lang.isArray(_130)){var _135=false;for(var i=0,st;(st=_130[i]);i++){if(_134(st)){_135=true;break;}}if(!_135){s.push(this.addViewDef({cells:_130}));}else{for(i=0;(st=_130[i]);i++){if(_133(st)){s.push(this.addViewDef({cells:st}));}else{if(_134(st)){s.push(this.addViewDef(st));}}}}}else{if(_134(_130)){s.push(this.addViewDef(_130));}}this.cellCount=this.cells.length;this.grid.setupHeaderMenu();}});});},"dojox/grid/_Grid":function(){require({cache:{"url:dojox/grid/resources/_Grid.html":"<div hidefocus=\"hidefocus\" role=\"grid\" dojoAttachEvent=\"onmouseout:_mouseOut\">\n\t<div class=\"dojoxGridMasterHeader\" dojoAttachPoint=\"viewsHeaderNode\" role=\"presentation\"></div>\n\t<div class=\"dojoxGridMasterView\" dojoAttachPoint=\"viewsNode\" role=\"presentation\"></div>\n\t<div class=\"dojoxGridMasterMessages\" style=\"display: none;\" dojoAttachPoint=\"messagesNode\"></div>\n\t<span dojoAttachPoint=\"lastFocusNode\" tabindex=\"0\"></span>\n</div>\n"}});define("dojox/grid/_Grid",["dojo/_base/kernel","../main","dojo/_base/declare","./_Events","./_Scroller","./_Layout","./_View","./_ViewManager","./_RowManager","./_FocusManager","./_EditManager","./Selection","./_RowSelector","./util","dijit/_Widget","dijit/_TemplatedMixin","dijit/CheckedMenuItem","dojo/text!./resources/_Grid.html","dojo/string","dojo/_base/array","dojo/_base/lang","dojo/_base/sniff","dojox/html/metrics","dojo/_base/html","dojo/query","dojo/dnd/common","dojo/i18n!dijit/nls/loading"],function(dojo,_136,_137,_138,_139,_13a,_13b,_13c,_13d,_13e,_13f,_140,_141,util,_142,_143,_144,_145,_146,_147,lang,has,_148,html,_149){if(!dojo.isCopyKey){dojo.isCopyKey=dojo.dnd.getCopyKeyState;}var _14a=_137("dojox.grid._Grid",[_142,_143,_138],{templateString:_145,classTag:"dojoxGrid",rowCount:5,keepRows:75,rowsPerPage:25,autoWidth:false,initialWidth:"",autoHeight:"",rowHeight:0,autoRender:true,defaultHeight:"15em",height:"",structure:null,elasticView:-1,singleClickEdit:false,selectionMode:"extended",rowSelector:"",columnReordering:false,headerMenu:null,placeholderLabel:"GridColumns",selectable:false,_click:null,loadingMessage:"<span class='dojoxGridLoading'>${loadingState}</span>",errorMessage:"<span class='dojoxGridError'>${errorState}</span>",noDataMessage:"",escapeHTMLInData:true,formatterScope:null,editable:false,sortInfo:0,themeable:true,_placeholders:null,_layoutClass:_13a,buildRendering:function(){this.inherited(arguments);if(!this.domNode.getAttribute("tabIndex")){this.domNode.tabIndex="0";}this.createScroller();this.createLayout();this.createViews();this.createManagers();this.createSelection();this.connect(this.selection,"onSelected","onSelected");this.connect(this.selection,"onDeselected","onDeselected");this.connect(this.selection,"onChanged","onSelectionChanged");_148.initOnFontResize();this.connect(_148,"onFontResize","textSizeChanged");util.funnelEvents(this.domNode,this,"doKeyEvent",util.keyEvents);if(this.selectionMode!="none"){this.domNode.setAttribute("aria-multiselectable",this.selectionMode=="single"?"false":"true");}html.addClass(this.domNode,this.classTag);if(!this.isLeftToRight()){html.addClass(this.domNode,this.classTag+"Rtl");}},postMixInProperties:function(){this.inherited(arguments);var _14b=dojo.i18n.getLocalization("dijit","loading",this.lang);this.loadingMessage=_146.substitute(this.loadingMessage,_14b);this.errorMessage=_146.substitute(this.errorMessage,_14b);if(this.srcNodeRef&&this.srcNodeRef.style.height){this.height=this.srcNodeRef.style.height;}this._setAutoHeightAttr(this.autoHeight,true);this.lastScrollTop=this.scrollTop=0;},postCreate:function(){this._placeholders=[];this._setHeaderMenuAttr(this.headerMenu);this._setStructureAttr(this.structure);this._click=[];this.inherited(arguments);if(this.domNode&&this.autoWidth&&this.initialWidth){this.domNode.style.width=this.initialWidth;}if(this.domNode&&!this.editable){html.attr(this.domNode,"aria-readonly","true");}},destroy:function(){this.domNode.onReveal=null;this.domNode.onSizeChange=null;delete this._click;if(this.scroller){this.scroller.destroy();delete this.scroller;}this.edit.destroy();delete this.edit;this.views.destroyViews();if(this.focus){this.focus.destroy();delete this.focus;}if(this.headerMenu&&this._placeholders.length){_147.forEach(this._placeholders,function(p){p.unReplace(true);});this.headerMenu.unBindDomNode(this.viewsHeaderNode);}this.inherited(arguments);},_setAutoHeightAttr:function(ah,_14c){if(typeof ah=="string"){if(!ah||ah=="false"){ah=false;}else{if(ah=="true"){ah=true;}else{ah=window.parseInt(ah,10);}}}if(typeof ah=="number"){if(isNaN(ah)){ah=false;}if(ah<0){ah=true;}else{if(ah===0){ah=false;}}}this.autoHeight=ah;if(typeof ah=="boolean"){this._autoHeight=ah;}else{if(typeof ah=="number"){this._autoHeight=(ah>=this.get("rowCount"));}else{this._autoHeight=false;}}if(this._started&&!_14c){this.render();}},_getRowCountAttr:function(){return this.updating&&this.invalidated&&this.invalidated.rowCount!=undefined?this.invalidated.rowCount:this.rowCount;},textSizeChanged:function(){this.render();},sizeChange:function(){this.update();},createManagers:function(){this.rows=new _13d(this);this.focus=new _13e(this);this.edit=new _13f(this);},createSelection:function(){this.selection=new _140(this);},createScroller:function(){this.scroller=new _139();this.scroller.grid=this;this.scroller.renderRow=lang.hitch(this,"renderRow");this.scroller.removeRow=lang.hitch(this,"rowRemoved");},createLayout:function(){this.layout=new this._layoutClass(this);this.connect(this.layout,"moveColumn","onMoveColumn");},onMoveColumn:function(){this.render();},onResizeColumn:function(_14d){},createViews:function(){this.views=new _13c(this);this.views.createView=lang.hitch(this,"createView");},createView:function(_14e,idx){var c=lang.getObject(_14e);var view=new c({grid:this,index:idx});this.viewsNode.appendChild(view.domNode);this.viewsHeaderNode.appendChild(view.headerNode);this.views.addView(view);html.attr(this.domNode,"align",this.isLeftToRight()?"left":"right");return view;},buildViews:function(){for(var i=0,vs;(vs=this.layout.structure[i]);i++){this.createView(vs.type||_136._scopeName+".grid._View",i).setStructure(vs);}this.scroller.setContentNodes(this.views.getContentNodes());},_setStructureAttr:function(_14f){var s=_14f;if(s&&lang.isString(s)){dojo.deprecated("dojox.grid._Grid.set('structure', 'objVar')","use dojox.grid._Grid.set('structure', objVar) instead","2.0");s=lang.getObject(s);}this.structure=s;if(!s){if(this.layout.structure){s=this.layout.structure;}else{return;}}this.views.destroyViews();this.focus.focusView=null;if(s!==this.layout.structure){this.layout.setStructure(s);}this._structureChanged();},setStructure:function(_150){dojo.deprecated("dojox.grid._Grid.setStructure(obj)","use dojox.grid._Grid.set('structure', obj) instead.","2.0");this._setStructureAttr(_150);},getColumnTogglingItems:function(){var _151,_152=[];_151=_147.map(this.layout.cells,function(cell){if(!cell.menuItems){cell.menuItems=[];}var self=this;var item=new _144({label:cell.name,checked:!cell.hidden,_gridCell:cell,onChange:function(_153){if(self.layout.setColumnVisibility(this._gridCell.index,_153)){var _154=this._gridCell.menuItems;if(_154.length>1){_147.forEach(_154,function(item){if(item!==this){item.setAttribute("checked",_153);}},this);}_153=_147.filter(self.layout.cells,function(c){if(c.menuItems.length>1){_147.forEach(c.menuItems,"item.set('disabled', false);");}else{c.menuItems[0].set("disabled",false);}return !c.hidden;});if(_153.length==1){_147.forEach(_153[0].menuItems,"item.set('disabled', true);");}}},destroy:function(){var _155=_147.indexOf(this._gridCell.menuItems,this);this._gridCell.menuItems.splice(_155,1);delete this._gridCell;_144.prototype.destroy.apply(this,arguments);}});cell.menuItems.push(item);if(!cell.hidden){_152.push(item);}return item;},this);if(_152.length==1){_152[0].set("disabled",true);}return _151;},_setHeaderMenuAttr:function(menu){if(this._placeholders&&this._placeholders.length){_147.forEach(this._placeholders,function(p){p.unReplace(true);});this._placeholders=[];}if(this.headerMenu){this.headerMenu.unBindDomNode(this.viewsHeaderNode);}this.headerMenu=menu;if(!menu){return;}this.headerMenu.bindDomNode(this.viewsHeaderNode);if(this.headerMenu.getPlaceholders){this._placeholders=this.headerMenu.getPlaceholders(this.placeholderLabel);}},setHeaderMenu:function(menu){dojo.deprecated("dojox.grid._Grid.setHeaderMenu(obj)","use dojox.grid._Grid.set('headerMenu', obj) instead.","2.0");this._setHeaderMenuAttr(menu);},setupHeaderMenu:function(){if(this._placeholders&&this._placeholders.length){_147.forEach(this._placeholders,function(p){if(p._replaced){p.unReplace(true);}p.replace(this.getColumnTogglingItems());},this);}},_fetch:function(_156){this.setScrollTop(0);},getItem:function(_157){return null;},showMessage:function(_158){if(_158){this.messagesNode.innerHTML=_158;this.messagesNode.style.display="";}else{this.messagesNode.innerHTML="";this.messagesNode.style.display="none";}},_structureChanged:function(){this.buildViews();if(this.autoRender&&this._started){this.render();}},hasLayout:function(){return this.layout.cells.length;},resize:function(_159,_15a){if(dojo.isIE&&!_159&&!_15a&&this._autoHeight){return;}this._pendingChangeSize=_159;this._pendingResultSize=_15a;this.sizeChange();},_getPadBorder:function(){this._padBorder=this._padBorder||html._getPadBorderExtents(this.domNode);return this._padBorder;},_getHeaderHeight:function(){var vns=this.viewsHeaderNode.style,t=vns.display=="none"?0:this.views.measureHeader();vns.height=t+"px";this.views.normalizeHeaderNodeHeight();return t;},_resize:function(_15b,_15c){_15b=_15b||this._pendingChangeSize;_15c=_15c||this._pendingResultSize;delete this._pendingChangeSize;delete this._pendingResultSize;if(!this.domNode){return;}var pn=this.domNode.parentNode;if(!pn||pn.nodeType!=1||!this.hasLayout()||pn.style.visibility=="hidden"||pn.style.display=="none"){return;}var _15d=this._getPadBorder();var hh=undefined;var h;if(this._autoHeight){this.domNode.style.height="auto";}else{if(typeof this.autoHeight=="number"){h=hh=this._getHeaderHeight();h+=(this.scroller.averageRowHeight*this.autoHeight);this.domNode.style.height=h+"px";}else{if(this.domNode.clientHeight<=_15d.h){if(pn==document.body){this.domNode.style.height=this.defaultHeight;}else{if(this.height){this.domNode.style.height=this.height;}else{this.fitTo="parent";}}}}}if(_15c){_15b=_15c;}if(!this._autoHeight&&_15b){html.marginBox(this.domNode,_15b);this.height=this.domNode.style.height;delete this.fitTo;}else{if(this.fitTo=="parent"){h=this._parentContentBoxHeight=this._parentContentBoxHeight||html._getContentBox(pn).h;this.domNode.style.height=Math.max(0,h)+"px";}}var _15e=_147.some(this.views.views,function(v){return v.flexCells;});if(!this._autoHeight&&(h||html._getContentBox(this.domNode).h)===0){this.viewsHeaderNode.style.display="none";}else{this.viewsHeaderNode.style.display="block";if(!_15e&&hh===undefined){hh=this._getHeaderHeight();}}if(_15e){hh=undefined;}this.adaptWidth();this.adaptHeight(hh);this.postresize();},adaptWidth:function(){var _15f=(!this.initialWidth&&this.autoWidth);var w=_15f?0:this.domNode.clientWidth||(this.domNode.offsetWidth-this._getPadBorder().w),vw=this.views.arrange(1,w);this.views.onEach("adaptWidth");if(_15f){this.domNode.style.width=vw+"px";}},adaptHeight:function(_160){var t=_160===undefined?this._getHeaderHeight():_160;var h=(this._autoHeight?-1:Math.max(this.domNode.clientHeight-t,0)||0);this.views.onEach("setSize",[0,h]);this.views.onEach("adaptHeight");if(!this._autoHeight){var _161=0,_162=0;var _163=_147.filter(this.views.views,function(v){var has=v.hasHScrollbar();if(has){_161++;}else{_162++;}return (!has);});if(_161>0&&_162>0){_147.forEach(_163,function(v){v.adaptHeight(true);});}}if(this.autoHeight===true||h!=-1||(typeof this.autoHeight=="number"&&this.autoHeight>=this.get("rowCount"))){this.scroller.windowHeight=h;}else{this.scroller.windowHeight=Math.max(this.domNode.clientHeight-t,0);}},startup:function(){if(this._started){return;}this.inherited(arguments);if(this.autoRender){this.render();}},render:function(){if(!this.domNode){return;}if(!this._started){return;}if(!this.hasLayout()){this.scroller.init(0,this.keepRows,this.rowsPerPage);return;}this.update=this.defaultUpdate;this._render();},_render:function(){this.scroller.init(this.get("rowCount"),this.keepRows,this.rowsPerPage);this.prerender();this.setScrollTop(0);this.postrender();},prerender:function(){this.keepRows=this._autoHeight?0:this.keepRows;this.scroller.setKeepInfo(this.keepRows);this.views.render();this._resize();},postrender:function(){this.postresize();this.focus.initFocusView();html.setSelectable(this.domNode,this.selectable);},postresize:function(){if(this._autoHeight){var size=Math.max(this.views.measureContent())+"px";this.viewsNode.style.height=size;}},renderRow:function(_164,_165){this.views.renderRow(_164,_165,this._skipRowRenormalize);},rowRemoved:function(_166){this.views.rowRemoved(_166);},invalidated:null,updating:false,beginUpdate:function(){this.invalidated=[];this.updating=true;},endUpdate:function(){this.updating=false;var i=this.invalidated,r;if(i.all){this.update();}else{if(i.rowCount!=undefined){this.updateRowCount(i.rowCount);}else{for(r in i){this.updateRow(Number(r));}}}this.invalidated=[];},defaultUpdate:function(){if(!this.domNode){return;}if(this.updating){this.invalidated.all=true;return;}this.lastScrollTop=this.scrollTop;this.prerender();this.scroller.invalidateNodes();this.setScrollTop(this.lastScrollTop);this.postrender();},update:function(){this.render();},updateRow:function(_167){_167=Number(_167);if(this.updating){this.invalidated[_167]=true;}else{this.views.updateRow(_167);this.scroller.rowHeightChanged(_167);}},updateRows:function(_168,_169){_168=Number(_168);_169=Number(_169);var i;if(this.updating){for(i=0;i<_169;i++){this.invalidated[i+_168]=true;}}else{for(i=0;i<_169;i++){this.views.updateRow(i+_168,this._skipRowRenormalize);}this.scroller.rowHeightChanged(_168);}},updateRowCount:function(_16a){if(this.updating){this.invalidated.rowCount=_16a;}else{this.rowCount=_16a;this._setAutoHeightAttr(this.autoHeight,true);if(this.layout.cells.length){this.scroller.updateRowCount(_16a);}this._resize();if(this.layout.cells.length){this.setScrollTop(this.scrollTop);}}},updateRowStyles:function(_16b){this.views.updateRowStyles(_16b);},getRowNode:function(_16c){if(this.focus.focusView&&!(this.focus.focusView instanceof _141)){return this.focus.focusView.rowNodes[_16c];}else{for(var i=0,_16d;(_16d=this.views.views[i]);i++){if(!(_16d instanceof _141)){return _16d.rowNodes[_16c];}}}return null;},rowHeightChanged:function(_16e){this.views.renormalizeRow(_16e);this.scroller.rowHeightChanged(_16e);},fastScroll:true,delayScroll:false,scrollRedrawThreshold:(has("ie")?100:50),scrollTo:function(_16f){if(!this.fastScroll){this.setScrollTop(_16f);return;}var _170=Math.abs(this.lastScrollTop-_16f);this.lastScrollTop=_16f;if(_170>this.scrollRedrawThreshold||this.delayScroll){this.delayScroll=true;this.scrollTop=_16f;this.views.setScrollTop(_16f);if(this._pendingScroll){window.clearTimeout(this._pendingScroll);}var _171=this;this._pendingScroll=window.setTimeout(function(){delete _171._pendingScroll;_171.finishScrollJob();},200);}else{this.setScrollTop(_16f);}},finishScrollJob:function(){this.delayScroll=false;this.setScrollTop(this.scrollTop);},setScrollTop:function(_172){this.scroller.scroll(this.views.setScrollTop(_172));},scrollToRow:function(_173){this.setScrollTop(this.scroller.findScrollTop(_173)+1);},styleRowNode:function(_174,_175){if(_175){this.rows.styleRowNode(_174,_175);}},_mouseOut:function(e){this.rows.setOverRow(-2);},getCell:function(_176){return this.layout.cells[_176];},setCellWidth:function(_177,_178){this.getCell(_177).unitWidth=_178;},getCellName:function(_179){return "Cell "+_179.index;},canSort:function(_17a){},sort:function(){},getSortAsc:function(_17b){_17b=_17b==undefined?this.sortInfo:_17b;return Boolean(_17b>0);},getSortIndex:function(_17c){_17c=_17c==undefined?this.sortInfo:_17c;return Math.abs(_17c)-1;},setSortIndex:function(_17d,_17e){var si=_17d+1;if(_17e!=undefined){si*=(_17e?1:-1);}else{if(this.getSortIndex()==_17d){si=-this.sortInfo;}}this.setSortInfo(si);},setSortInfo:function(_17f){if(this.canSort(_17f)){this.sortInfo=_17f;this.sort();this.update();}},doKeyEvent:function(e){e.dispatch="do"+e.type;this.onKeyEvent(e);},_dispatch:function(m,e){if(m in this){return this[m](e);}return false;},dispatchKeyEvent:function(e){this._dispatch(e.dispatch,e);},dispatchContentEvent:function(e){this.edit.dispatchEvent(e)||e.sourceView.dispatchContentEvent(e)||this._dispatch(e.dispatch,e);},dispatchHeaderEvent:function(e){e.sourceView.dispatchHeaderEvent(e)||this._dispatch("doheader"+e.type,e);},dokeydown:function(e){this.onKeyDown(e);},doclick:function(e){if(e.cellNode){this.onCellClick(e);}else{this.onRowClick(e);}},dodblclick:function(e){if(e.cellNode){this.onCellDblClick(e);}else{this.onRowDblClick(e);}},docontextmenu:function(e){if(e.cellNode){this.onCellContextMenu(e);}else{this.onRowContextMenu(e);}},doheaderclick:function(e){if(e.cellNode){this.onHeaderCellClick(e);}else{this.onHeaderClick(e);}},doheaderdblclick:function(e){if(e.cellNode){this.onHeaderCellDblClick(e);}else{this.onHeaderDblClick(e);}},doheadercontextmenu:function(e){if(e.cellNode){this.onHeaderCellContextMenu(e);}else{this.onHeaderContextMenu(e);}},doStartEdit:function(_180,_181){this.onStartEdit(_180,_181);},doApplyCellEdit:function(_182,_183,_184){this.onApplyCellEdit(_182,_183,_184);},doCancelEdit:function(_185){this.onCancelEdit(_185);},doApplyEdit:function(_186){this.onApplyEdit(_186);},addRow:function(){this.updateRowCount(this.get("rowCount")+1);},removeSelectedRows:function(){if(this.allItemsSelected){this.updateRowCount(0);}else{this.updateRowCount(Math.max(0,this.get("rowCount")-this.selection.getSelected().length));}this.selection.clear();}});_14a.markupFactory=function(_187,node,ctor,_188){var _189=function(n){var w=html.attr(n,"width")||"auto";if((w!="auto")&&(w.slice(-2)!="em")&&(w.slice(-1)!="%")){w=parseInt(w,10)+"px";}return w;};if(!_187.structure&&node.nodeName.toLowerCase()=="table"){_187.structure=_149("> colgroup",node).map(function(cg){var sv=html.attr(cg,"span");var v={noscroll:(html.attr(cg,"noscroll")=="true")?true:false,__span:(!!sv?parseInt(sv,10):1),cells:[]};if(html.hasAttr(cg,"width")){v.width=_189(cg);}return v;});if(!_187.structure.length){_187.structure.push({__span:Infinity,cells:[]});}_149("thead > tr",node).forEach(function(tr,_18a){var _18b=0;var _18c=0;var _18d;var _18e=null;_149("> th",tr).map(function(th){if(!_18e){_18d=0;_18e=_187.structure[0];}else{if(_18b>=(_18d+_18e.__span)){_18c++;_18d+=_18e.__span;var _18f=_18e;_18e=_187.structure[_18c];}}var cell={name:lang.trim(html.attr(th,"name")||th.innerHTML),colSpan:parseInt(html.attr(th,"colspan")||1,10),type:lang.trim(html.attr(th,"cellType")||""),id:lang.trim(html.attr(th,"id")||"")};_18b+=cell.colSpan;var _190=html.attr(th,"rowspan");if(_190){cell.rowSpan=_190;}if(html.hasAttr(th,"width")){cell.width=_189(th);}if(html.hasAttr(th,"relWidth")){cell.relWidth=window.parseInt(html.attr(th,"relWidth"),10);}if(html.hasAttr(th,"hidden")){cell.hidden=(html.attr(th,"hidden")=="true"||html.attr(th,"hidden")===true);}if(_188){_188(th,cell);}cell.type=cell.type?lang.getObject(cell.type):_136.grid.cells.Cell;if(cell.type&&cell.type.markupFactory){cell.type.markupFactory(th,cell);}if(!_18e.cells[_18a]){_18e.cells[_18a]=[];}_18e.cells[_18a].push(cell);});});}return new ctor(_187,node);};return _14a;});},"dijit/nls/loading":function(){define("dijit/nls/loading",{root:({loadingState:"Loading...",errorState:"Sorry, an error occurred"}),"zh":true,"zh-tw":true,"tr":true,"th":true,"sv":true,"sl":true,"sk":true,"ru":true,"ro":true,"pt":true,"pt-pt":true,"pl":true,"nl":true,"nb":true,"ko":true,"kk":true,"ja":true,"it":true,"hu":true,"hr":true,"he":true,"fr":true,"fi":true,"es":true,"el":true,"de":true,"da":true,"cs":true,"ca":true,"az":true,"ar":true});},"dojox/main":function(){define("dojox/main",["dojo/_base/kernel"],function(dojo){return dojo.dojox;});},"dojo/dnd/Mover":function(){define(["../main","../Evented","../touch","./common","./autoscroll"],function(dojo,_191,_192){dojo.declare("dojo.dnd.Mover",[_191],{constructor:function(node,e,host){this.node=dojo.byId(node);this.marginBox={l:e.pageX,t:e.pageY};this.mouseButton=e.button;var h=(this.host=host),d=node.ownerDocument;this.events=[dojo.connect(d,_192.move,this,"onFirstMove"),dojo.connect(d,_192.move,this,"onMouseMove"),dojo.connect(d,_192.release,this,"onMouseUp"),dojo.connect(d,"ondragstart",dojo.stopEvent),dojo.connect(d.body,"onselectstart",dojo.stopEvent)];if(h&&h.onMoveStart){h.onMoveStart(this);}},onMouseMove:function(e){dojo.dnd.autoScroll(e);var m=this.marginBox;this.host.onMove(this,{l:m.l+e.pageX,t:m.t+e.pageY},e);dojo.stopEvent(e);},onMouseUp:function(e){if(dojo.isWebKit&&dojo.isMac&&this.mouseButton==2?e.button==0:this.mouseButton==e.button){this.destroy();}dojo.stopEvent(e);},onFirstMove:function(e){var s=this.node.style,l,t,h=this.host;switch(s.position){case "relative":case "absolute":l=Math.round(parseFloat(s.left))||0;t=Math.round(parseFloat(s.top))||0;break;default:s.position="absolute";var m=dojo.marginBox(this.node);var b=dojo.doc.body;var bs=dojo.getComputedStyle(b);var bm=dojo._getMarginBox(b,bs);var bc=dojo._getContentBox(b,bs);l=m.l-(bc.l-bm.l);t=m.t-(bc.t-bm.t);break;}this.marginBox.l=l-this.marginBox.l;this.marginBox.t=t-this.marginBox.t;if(h&&h.onFirstMove){h.onFirstMove(this,e);}dojo.disconnect(this.events.shift());},destroy:function(){dojo.forEach(this.events,dojo.disconnect);var h=this.host;if(h&&h.onMoveStop){h.onMoveStop(this);}this.events=this.node=this.host=null;}});return dojo.dnd.Mover;});},"dojo/Stateful":function(){define(["./_base/kernel","./_base/declare","./_base/lang","./_base/array"],function(dojo,_193,lang,_194){return dojo.declare("dojo.Stateful",null,{postscript:function(_195){if(_195){lang.mixin(this,_195);}},get:function(name){return this[name];},set:function(name,_196){if(typeof name==="object"){for(var x in name){this.set(x,name[x]);}return this;}var _197=this[name];this[name]=_196;if(this._watchCallbacks){this._watchCallbacks(name,_197,_196);}return this;},watch:function(name,_198){var _199=this._watchCallbacks;if(!_199){var self=this;_199=this._watchCallbacks=function(name,_19a,_19b,_19c){var _19d=function(_19e){if(_19e){_19e=_19e.slice();for(var i=0,l=_19e.length;i<l;i++){try{_19e[i].call(self,name,_19a,_19b);}catch(e){console.error(e);}}}};_19d(_199["_"+name]);if(!_19c){_19d(_199["*"]);}};}if(!_198&&typeof name==="function"){_198=name;name="*";}else{name="_"+name;}var _19f=_199[name];if(typeof _19f!=="object"){_19f=_199[name]=[];}_19f.push(_198);return {unwatch:function(){_19f.splice(_194.indexOf(_19f,_198),1);}};}});});},"dojo/touch":function(){define(["./_base/kernel","./on","./has","./mouse"],function(dojo,on,has,_1a0){function _1a1(type){return function(node,_1a2){return on(node,type,_1a2);};};var _1a3=has("touch");dojo.touch={press:_1a1(_1a3?"touchstart":"mousedown"),move:_1a1(_1a3?"touchmove":"mousemove"),release:_1a1(_1a3?"touchend":"mouseup"),cancel:_1a3?_1a1("touchcancel"):_1a0.leave};return dojo.touch;});},"dojox/grid/Selection":function(){define("dojox/grid/Selection",["dojo/_base/declare","dojo/_base/array","dojo/_base/lang","dojo/dom-attr"],function(_1a4,_1a5,lang,_1a6){return _1a4("dojox.grid.Selection",null,{constructor:function(_1a7){this.grid=_1a7;this.selected=[];this.setMode(_1a7.selectionMode);},mode:"extended",selected:null,updating:0,selectedIndex:-1,setMode:function(mode){if(this.selected.length){this.deselectAll();}if(mode!="extended"&&mode!="multiple"&&mode!="single"&&mode!="none"){this.mode="extended";}else{this.mode=mode;}},onCanSelect:function(_1a8){return this.grid.onCanSelect(_1a8);},onCanDeselect:function(_1a9){return this.grid.onCanDeselect(_1a9);},onSelected:function(_1aa){},onDeselected:function(_1ab){},onChanging:function(){},onChanged:function(){},isSelected:function(_1ac){if(this.mode=="none"){return false;}return this.selected[_1ac];},getFirstSelected:function(){if(!this.selected.length||this.mode=="none"){return -1;}for(var i=0,l=this.selected.length;i<l;i++){if(this.selected[i]){return i;}}return -1;},getNextSelected:function(_1ad){if(this.mode=="none"){return -1;}for(var i=_1ad+1,l=this.selected.length;i<l;i++){if(this.selected[i]){return i;}}return -1;},getSelected:function(){var _1ae=[];for(var i=0,l=this.selected.length;i<l;i++){if(this.selected[i]){_1ae.push(i);}}return _1ae;},getSelectedCount:function(){var c=0;for(var i=0;i<this.selected.length;i++){if(this.selected[i]){c++;}}return c;},_beginUpdate:function(){if(this.updating===0){this.onChanging();}this.updating++;},_endUpdate:function(){this.updating--;if(this.updating===0){this.onChanged();}},select:function(_1af){if(this.mode=="none"){return;}if(this.mode!="multiple"){this.deselectAll(_1af);this.addToSelection(_1af);}else{this.toggleSelect(_1af);}},addToSelection:function(_1b0){if(this.mode=="none"){return;}if(lang.isArray(_1b0)){_1a5.forEach(_1b0,this.addToSelection,this);return;}_1b0=Number(_1b0);if(this.selected[_1b0]){this.selectedIndex=_1b0;}else{if(this.onCanSelect(_1b0)!==false){this.selectedIndex=_1b0;var _1b1=this.grid.getRowNode(_1b0);if(_1b1){_1a6.set(_1b1,"aria-selected","true");}this._beginUpdate();this.selected[_1b0]=true;this.onSelected(_1b0);this._endUpdate();}}},deselect:function(_1b2){if(this.mode=="none"){return;}if(lang.isArray(_1b2)){_1a5.forEach(_1b2,this.deselect,this);return;}_1b2=Number(_1b2);if(this.selectedIndex==_1b2){this.selectedIndex=-1;}if(this.selected[_1b2]){if(this.onCanDeselect(_1b2)===false){return;}var _1b3=this.grid.getRowNode(_1b2);if(_1b3){_1a6.set(_1b3,"aria-selected","false");}this._beginUpdate();delete this.selected[_1b2];this.onDeselected(_1b2);this._endUpdate();}},setSelected:function(_1b4,_1b5){this[(_1b5?"addToSelection":"deselect")](_1b4);},toggleSelect:function(_1b6){if(lang.isArray(_1b6)){_1a5.forEach(_1b6,this.toggleSelect,this);return;}this.setSelected(_1b6,!this.selected[_1b6]);},_range:function(_1b7,inTo,func){var s=(_1b7>=0?_1b7:inTo),e=inTo;if(s>e){e=s;s=inTo;}for(var i=s;i<=e;i++){func(i);}},selectRange:function(_1b8,inTo){this._range(_1b8,inTo,lang.hitch(this,"addToSelection"));},deselectRange:function(_1b9,inTo){this._range(_1b9,inTo,lang.hitch(this,"deselect"));},insert:function(_1ba){this.selected.splice(_1ba,0,false);if(this.selectedIndex>=_1ba){this.selectedIndex++;}},remove:function(_1bb){this.selected.splice(_1bb,1);if(this.selectedIndex>=_1bb){this.selectedIndex--;}},deselectAll:function(_1bc){for(var i in this.selected){if((i!=_1bc)&&(this.selected[i]===true)){this.deselect(i);}}},clickSelect:function(_1bd,_1be,_1bf){if(this.mode=="none"){return;}this._beginUpdate();if(this.mode!="extended"){this.select(_1bd);}else{var _1c0=this.selectedIndex;if(!_1be){this.deselectAll(_1bd);}if(_1bf){this.selectRange(_1c0,_1bd);}else{if(_1be){this.toggleSelect(_1bd);}else{this.addToSelection(_1bd);}}}this._endUpdate();},clickSelectEvent:function(e){this.clickSelect(e.rowIndex,dojo.isCopyKey(e),e.shiftKey);},clear:function(){this._beginUpdate();this.deselectAll();this._endUpdate();}});});},"dijit/_CssStateMixin":function(){define("dijit/_CssStateMixin",["dojo/touch","dojo/_base/array","dojo/_base/declare","dojo/dom-class","dojo/_base/lang","dojo/_base/window"],function(_1c1,_1c2,_1c3,_1c4,lang,win){return _1c3("dijit._CssStateMixin",[],{cssStateNodes:{},hovering:false,active:false,_applyAttributes:function(){this.inherited(arguments);_1c2.forEach(["onmouseenter","onmouseleave",_1c1.press],function(e){this.connect(this.domNode,e,"_cssMouseEvent");},this);_1c2.forEach(["disabled","readOnly","checked","selected","focused","state","hovering","active"],function(attr){this.watch(attr,lang.hitch(this,"_setStateClass"));},this);for(var ap in this.cssStateNodes){this._trackMouseState(this[ap],this.cssStateNodes[ap]);}this._setStateClass();},_cssMouseEvent:function(_1c5){if(!this.disabled){switch(_1c5.type){case "mouseenter":case "mouseover":this._set("hovering",true);this._set("active",this._mouseDown);break;case "mouseleave":case "mouseout":this._set("hovering",false);this._set("active",false);break;case "mousedown":case "touchpress":this._set("active",true);this._mouseDown=true;var _1c6=this.connect(win.body(),_1c1.release,function(){this._mouseDown=false;this._set("active",false);this.disconnect(_1c6);});break;}}},_setStateClass:function(){var _1c7=this.baseClass.split(" ");function _1c8(_1c9){_1c7=_1c7.concat(_1c2.map(_1c7,function(c){return c+_1c9;}),"dijit"+_1c9);};if(!this.isLeftToRight()){_1c8("Rtl");}var _1ca=this.checked=="mixed"?"Mixed":(this.checked?"Checked":"");if(this.checked){_1c8(_1ca);}if(this.state){_1c8(this.state);}if(this.selected){_1c8("Selected");}if(this.disabled){_1c8("Disabled");}else{if(this.readOnly){_1c8("ReadOnly");}else{if(this.active){_1c8("Active");}else{if(this.hovering){_1c8("Hover");}}}}if(this.focused){_1c8("Focused");}var tn=this.stateNode||this.domNode,_1cb={};_1c2.forEach(tn.className.split(" "),function(c){_1cb[c]=true;});if("_stateClasses" in this){_1c2.forEach(this._stateClasses,function(c){delete _1cb[c];});}_1c2.forEach(_1c7,function(c){_1cb[c]=true;});var _1cc=[];for(var c in _1cb){_1cc.push(c);}tn.className=_1cc.join(" ");this._stateClasses=_1c7;},_trackMouseState:function(node,_1cd){var _1ce=false,_1cf=false,_1d0=false;var self=this,cn=lang.hitch(this,"connect",node);function _1d1(){var _1d2=("disabled" in self&&self.disabled)||("readonly" in self&&self.readonly);_1c4.toggle(node,_1cd+"Hover",_1ce&&!_1cf&&!_1d2);_1c4.toggle(node,_1cd+"Active",_1cf&&!_1d2);_1c4.toggle(node,_1cd+"Focused",_1d0&&!_1d2);};cn("onmouseenter",function(){_1ce=true;_1d1();});cn("onmouseleave",function(){_1ce=false;_1cf=false;_1d1();});cn(_1c1.press,function(){_1cf=true;_1d1();});cn(_1c1.release,function(){_1cf=false;_1d1();});cn("onfocus",function(){_1d0=true;_1d1();});cn("onblur",function(){_1d0=false;_1d1();});this.watch("disabled",_1d1);this.watch("readOnly",_1d1);}});});},"url:dojox/grid/resources/_Grid.html":"<div hidefocus=\"hidefocus\" role=\"grid\" dojoAttachEvent=\"onmouseout:_mouseOut\">\n\t<div class=\"dojoxGridMasterHeader\" dojoAttachPoint=\"viewsHeaderNode\" role=\"presentation\"></div>\n\t<div class=\"dojoxGridMasterView\" dojoAttachPoint=\"viewsNode\" role=\"presentation\"></div>\n\t<div class=\"dojoxGridMasterMessages\" style=\"display: none;\" dojoAttachPoint=\"messagesNode\"></div>\n\t<span dojoAttachPoint=\"lastFocusNode\" tabindex=\"0\"></span>\n</div>\n","dojox/grid/_RowManager":function(){define("dojox/grid/_RowManager",["dojo/_base/declare","dojo/_base/lang","dojo/dom-class"],function(_1d3,lang,_1d4){var _1d5=function(_1d6,_1d7){if(_1d6.style.cssText==undefined){_1d6.setAttribute("style",_1d7);}else{_1d6.style.cssText=_1d7;}};return _1d3("dojox.grid._RowManager",null,{constructor:function(_1d8){this.grid=_1d8;},linesToEms:2,overRow:-2,prepareStylingRow:function(_1d9,_1da){return {index:_1d9,node:_1da,odd:Boolean(_1d9&1),selected:!!this.grid.selection.isSelected(_1d9),over:this.isOver(_1d9),customStyles:"",customClasses:"dojoxGridRow"};},styleRowNode:function(_1db,_1dc){var row=this.prepareStylingRow(_1db,_1dc);this.grid.onStyleRow(row);this.applyStyles(row);},applyStyles:function(_1dd){var i=_1dd;i.node.className=i.customClasses;var h=i.node.style.height;_1d5(i.node,i.customStyles+";"+(i.node._style||""));i.node.style.height=h;},updateStyles:function(_1de){this.grid.updateRowStyles(_1de);},setOverRow:function(_1df){var last=this.overRow;this.overRow=_1df;if((last!=this.overRow)&&(lang.isString(last)||last>=0)){this.updateStyles(last);}this.updateStyles(this.overRow);},isOver:function(_1e0){return (this.overRow==_1e0&&!_1d4.contains(this.grid.domNode,"dojoxGridColumnResizing"));}});});},"dojo/_base/url":function(){define(["./kernel"],function(dojo){var ore=new RegExp("^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?$"),ire=new RegExp("^((([^\\[:]+):)?([^@]+)@)?(\\[([^\\]]+)\\]|([^\\[:]*))(:([0-9]+))?$"),_1e1=function(){var n=null,_1e2=arguments,uri=[_1e2[0]];for(var i=1;i<_1e2.length;i++){if(!_1e2[i]){continue;}var _1e3=new _1e1(_1e2[i]+""),_1e4=new _1e1(uri[0]+"");if(_1e3.path==""&&!_1e3.scheme&&!_1e3.authority&&!_1e3.query){if(_1e3.fragment!=n){_1e4.fragment=_1e3.fragment;}_1e3=_1e4;}else{if(!_1e3.scheme){_1e3.scheme=_1e4.scheme;if(!_1e3.authority){_1e3.authority=_1e4.authority;if(_1e3.path.charAt(0)!="/"){var path=_1e4.path.substring(0,_1e4.path.lastIndexOf("/")+1)+_1e3.path;var segs=path.split("/");for(var j=0;j<segs.length;j++){if(segs[j]=="."){if(j==segs.length-1){segs[j]="";}else{segs.splice(j,1);j--;}}else{if(j>0&&!(j==1&&segs[0]=="")&&segs[j]==".."&&segs[j-1]!=".."){if(j==(segs.length-1)){segs.splice(j,1);segs[j-1]="";}else{segs.splice(j-1,2);j-=2;}}}}_1e3.path=segs.join("/");}}}}uri=[];if(_1e3.scheme){uri.push(_1e3.scheme,":");}if(_1e3.authority){uri.push("//",_1e3.authority);}uri.push(_1e3.path);if(_1e3.query){uri.push("?",_1e3.query);}if(_1e3.fragment){uri.push("#",_1e3.fragment);}}this.uri=uri.join("");var r=this.uri.match(ore);this.scheme=r[2]||(r[1]?"":n);this.authority=r[4]||(r[3]?"":n);this.path=r[5];this.query=r[7]||(r[6]?"":n);this.fragment=r[9]||(r[8]?"":n);if(this.authority!=n){r=this.authority.match(ire);this.user=r[3]||n;this.password=r[4]||n;this.host=r[6]||r[7];this.port=r[9]||n;}};_1e1.prototype.toString=function(){return this.uri;};return dojo._Url=_1e1;});},"dojo/string":function(){define(["./_base/kernel","./_base/lang"],function(dojo,lang){lang.getObject("string",true,dojo);dojo.string.rep=function(str,num){if(num<=0||!str){return "";}var buf=[];for(;;){if(num&1){buf.push(str);}if(!(num>>=1)){break;}str+=str;}return buf.join("");};dojo.string.pad=function(text,size,ch,end){if(!ch){ch="0";}var out=String(text),pad=dojo.string.rep(ch,Math.ceil((size-out.length)/ch.length));return end?out+pad:pad+out;};dojo.string.substitute=function(_1e5,map,_1e6,_1e7){_1e7=_1e7||dojo.global;_1e6=_1e6?lang.hitch(_1e7,_1e6):function(v){return v;};return _1e5.replace(/\$\{([^\s\:\}]+)(?:\:([^\s\:\}]+))?\}/g,function(_1e8,key,_1e9){var _1ea=lang.getObject(key,false,map);if(_1e9){_1ea=lang.getObject(_1e9,false,_1e7).call(_1e7,_1ea,key);}return _1e6(_1ea,key).toString();});};dojo.string.trim=String.prototype.trim?lang.trim:function(str){str=str.replace(/^\s+/,"");for(var i=str.length-1;i>=0;i--){if(/\S/.test(str.charAt(i))){str=str.substring(0,i+1);break;}}return str;};return dojo.string;});},"dojo/dnd/Avatar":function(){define(["../main","./common"],function(dojo){dojo.declare("dojo.dnd.Avatar",null,{constructor:function(_1eb){this.manager=_1eb;this.construct();},construct:function(){this.isA11y=dojo.hasClass(dojo.body(),"dijit_a11y");var a=dojo.create("table",{"class":"dojoDndAvatar",style:{position:"absolute",zIndex:"1999",margin:"0px"}}),_1ec=this.manager.source,node,b=dojo.create("tbody",null,a),tr=dojo.create("tr",null,b),td=dojo.create("td",null,tr),icon=this.isA11y?dojo.create("span",{id:"a11yIcon",innerHTML:this.manager.copy?"+":"<"},td):null,span=dojo.create("span",{innerHTML:_1ec.generateText?this._generateText():""},td),k=Math.min(5,this.manager.nodes.length),i=0;dojo.attr(tr,{"class":"dojoDndAvatarHeader",style:{opacity:0.9}});for(;i<k;++i){if(_1ec.creator){node=_1ec._normalizedCreator(_1ec.getItem(this.manager.nodes[i].id).data,"avatar").node;}else{node=this.manager.nodes[i].cloneNode(true);if(node.tagName.toLowerCase()=="tr"){var _1ed=dojo.create("table"),_1ee=dojo.create("tbody",null,_1ed);_1ee.appendChild(node);node=_1ed;}}node.id="";tr=dojo.create("tr",null,b);td=dojo.create("td",null,tr);td.appendChild(node);dojo.attr(tr,{"class":"dojoDndAvatarItem",style:{opacity:(9-i)/10}});}this.node=a;},destroy:function(){dojo.destroy(this.node);this.node=false;},update:function(){dojo[(this.manager.canDropFlag?"add":"remove")+"Class"](this.node,"dojoDndAvatarCanDrop");if(this.isA11y){var icon=dojo.byId("a11yIcon");var text="+";if(this.manager.canDropFlag&&!this.manager.copy){text="< ";}else{if(!this.manager.canDropFlag&&!this.manager.copy){text="o";}else{if(!this.manager.canDropFlag){text="x";}}}icon.innerHTML=text;}dojo.query(("tr.dojoDndAvatarHeader td span"+(this.isA11y?" span":"")),this.node).forEach(function(node){node.innerHTML=this._generateText();},this);},_generateText:function(){return this.manager.nodes.length.toString();}});return dojo.dnd.Avatar;});},"dojox/grid/_Scroller":function(){define("dojox/grid/_Scroller",["dijit/registry","dojo/_base/declare","dojo/_base/lang","./util","dojo/_base/html"],function(_1ef,_1f0,lang,util,html){var _1f1=function(_1f2){var i=0,n,p=_1f2.parentNode;while((n=p.childNodes[i++])){if(n==_1f2){return i-1;}}return -1;};var _1f3=function(_1f4){if(!_1f4){return;}dojo.forEach(_1ef.toArray(),function(w){if(w.domNode&&html.isDescendant(w.domNode,_1f4,true)){w.destroy();}});};var _1f5=function(_1f6){var node=html.byId(_1f6);return (node&&node.tagName?node.tagName.toLowerCase():"");};var _1f7=function(_1f8,_1f9){var _1fa=[];var i=0,n;while((n=_1f8.childNodes[i])){i++;if(_1f5(n)==_1f9){_1fa.push(n);}}return _1fa;};var _1fb=function(_1fc){return _1f7(_1fc,"div");};return _1f0("dojox.grid._Scroller",null,{constructor:function(_1fd){this.setContentNodes(_1fd);this.pageHeights=[];this.pageNodes=[];this.stack=[];},rowCount:0,defaultRowHeight:32,keepRows:100,contentNode:null,scrollboxNode:null,defaultPageHeight:0,keepPages:10,pageCount:0,windowHeight:0,firstVisibleRow:0,lastVisibleRow:0,averageRowHeight:0,page:0,pageTop:0,init:function(_1fe,_1ff,_200){switch(arguments.length){case 3:this.rowsPerPage=_200;case 2:this.keepRows=_1ff;case 1:this.rowCount=_1fe;default:break;}this.defaultPageHeight=this.defaultRowHeight*this.rowsPerPage;this.pageCount=this._getPageCount(this.rowCount,this.rowsPerPage);this.setKeepInfo(this.keepRows);this.invalidate();if(this.scrollboxNode){this.scrollboxNode.scrollTop=0;this.scroll(0);this.scrollboxNode.onscroll=lang.hitch(this,"onscroll");}},_getPageCount:function(_201,_202){return _201?(Math.ceil(_201/_202)||1):0;},destroy:function(){this.invalidateNodes();delete this.contentNodes;delete this.contentNode;delete this.scrollboxNode;},setKeepInfo:function(_203){this.keepRows=_203;this.keepPages=!this.keepRows?this.keepPages:Math.max(Math.ceil(this.keepRows/this.rowsPerPage),2);},setContentNodes:function(_204){this.contentNodes=_204;this.colCount=(this.contentNodes?this.contentNodes.length:0);this.pageNodes=[];for(var i=0;i<this.colCount;i++){this.pageNodes[i]=[];}},getDefaultNodes:function(){return this.pageNodes[0]||[];},invalidate:function(){this._invalidating=true;this.invalidateNodes();this.pageHeights=[];this.height=(this.pageCount?(this.pageCount-1)*this.defaultPageHeight+this.calcLastPageHeight():0);this.resize();this._invalidating=false;},updateRowCount:function(_205){this.invalidateNodes();this.rowCount=_205;var _206=this.pageCount;if(_206===0){this.height=1;}this.pageCount=this._getPageCount(this.rowCount,this.rowsPerPage);if(this.pageCount<_206){for(var i=_206-1;i>=this.pageCount;i--){this.height-=this.getPageHeight(i);delete this.pageHeights[i];}}else{if(this.pageCount>_206){this.height+=this.defaultPageHeight*(this.pageCount-_206-1)+this.calcLastPageHeight();}}this.resize();},pageExists:function(_207){return Boolean(this.getDefaultPageNode(_207));},measurePage:function(_208){if(this.grid.rowHeight){var _209=this.grid.rowHeight+1;return ((_208+1)*this.rowsPerPage>this.rowCount?this.rowCount-_208*this.rowsPerPage:this.rowsPerPage)*_209;}var n=this.getDefaultPageNode(_208);return (n&&n.innerHTML)?n.offsetHeight:undefined;},positionPage:function(_20a,_20b){for(var i=0;i<this.colCount;i++){this.pageNodes[i][_20a].style.top=_20b+"px";}},repositionPages:function(_20c){var _20d=this.getDefaultNodes();var last=0;for(var i=0;i<this.stack.length;i++){last=Math.max(this.stack[i],last);}var n=_20d[_20c];var y=(n?this.getPageNodePosition(n)+this.getPageHeight(_20c):0);for(var p=_20c+1;p<=last;p++){n=_20d[p];if(n){if(this.getPageNodePosition(n)==y){return;}this.positionPage(p,y);}y+=this.getPageHeight(p);}},installPage:function(_20e){for(var i=0;i<this.colCount;i++){this.contentNodes[i].appendChild(this.pageNodes[i][_20e]);}},preparePage:function(_20f,_210){var p=(_210?this.popPage():null);for(var i=0;i<this.colCount;i++){var _211=this.pageNodes[i];var _212=(p===null?this.createPageNode():this.invalidatePageNode(p,_211));_212.pageIndex=_20f;_211[_20f]=_212;}},renderPage:function(_213){var _214=[];var i,j;for(i=0;i<this.colCount;i++){_214[i]=this.pageNodes[i][_213];}for(i=0,j=_213*this.rowsPerPage;(i<this.rowsPerPage)&&(j<this.rowCount);i++,j++){this.renderRow(j,_214);}},removePage:function(_215){for(var i=0,j=_215*this.rowsPerPage;i<this.rowsPerPage;i++,j++){this.removeRow(j);}},destroyPage:function(_216){for(var i=0;i<this.colCount;i++){var n=this.invalidatePageNode(_216,this.pageNodes[i]);if(n){html.destroy(n);}}},pacify:function(_217){},pacifying:false,pacifyTicks:200,setPacifying:function(_218){if(this.pacifying!=_218){this.pacifying=_218;this.pacify(this.pacifying);}},startPacify:function(){this.startPacifyTicks=new Date().getTime();},doPacify:function(){var _219=(new Date().getTime()-this.startPacifyTicks)>this.pacifyTicks;this.setPacifying(true);this.startPacify();return _219;},endPacify:function(){this.setPacifying(false);},resize:function(){if(this.scrollboxNode){this.windowHeight=this.scrollboxNode.clientHeight;}for(var i=0;i<this.colCount;i++){util.setStyleHeightPx(this.contentNodes[i],Math.max(1,this.height));}var _21a=(!this._invalidating);if(!_21a){var ah=this.grid.get("autoHeight");if(typeof ah=="number"&&ah<=Math.min(this.rowsPerPage,this.rowCount)){_21a=true;}}if(_21a){this.needPage(this.page,this.pageTop);}var _21b=(this.page<this.pageCount-1)?this.rowsPerPage:((this.rowCount%this.rowsPerPage)||this.rowsPerPage);var _21c=this.getPageHeight(this.page);this.averageRowHeight=(_21c>0&&_21b>0)?(_21c/_21b):0;},calcLastPageHeight:function(){if(!this.pageCount){return 0;}var _21d=this.pageCount-1;var _21e=((this.rowCount%this.rowsPerPage)||(this.rowsPerPage))*this.defaultRowHeight;this.pageHeights[_21d]=_21e;return _21e;},updateContentHeight:function(inDh){this.height+=inDh;this.resize();},updatePageHeight:function(_21f,_220,_221){if(this.pageExists(_21f)){var oh=this.getPageHeight(_21f);var h=(this.measurePage(_21f));if(h===undefined){h=oh;}this.pageHeights[_21f]=h;if(oh!=h){this.updateContentHeight(h-oh);var ah=this.grid.get("autoHeight");if((typeof ah=="number"&&ah>this.rowCount)||(ah===true&&!_220)){if(!_221){this.grid.sizeChange();}else{var ns=this.grid.viewsNode.style;ns.height=parseInt(ns.height)+h-oh+"px";this.repositionPages(_21f);}}else{this.repositionPages(_21f);}}return h;}return 0;},rowHeightChanged:function(_222,_223){this.updatePageHeight(Math.floor(_222/this.rowsPerPage),false,_223);},invalidateNodes:function(){while(this.stack.length){this.destroyPage(this.popPage());}},createPageNode:function(){var p=document.createElement("div");html.attr(p,"role","presentation");p.style.position="absolute";p.style[this.grid.isLeftToRight()?"left":"right"]="0";return p;},getPageHeight:function(_224){var ph=this.pageHeights[_224];return (ph!==undefined?ph:this.defaultPageHeight);},pushPage:function(_225){return this.stack.push(_225);},popPage:function(){return this.stack.shift();},findPage:function(_226){var i=0,h=0;for(var ph=0;i<this.pageCount;i++,h+=ph){ph=this.getPageHeight(i);if(h+ph>=_226){break;}}this.page=i;this.pageTop=h;},buildPage:function(_227,_228,_229){this.preparePage(_227,_228);this.positionPage(_227,_229);this.installPage(_227);this.renderPage(_227);this.pushPage(_227);},needPage:function(_22a,_22b){var h=this.getPageHeight(_22a),oh=h;if(!this.pageExists(_22a)){this.buildPage(_22a,(!this.grid._autoHeight&&this.keepPages&&(this.stack.length>=this.keepPages)),_22b);h=this.updatePageHeight(_22a,true);}else{this.positionPage(_22a,_22b);}return h;},onscroll:function(){this.scroll(this.scrollboxNode.scrollTop);},scroll:function(_22c){this.grid.scrollTop=_22c;if(this.colCount){this.startPacify();this.findPage(_22c);var h=this.height;var b=this.getScrollBottom(_22c);for(var p=this.page,y=this.pageTop;(p<this.pageCount)&&((b<0)||(y<b));p++){y+=this.needPage(p,y);}this.firstVisibleRow=this.getFirstVisibleRow(this.page,this.pageTop,_22c);this.lastVisibleRow=this.getLastVisibleRow(p-1,y,b);if(h!=this.height){this.repositionPages(p-1);}this.endPacify();}},getScrollBottom:function(_22d){return (this.windowHeight>=0?_22d+this.windowHeight:-1);},processNodeEvent:function(e,_22e){var t=e.target;while(t&&(t!=_22e)&&t.parentNode&&(t.parentNode.parentNode!=_22e)){t=t.parentNode;}if(!t||!t.parentNode||(t.parentNode.parentNode!=_22e)){return false;}var page=t.parentNode;e.topRowIndex=page.pageIndex*this.rowsPerPage;e.rowIndex=e.topRowIndex+_1f1(t);e.rowTarget=t;return true;},processEvent:function(e){return this.processNodeEvent(e,this.contentNode);},renderRow:function(_22f,_230){},removeRow:function(_231){},getDefaultPageNode:function(_232){return this.getDefaultNodes()[_232];},positionPageNode:function(_233,_234){},getPageNodePosition:function(_235){return _235.offsetTop;},invalidatePageNode:function(_236,_237){var p=_237[_236];if(p){delete _237[_236];this.removePage(_236,p);_1f3(p);p.innerHTML="";}return p;},getPageRow:function(_238){return _238*this.rowsPerPage;},getLastPageRow:function(_239){return Math.min(this.rowCount,this.getPageRow(_239+1))-1;},getFirstVisibleRow:function(_23a,_23b,_23c){if(!this.pageExists(_23a)){return 0;}var row=this.getPageRow(_23a);var _23d=this.getDefaultNodes();var rows=_1fb(_23d[_23a]);for(var i=0,l=rows.length;i<l&&_23b<_23c;i++,row++){_23b+=rows[i].offsetHeight;}return (row?row-1:row);},getLastVisibleRow:function(_23e,_23f,_240){if(!this.pageExists(_23e)){return 0;}var _241=this.getDefaultNodes();var row=this.getLastPageRow(_23e);var rows=_1fb(_241[_23e]);for(var i=rows.length-1;i>=0&&_23f>_240;i--,row--){_23f-=rows[i].offsetHeight;}return row+1;},findTopRow:function(_242){var _243=this.getDefaultNodes();var rows=_1fb(_243[this.page]);for(var i=0,l=rows.length,t=this.pageTop,h;i<l;i++){h=rows[i].offsetHeight;t+=h;if(t>=_242){this.offset=h-(t-_242);return i+this.page*this.rowsPerPage;}}return -1;},findScrollTop:function(_244){var _245=Math.floor(_244/this.rowsPerPage);var t=0;var i,l;for(i=0;i<_245;i++){t+=this.getPageHeight(i);}this.pageTop=t;this.page=_245;this.needPage(_245,this.pageTop);var _246=this.getDefaultNodes();var rows=_1fb(_246[_245]);var r=_244-this.rowsPerPage*_245;for(i=0,l=rows.length;i<l&&i<r;i++){t+=rows[i].offsetHeight;}return t;},dummy:0});});},"dojox/grid/_Events":function(){define("dojox/grid/_Events",["dojo/keys","dojo/dom-class","dojo/_base/declare","dojo/_base/event","dojo/_base/sniff"],function(keys,_247,_248,_249,has){return _248("dojox.grid._Events",null,{cellOverClass:"dojoxGridCellOver",onKeyEvent:function(e){this.dispatchKeyEvent(e);},onContentEvent:function(e){this.dispatchContentEvent(e);},onHeaderEvent:function(e){this.dispatchHeaderEvent(e);},onStyleRow:function(_24a){var i=_24a;i.customClasses+=(i.odd?" dojoxGridRowOdd":"")+(i.selected?" dojoxGridRowSelected":"")+(i.over?" dojoxGridRowOver":"");this.focus.styleRow(_24a);this.edit.styleRow(_24a);},onKeyDown:function(e){if(e.altKey||e.metaKey){return;}var _24b;switch(e.keyCode){case keys.ESCAPE:this.edit.cancel();break;case keys.ENTER:if(!this.edit.isEditing()){_24b=this.focus.getHeaderIndex();if(_24b>=0){this.setSortIndex(_24b);break;}else{this.selection.clickSelect(this.focus.rowIndex,dojo.isCopyKey(e),e.shiftKey);}_249.stop(e);}if(!e.shiftKey){var _24c=this.edit.isEditing();this.edit.apply();if(!_24c){this.edit.setEditCell(this.focus.cell,this.focus.rowIndex);}}if(!this.edit.isEditing()){var _24d=this.focus.focusView||this.views.views[0];_24d.content.decorateEvent(e);this.onRowClick(e);_249.stop(e);}break;case keys.SPACE:if(!this.edit.isEditing()){_24b=this.focus.getHeaderIndex();if(_24b>=0){this.setSortIndex(_24b);break;}else{this.selection.clickSelect(this.focus.rowIndex,dojo.isCopyKey(e),e.shiftKey);}_249.stop(e);}break;case keys.TAB:this.focus[e.shiftKey?"previousKey":"nextKey"](e);break;case keys.LEFT_ARROW:case keys.RIGHT_ARROW:if(!this.edit.isEditing()){var _24e=e.keyCode;_249.stop(e);_24b=this.focus.getHeaderIndex();if(_24b>=0&&(e.shiftKey&&e.ctrlKey)){this.focus.colSizeAdjust(e,_24b,(_24e==keys.LEFT_ARROW?-1:1)*5);}else{var _24f=(_24e==keys.LEFT_ARROW)?1:-1;if(this.isLeftToRight()){_24f*=-1;}this.focus.move(0,_24f);}}break;case keys.UP_ARROW:if(!this.edit.isEditing()&&this.focus.rowIndex!==0){_249.stop(e);this.focus.move(-1,0);}break;case keys.DOWN_ARROW:if(!this.edit.isEditing()&&this.focus.rowIndex+1!=this.rowCount){_249.stop(e);this.focus.move(1,0);}break;case keys.PAGE_UP:if(!this.edit.isEditing()&&this.focus.rowIndex!==0){_249.stop(e);if(this.focus.rowIndex!=this.scroller.firstVisibleRow+1){this.focus.move(this.scroller.firstVisibleRow-this.focus.rowIndex,0);}else{this.setScrollTop(this.scroller.findScrollTop(this.focus.rowIndex-1));this.focus.move(this.scroller.firstVisibleRow-this.scroller.lastVisibleRow+1,0);}}break;case keys.PAGE_DOWN:if(!this.edit.isEditing()&&this.focus.rowIndex+1!=this.rowCount){_249.stop(e);if(this.focus.rowIndex!=this.scroller.lastVisibleRow-1){this.focus.move(this.scroller.lastVisibleRow-this.focus.rowIndex-1,0);}else{this.setScrollTop(this.scroller.findScrollTop(this.focus.rowIndex+1));this.focus.move(this.scroller.lastVisibleRow-this.scroller.firstVisibleRow-1,0);}}break;default:break;}},onMouseOver:function(e){e.rowIndex==-1?this.onHeaderCellMouseOver(e):this.onCellMouseOver(e);},onMouseOut:function(e){e.rowIndex==-1?this.onHeaderCellMouseOut(e):this.onCellMouseOut(e);},onMouseDown:function(e){e.rowIndex==-1?this.onHeaderCellMouseDown(e):this.onCellMouseDown(e);},onMouseOverRow:function(e){if(!this.rows.isOver(e.rowIndex)){this.rows.setOverRow(e.rowIndex);e.rowIndex==-1?this.onHeaderMouseOver(e):this.onRowMouseOver(e);}},onMouseOutRow:function(e){if(this.rows.isOver(-1)){this.onHeaderMouseOut(e);}else{if(!this.rows.isOver(-2)){this.rows.setOverRow(-2);this.onRowMouseOut(e);}}},onMouseDownRow:function(e){if(e.rowIndex!=-1){this.onRowMouseDown(e);}},onCellMouseOver:function(e){if(e.cellNode){_247.add(e.cellNode,this.cellOverClass);}},onCellMouseOut:function(e){if(e.cellNode){_247.remove(e.cellNode,this.cellOverClass);}},onCellMouseDown:function(e){},onCellClick:function(e){this._click[0]=this._click[1];this._click[1]=e;if(!this.edit.isEditCell(e.rowIndex,e.cellIndex)){this.focus.setFocusCell(e.cell,e.rowIndex);}if(this._click.length>1&&this._click[0]==null){this._click.shift();}this.onRowClick(e);},onCellDblClick:function(e){var _250;if(this._click.length>1&&has("ie")){_250=this._click[1];}else{if(this._click.length>1&&this._click[0].rowIndex!=this._click[1].rowIndex){_250=this._click[0];}else{_250=e;}}this.focus.setFocusCell(_250.cell,_250.rowIndex);this.onRowClick(_250);this.edit.setEditCell(_250.cell,_250.rowIndex);this.onRowDblClick(e);},onCellContextMenu:function(e){this.onRowContextMenu(e);},onCellFocus:function(_251,_252){this.edit.cellFocus(_251,_252);},onRowClick:function(e){this.edit.rowClick(e);this.selection.clickSelectEvent(e);},onRowDblClick:function(e){},onRowMouseOver:function(e){},onRowMouseOut:function(e){},onRowMouseDown:function(e){},onRowContextMenu:function(e){_249.stop(e);},onHeaderMouseOver:function(e){},onHeaderMouseOut:function(e){},onHeaderCellMouseOver:function(e){if(e.cellNode){_247.add(e.cellNode,this.cellOverClass);}},onHeaderCellMouseOut:function(e){if(e.cellNode){_247.remove(e.cellNode,this.cellOverClass);}},onHeaderCellMouseDown:function(e){},onHeaderClick:function(e){},onHeaderCellClick:function(e){this.setSortIndex(e.cell.index);this.onHeaderClick(e);},onHeaderDblClick:function(e){},onHeaderCellDblClick:function(e){this.onHeaderDblClick(e);},onHeaderCellContextMenu:function(e){this.onHeaderContextMenu(e);},onHeaderContextMenu:function(e){if(!this.headerMenu){_249.stop(e);}},onStartEdit:function(_253,_254){},onApplyCellEdit:function(_255,_256,_257){},onCancelEdit:function(_258){},onApplyEdit:function(_259){},onCanSelect:function(_25a){return true;},onCanDeselect:function(_25b){return true;},onSelected:function(_25c){this.updateRowStyles(_25c);},onDeselected:function(_25d){this.updateRowStyles(_25d);},onSelectionChanged:function(){}});});},"dojo/dnd/autoscroll":function(){define(["../main","../window"],function(dojo){dojo.getObject("dnd",true,dojo);dojo.dnd.getViewport=dojo.window.getBox;dojo.dnd.V_TRIGGER_AUTOSCROLL=32;dojo.dnd.H_TRIGGER_AUTOSCROLL=32;dojo.dnd.V_AUTOSCROLL_VALUE=16;dojo.dnd.H_AUTOSCROLL_VALUE=16;dojo.dnd.autoScroll=function(e){var v=dojo.window.getBox(),dx=0,dy=0;if(e.clientX<dojo.dnd.H_TRIGGER_AUTOSCROLL){dx=-dojo.dnd.H_AUTOSCROLL_VALUE;}else{if(e.clientX>v.w-dojo.dnd.H_TRIGGER_AUTOSCROLL){dx=dojo.dnd.H_AUTOSCROLL_VALUE;}}if(e.clientY<dojo.dnd.V_TRIGGER_AUTOSCROLL){dy=-dojo.dnd.V_AUTOSCROLL_VALUE;}else{if(e.clientY>v.h-dojo.dnd.V_TRIGGER_AUTOSCROLL){dy=dojo.dnd.V_AUTOSCROLL_VALUE;}}window.scrollBy(dx,dy);};dojo.dnd._validNodes={"div":1,"p":1,"td":1};dojo.dnd._validOverflow={"auto":1,"scroll":1};dojo.dnd.autoScrollNodes=function(e){var b,t,w,h,rx,ry,dx=0,dy=0,_25e,_25f;for(var n=e.target;n;){if(n.nodeType==1&&(n.tagName.toLowerCase() in dojo.dnd._validNodes)){var s=dojo.getComputedStyle(n),_260=(s.overflow.toLowerCase() in dojo.dnd._validOverflow),_261=(s.overflowX.toLowerCase() in dojo.dnd._validOverflow),_262=(s.overflowY.toLowerCase() in dojo.dnd._validOverflow);if(_260||_261||_262){b=dojo._getContentBox(n,s);t=dojo.position(n,true);}if(_260||_261){w=Math.min(dojo.dnd.H_TRIGGER_AUTOSCROLL,b.w/2);rx=e.pageX-t.x;if(dojo.isWebKit||dojo.isOpera){rx+=dojo.body().scrollLeft;}dx=0;if(rx>0&&rx<b.w){if(rx<w){dx=-w;}else{if(rx>b.w-w){dx=w;}}_25e=n.scrollLeft;n.scrollLeft=n.scrollLeft+dx;}}if(_260||_262){h=Math.min(dojo.dnd.V_TRIGGER_AUTOSCROLL,b.h/2);ry=e.pageY-t.y;if(dojo.isWebKit||dojo.isOpera){ry+=dojo.body().scrollTop;}dy=0;if(ry>0&&ry<b.h){if(ry<h){dy=-h;}else{if(ry>b.h-h){dy=h;}}_25f=n.scrollTop;n.scrollTop=n.scrollTop+dy;}}if(dx||dy){return;}}try{n=n.parentNode;}catch(x){n=null;}}dojo.dnd.autoScroll(e);};return dojo.dnd;});},"dijit/registry":function(){define("dijit/registry",["dojo/_base/array","dojo/_base/sniff","dojo/_base/unload","dojo/_base/window","."],function(_263,has,_264,win,_265){var _266={},hash={};var _267={length:0,add:function(_268){if(hash[_268.id]){throw new Error("Tried to register widget with id=="+_268.id+" but that id is already registered");}hash[_268.id]=_268;this.length++;},remove:function(id){if(hash[id]){delete hash[id];this.length--;}},byId:function(id){return typeof id=="string"?hash[id]:id;},byNode:function(node){return hash[node.getAttribute("widgetId")];},toArray:function(){var ar=[];for(var id in hash){ar.push(hash[id]);}return ar;},getUniqueId:function(_269){var id;do{id=_269+"_"+(_269 in _266?++_266[_269]:_266[_269]=0);}while(hash[id]);return _265._scopeName=="dijit"?id:_265._scopeName+"_"+id;},findWidgets:function(root){var _26a=[];function _26b(root){for(var node=root.firstChild;node;node=node.nextSibling){if(node.nodeType==1){var _26c=node.getAttribute("widgetId");if(_26c){var _26d=hash[_26c];if(_26d){_26a.push(_26d);}}else{_26b(node);}}}};_26b(root);return _26a;},_destroyAll:function(){_265._curFocus=null;_265._prevFocus=null;_265._activeStack=[];_263.forEach(_267.findWidgets(win.body()),function(_26e){if(!_26e._destroyed){if(_26e.destroyRecursive){_26e.destroyRecursive();}else{if(_26e.destroy){_26e.destroy();}}}});},getEnclosingWidget:function(node){while(node){var id=node.getAttribute&&node.getAttribute("widgetId");if(id){return hash[id];}node=node.parentNode;}return null;},_hash:hash};if(has("ie")){_264.addOnWindowUnload(function(){_267._destroyAll();});}_265.registry=_267;return _267;});},"dijit/_base/manager":function(){define("dijit/_base/manager",["dojo/_base/array","dojo/_base/config","../registry",".."],function(_26f,_270,_271,_272){_26f.forEach(["byId","getUniqueId","findWidgets","_destroyAll","byNode","getEnclosingWidget"],function(name){_272[name]=_271[name];});_272.defaultDuration=_270["defaultDuration"]||200;return _272;});},"dojox/html/metrics":function(){define("dojox/html/metrics",["dojo/_base/kernel","dojo/_base/lang","dojo/_base/sniff","dojo/ready","dojo/_base/unload","dojo/_base/window","dojo/dom-geometry"],function(_273,lang,has,_274,_275,_276,_277){var dhm=lang.getObject("dojox.html.metrics",true);var _278=lang.getObject("dojox");dhm.getFontMeasurements=function(){var _279={"1em":0,"1ex":0,"100%":0,"12pt":0,"16px":0,"xx-small":0,"x-small":0,"small":0,"medium":0,"large":0,"x-large":0,"xx-large":0};if(has("ie")){_276.doc.documentElement.style.fontSize="100%";}var div=_276.doc.createElement("div");var ds=div.style;ds.position="absolute";ds.left="-100px";ds.top="0";ds.width="30px";ds.height="1000em";ds.borderWidth="0";ds.margin="0";ds.padding="0";ds.outline="0";ds.lineHeight="1";ds.overflow="hidden";_276.body().appendChild(div);for(var p in _279){ds.fontSize=p;_279[p]=Math.round(div.offsetHeight*12/16)*16/12/1000;}_276.body().removeChild(div);div=null;return _279;};var _27a=null;dhm.getCachedFontMeasurements=function(_27b){if(_27b||!_27a){_27a=dhm.getFontMeasurements();}return _27a;};var _27c=null,_27d={};dhm.getTextBox=function(text,_27e,_27f){var m,s;if(!_27c){m=_27c=_276.doc.createElement("div");var c=_276.doc.createElement("div");c.appendChild(m);s=c.style;s.overflow="scroll";s.position="absolute";s.left="0px";s.top="-10000px";s.width="1px";s.height="1px";s.visibility="hidden";s.borderWidth="0";s.margin="0";s.padding="0";s.outline="0";_276.body().appendChild(c);}else{m=_27c;}m.className="";s=m.style;s.borderWidth="0";s.margin="0";s.padding="0";s.outline="0";if(arguments.length>1&&_27e){for(var i in _27e){if(i in _27d){continue;}s[i]=_27e[i];}}if(arguments.length>2&&_27f){m.className=_27f;}m.innerHTML=text;var box=_277.position(m);box.w=m.parentNode.scrollWidth;return box;};var _280={w:16,h:16};dhm.getScrollbar=function(){return {w:_280.w,h:_280.h};};dhm._fontResizeNode=null;dhm.initOnFontResize=function(_281){var f=dhm._fontResizeNode=_276.doc.createElement("iframe");var fs=f.style;fs.position="absolute";fs.width="5em";fs.height="10em";fs.top="-10000px";if(has("ie")){f.onreadystatechange=function(){if(f.contentWindow.document.readyState=="complete"){f.onresize=f.contentWindow.parent[_278._scopeName].html.metrics._fontresize;}};}else{f.onload=function(){f.contentWindow.onresize=f.contentWindow.parent[_278._scopeName].html.metrics._fontresize;};}f.setAttribute("src","javascript:'<html><head><script>if(\"loadFirebugConsole\" in window){window.loadFirebugConsole();}</script></head><body></body></html>'");_276.body().appendChild(f);dhm.initOnFontResize=function(){};};dhm.onFontResize=function(){};dhm._fontresize=function(){dhm.onFontResize();};_275.addOnUnload(function(){var f=dhm._fontResizeNode;if(f){if(has("ie")&&f.onresize){f.onresize=null;}else{if(f.contentWindow&&f.contentWindow.onresize){f.contentWindow.onresize=null;}}dhm._fontResizeNode=null;}});_274(function(){try{var n=_276.doc.createElement("div");n.style.cssText="top:0;left:0;width:100px;height:100px;overflow:scroll;position:absolute;visibility:hidden;";_276.body().appendChild(n);_280.w=n.offsetWidth-n.clientWidth;_280.h=n.offsetHeight-n.clientHeight;_276.body().removeChild(n);delete n;}catch(e){}if("fontSizeWatch" in _273.config&&!!_273.config.fontSizeWatch){dhm.initOnFontResize();}});return dhm;});},"dojox/grid/_EditManager":function(){define("dojox/grid/_EditManager",["dojo/_base/lang","dojo/_base/array","dojo/_base/declare","dojo/_base/connect","dojo/_base/sniff","./util"],function(lang,_282,_283,_284,has,util){return _283("dojox.grid._EditManager",null,{constructor:function(_285){this.grid=_285;if(has("ie")){this.connections=[_284.connect(document.body,"onfocus",lang.hitch(this,"_boomerangFocus"))];}else{this.connections=[_284.connect(this.grid,"onBlur",this,"apply")];}},info:{},destroy:function(){_282.forEach(this.connections,_284.disconnect);},cellFocus:function(_286,_287){if(this.grid.singleClickEdit||this.isEditRow(_287)){this.setEditCell(_286,_287);}else{this.apply();}if(this.isEditing()||(_286&&_286.editable&&_286.alwaysEditing)){this._focusEditor(_286,_287);}},rowClick:function(e){if(this.isEditing()&&!this.isEditRow(e.rowIndex)){this.apply();}},styleRow:function(_288){if(_288.index==this.info.rowIndex){_288.customClasses+=" dojoxGridRowEditing";}},dispatchEvent:function(e){var c=e.cell,ed=(c&&c["editable"])?c:0;return ed&&ed.dispatchEvent(e.dispatch,e);},isEditing:function(){return this.info.rowIndex!==undefined;},isEditCell:function(_289,_28a){return (this.info.rowIndex===_289)&&(this.info.cell.index==_28a);},isEditRow:function(_28b){return this.info.rowIndex===_28b;},setEditCell:function(_28c,_28d){if(!this.isEditCell(_28d,_28c.index)&&this.grid.canEdit&&this.grid.canEdit(_28c,_28d)){this.start(_28c,_28d,this.isEditRow(_28d)||_28c.editable);}},_focusEditor:function(_28e,_28f){util.fire(_28e,"focus",[_28f]);},focusEditor:function(){if(this.isEditing()){this._focusEditor(this.info.cell,this.info.rowIndex);}},_boomerangWindow:500,_shouldCatchBoomerang:function(){return this._catchBoomerang>new Date().getTime();},_boomerangFocus:function(){if(this._shouldCatchBoomerang()){this.grid.focus.focusGrid();this.focusEditor();this._catchBoomerang=0;}},_doCatchBoomerang:function(){if(has("ie")){this._catchBoomerang=new Date().getTime()+this._boomerangWindow;}},start:function(_290,_291,_292){if(!this._isValidInput()){return;}this.grid.beginUpdate();this.editorApply();if(this.isEditing()&&!this.isEditRow(_291)){this.applyRowEdit();this.grid.updateRow(_291);}if(_292){this.info={cell:_290,rowIndex:_291};this.grid.doStartEdit(_290,_291);this.grid.updateRow(_291);}else{this.info={};}this.grid.endUpdate();this.grid.focus.focusGrid();this._focusEditor(_290,_291);this._doCatchBoomerang();},_editorDo:function(_293){var c=this.info.cell;if(c&&c.editable){c[_293](this.info.rowIndex);}},editorApply:function(){this._editorDo("apply");},editorCancel:function(){this._editorDo("cancel");},applyCellEdit:function(_294,_295,_296){if(this.grid.canEdit(_295,_296)){this.grid.doApplyCellEdit(_294,_296,_295.field);}},applyRowEdit:function(){this.grid.doApplyEdit(this.info.rowIndex,this.info.cell.field);},apply:function(){if(this.isEditing()&&this._isValidInput()){this.grid.beginUpdate();this.editorApply();this.applyRowEdit();this.info={};this.grid.endUpdate();this.grid.focus.focusGrid();this._doCatchBoomerang();}},cancel:function(){if(this.isEditing()){this.grid.beginUpdate();this.editorCancel();this.info={};this.grid.endUpdate();this.grid.focus.focusGrid();this._doCatchBoomerang();}},save:function(_297,_298){var c=this.info.cell;if(this.isEditRow(_297)&&(!_298||c.view==_298)&&c.editable){c.save(c,this.info.rowIndex);}},restore:function(_299,_29a){var c=this.info.cell;if(this.isEditRow(_29a)&&c.view==_299&&c.editable){c.restore(this.info.rowIndex);}},_isValidInput:function(){var w=(this.info.cell||{}).widget;if(!w||!w.isValid){return true;}w.focused=true;return w.isValid(true);}});});},"dijit/a11y":function(){define("dijit/a11y",["dojo/_base/array","dojo/_base/config","dojo/_base/declare","dojo/dom","dojo/dom-attr","dojo/dom-style","dojo/_base/sniff","./_base/manager","."],function(_29b,_29c,_29d,dom,_29e,_29f,has,_2a0,_2a1){var _2a2=(_2a1._isElementShown=function(elem){var s=_29f.get(elem);return (s.visibility!="hidden")&&(s.visibility!="collapsed")&&(s.display!="none")&&(_29e.get(elem,"type")!="hidden");});_2a1.hasDefaultTabStop=function(elem){switch(elem.nodeName.toLowerCase()){case "a":return _29e.has(elem,"href");case "area":case "button":case "input":case "object":case "select":case "textarea":return true;case "iframe":var body;try{var _2a3=elem.contentDocument;if("designMode" in _2a3&&_2a3.designMode=="on"){return true;}body=_2a3.body;}catch(e1){try{body=elem.contentWindow.document.body;}catch(e2){return false;}}return body&&(body.contentEditable=="true"||(body.firstChild&&body.firstChild.contentEditable=="true"));default:return elem.contentEditable=="true";}};var _2a4=(_2a1.isTabNavigable=function(elem){if(_29e.get(elem,"disabled")){return false;}else{if(_29e.has(elem,"tabIndex")){return _29e.get(elem,"tabIndex")>=0;}else{return _2a1.hasDefaultTabStop(elem);}}});_2a1._getTabNavigable=function(root){var _2a5,last,_2a6,_2a7,_2a8,_2a9,_2aa={};function _2ab(node){return node&&node.tagName.toLowerCase()=="input"&&node.type&&node.type.toLowerCase()=="radio"&&node.name&&node.name.toLowerCase();};var _2ac=function(_2ad){for(var _2ae=_2ad.firstChild;_2ae;_2ae=_2ae.nextSibling){if(_2ae.nodeType!=1||(has("ie")&&_2ae.scopeName!=="HTML")||!_2a2(_2ae)){continue;}if(_2a4(_2ae)){var _2af=_29e.get(_2ae,"tabIndex");if(!_29e.has(_2ae,"tabIndex")||_2af==0){if(!_2a5){_2a5=_2ae;}last=_2ae;}else{if(_2af>0){if(!_2a6||_2af<_2a7){_2a7=_2af;_2a6=_2ae;}if(!_2a8||_2af>=_2a9){_2a9=_2af;_2a8=_2ae;}}}var rn=_2ab(_2ae);if(_29e.get(_2ae,"checked")&&rn){_2aa[rn]=_2ae;}}if(_2ae.nodeName.toUpperCase()!="SELECT"){_2ac(_2ae);}}};if(_2a2(root)){_2ac(root);}function rs(node){return _2aa[_2ab(node)]||node;};return {first:rs(_2a5),last:rs(last),lowest:rs(_2a6),highest:rs(_2a8)};};_2a1.getFirstInTabbingOrder=function(root){var _2b0=_2a1._getTabNavigable(dom.byId(root));return _2b0.lowest?_2b0.lowest:_2b0.first;};_2a1.getLastInTabbingOrder=function(root){var _2b1=_2a1._getTabNavigable(dom.byId(root));return _2b1.last?_2b1.last:_2b1.highest;};return {hasDefaultTabStop:_2a1.hasDefaultTabStop,isTabNavigable:_2a1.isTabNavigable,_getTabNavigable:_2a1._getTabNavigable,getFirstInTabbingOrder:_2a1.getFirstInTabbingOrder,getLastInTabbingOrder:_2a1.getLastInTabbingOrder};});},"dijit/CheckedMenuItem":function(){require({cache:{"url:dijit/templates/CheckedMenuItem.html":"<tr class=\"dijitReset dijitMenuItem\" data-dojo-attach-point=\"focusNode\" role=\"menuitemcheckbox\" tabIndex=\"-1\"\n\t\tdata-dojo-attach-event=\"onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick\">\n\t<td class=\"dijitReset dijitMenuItemIconCell\" role=\"presentation\">\n\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitMenuItemIcon dijitCheckedMenuItemIcon\" data-dojo-attach-point=\"iconNode\"/>\n\t\t<span class=\"dijitCheckedMenuItemIconChar\">&#10003;</span>\n\t</td>\n\t<td class=\"dijitReset dijitMenuItemLabel\" colspan=\"2\" data-dojo-attach-point=\"containerNode,labelNode\"></td>\n\t<td class=\"dijitReset dijitMenuItemAccelKey\" style=\"display: none\" data-dojo-attach-point=\"accelKeyNode\"></td>\n\t<td class=\"dijitReset dijitMenuArrowCell\" role=\"presentation\">&#160;</td>\n</tr>\n"}});define("dijit/CheckedMenuItem",["dojo/_base/declare","dojo/dom-class","./MenuItem","dojo/text!./templates/CheckedMenuItem.html","./hccss"],function(_2b2,_2b3,_2b4,_2b5){return _2b2("dijit.CheckedMenuItem",_2b4,{templateString:_2b5,checked:false,_setCheckedAttr:function(_2b6){_2b3.toggle(this.domNode,"dijitCheckedMenuItemChecked",_2b6);this.domNode.setAttribute("aria-checked",_2b6);this._set("checked",_2b6);},iconClass:"",onChange:function(){},_onClick:function(e){if(!this.disabled){this.set("checked",!this.checked);this.onChange(this.checked);}this.inherited(arguments);}});});},"dojo/dnd/Container":function(){define(["../main","../Evented","./common","../parser"],function(dojo,_2b7){dojo.declare("dojo.dnd.Container",_2b7,{skipForm:false,constructor:function(node,_2b8){this.node=dojo.byId(node);if(!_2b8){_2b8={};}this.creator=_2b8.creator||null;this.skipForm=_2b8.skipForm;this.parent=_2b8.dropParent&&dojo.byId(_2b8.dropParent);this.map={};this.current=null;this.containerState="";dojo.addClass(this.node,"dojoDndContainer");if(!(_2b8&&_2b8._skipStartup)){this.startup();}this.events=[dojo.connect(this.node,"onmouseover",this,"onMouseOver"),dojo.connect(this.node,"onmouseout",this,"onMouseOut"),dojo.connect(this.node,"ondragstart",this,"onSelectStart"),dojo.connect(this.node,"onselectstart",this,"onSelectStart")];},creator:function(){},getItem:function(key){return this.map[key];},setItem:function(key,data){this.map[key]=data;},delItem:function(key){delete this.map[key];},forInItems:function(f,o){o=o||dojo.global;var m=this.map,e=dojo.dnd._empty;for(var i in m){if(i in e){continue;}f.call(o,m[i],i,this);}return o;},clearItems:function(){this.map={};},getAllNodes:function(){return dojo.query("> .dojoDndItem",this.parent);},sync:function(){var map={};this.getAllNodes().forEach(function(node){if(node.id){var item=this.getItem(node.id);if(item){map[node.id]=item;return;}}else{node.id=dojo.dnd.getUniqueId();}var type=node.getAttribute("dndType"),data=node.getAttribute("dndData");map[node.id]={data:data||node.innerHTML,type:type?type.split(/\s*,\s*/):["text"]};},this);this.map=map;return this;},insertNodes:function(data,_2b9,_2ba){if(!this.parent.firstChild){_2ba=null;}else{if(_2b9){if(!_2ba){_2ba=this.parent.firstChild;}}else{if(_2ba){_2ba=_2ba.nextSibling;}}}if(_2ba){for(var i=0;i<data.length;++i){var t=this._normalizedCreator(data[i]);this.setItem(t.node.id,{data:t.data,type:t.type});this.parent.insertBefore(t.node,_2ba);}}else{for(var i=0;i<data.length;++i){var t=this._normalizedCreator(data[i]);this.setItem(t.node.id,{data:t.data,type:t.type});this.parent.appendChild(t.node);}}return this;},destroy:function(){dojo.forEach(this.events,dojo.disconnect);this.clearItems();this.node=this.parent=this.current=null;},markupFactory:function(_2bb,node,ctor){_2bb._skipStartup=true;return new ctor(node,_2bb);},startup:function(){if(!this.parent){this.parent=this.node;if(this.parent.tagName.toLowerCase()=="table"){var c=this.parent.getElementsByTagName("tbody");if(c&&c.length){this.parent=c[0];}}}this.defaultCreator=dojo.dnd._defaultCreator(this.parent);this.sync();},onMouseOver:function(e){var n=e.relatedTarget;while(n){if(n==this.node){break;}try{n=n.parentNode;}catch(x){n=null;}}if(!n){this._changeState("Container","Over");this.onOverEvent();}n=this._getChildByEvent(e);if(this.current==n){return;}if(this.current){this._removeItemClass(this.current,"Over");}if(n){this._addItemClass(n,"Over");}this.current=n;},onMouseOut:function(e){for(var n=e.relatedTarget;n;){if(n==this.node){return;}try{n=n.parentNode;}catch(x){n=null;}}if(this.current){this._removeItemClass(this.current,"Over");this.current=null;}this._changeState("Container","");this.onOutEvent();},onSelectStart:function(e){if(!this.skipForm||!dojo.dnd.isFormElement(e)){dojo.stopEvent(e);}},onOverEvent:function(){},onOutEvent:function(){},_changeState:function(type,_2bc){var _2bd="dojoDnd"+type;var _2be=type.toLowerCase()+"State";dojo.replaceClass(this.node,_2bd+_2bc,_2bd+this[_2be]);this[_2be]=_2bc;},_addItemClass:function(node,type){dojo.addClass(node,"dojoDndItem"+type);},_removeItemClass:function(node,type){dojo.removeClass(node,"dojoDndItem"+type);},_getChildByEvent:function(e){var node=e.target;if(node){for(var _2bf=node.parentNode;_2bf;node=_2bf,_2bf=node.parentNode){if(_2bf==this.parent&&dojo.hasClass(node,"dojoDndItem")){return node;}}}return null;},_normalizedCreator:function(item,hint){var t=(this.creator||this.defaultCreator).call(this,item,hint);if(!dojo.isArray(t.type)){t.type=["text"];}if(!t.node.id){t.node.id=dojo.dnd.getUniqueId();}dojo.addClass(t.node,"dojoDndItem");return t;}});dojo.dnd._createNode=function(tag){if(!tag){return dojo.dnd._createSpan;}return function(text){return dojo.create(tag,{innerHTML:text});};};dojo.dnd._createTrTd=function(text){var tr=dojo.create("tr");dojo.create("td",{innerHTML:text},tr);return tr;};dojo.dnd._createSpan=function(text){return dojo.create("span",{innerHTML:text});};dojo.dnd._defaultCreatorNodes={ul:"li",ol:"li",div:"div",p:"div"};dojo.dnd._defaultCreator=function(node){var tag=node.tagName.toLowerCase();var c=tag=="tbody"||tag=="thead"?dojo.dnd._createTrTd:dojo.dnd._createNode(dojo.dnd._defaultCreatorNodes[tag]);return function(item,hint){var _2c0=item&&dojo.isObject(item),data,type,n;if(_2c0&&item.tagName&&item.nodeType&&item.getAttribute){data=item.getAttribute("dndData")||item.innerHTML;type=item.getAttribute("dndType");type=type?type.split(/\s*,\s*/):["text"];n=item;}else{data=(_2c0&&item.data)?item.data:item;type=(_2c0&&item.type)?item.type:["text"];n=(hint=="avatar"?dojo.dnd._createSpan:c)(String(data));}if(!n.id){n.id=dojo.dnd.getUniqueId();}return {node:n,data:data,type:type};};};return dojo.dnd.Container;});},"dojo/dnd/common":function(){define(["../main"],function(dojo){dojo.getObject("dnd",true,dojo);dojo.dnd.getCopyKeyState=dojo.isCopyKey;dojo.dnd._uniqueId=0;dojo.dnd.getUniqueId=function(){var id;do{id=dojo._scopeName+"Unique"+(++dojo.dnd._uniqueId);}while(dojo.byId(id));return id;};dojo.dnd._empty={};dojo.dnd.isFormElement=function(e){var t=e.target;if(t.nodeType==3){t=t.parentNode;}return " button textarea input select option ".indexOf(" "+t.tagName.toLowerCase()+" ")>=0;};return dojo.dnd;});},"dojox/grid/_ViewManager":function(){define("dojox/grid/_ViewManager",["dojo/_base/declare","dojo/_base/sniff","dojo/dom-class"],function(_2c1,has,_2c2){return _2c1("dojox.grid._ViewManager",null,{constructor:function(_2c3){this.grid=_2c3;},defaultWidth:200,views:[],resize:function(){this.onEach("resize");},render:function(){this.onEach("render");},addView:function(_2c4){_2c4.idx=this.views.length;this.views.push(_2c4);},destroyViews:function(){for(var i=0,v;v=this.views[i];i++){v.destroy();}this.views=[];},getContentNodes:function(){var _2c5=[];for(var i=0,v;v=this.views[i];i++){_2c5.push(v.contentNode);}return _2c5;},forEach:function(_2c6){for(var i=0,v;v=this.views[i];i++){_2c6(v,i);}},onEach:function(_2c7,_2c8){_2c8=_2c8||[];for(var i=0,v;v=this.views[i];i++){if(_2c7 in v){v[_2c7].apply(v,_2c8);}}},normalizeHeaderNodeHeight:function(){var _2c9=[];for(var i=0,v;(v=this.views[i]);i++){if(v.headerContentNode.firstChild){_2c9.push(v.headerContentNode);}}this.normalizeRowNodeHeights(_2c9);},normalizeRowNodeHeights:function(_2ca){var h=0;var _2cb=[];if(this.grid.rowHeight){h=this.grid.rowHeight;}else{if(_2ca.length<=1){return;}for(var i=0,n;(n=_2ca[i]);i++){if(!_2c2.contains(n,"dojoxGridNonNormalizedCell")){_2cb[i]=n.firstChild.offsetHeight;h=Math.max(h,_2cb[i]);}}h=(h>=0?h:0);if((has("mozilla")||has("ie")>8)&&h){h++;}}for(i=0;(n=_2ca[i]);i++){if(_2cb[i]!=h){n.firstChild.style.height=h+"px";}}},resetHeaderNodeHeight:function(){for(var i=0,v,n;(v=this.views[i]);i++){n=v.headerContentNode.firstChild;if(n){n.style.height="";}}},renormalizeRow:function(_2cc){var _2cd=[];for(var i=0,v,n;(v=this.views[i])&&(n=v.getRowNode(_2cc));i++){n.firstChild.style.height="";_2cd.push(n);}this.normalizeRowNodeHeights(_2cd);},getViewWidth:function(_2ce){return this.views[_2ce].getWidth()||this.defaultWidth;},measureHeader:function(){this.resetHeaderNodeHeight();this.forEach(function(_2cf){_2cf.headerContentNode.style.height="";});var h=0;this.forEach(function(_2d0){h=Math.max(_2d0.headerNode.offsetHeight,h);});return h;},measureContent:function(){var h=0;this.forEach(function(_2d1){h=Math.max(_2d1.domNode.offsetHeight,h);});return h;},findClient:function(_2d2){var c=this.grid.elasticView||-1;if(c<0){for(var i=1,v;(v=this.views[i]);i++){if(v.viewWidth){for(i=1;(v=this.views[i]);i++){if(!v.viewWidth){c=i;break;}}break;}}}if(c<0){c=Math.floor(this.views.length/2);}return c;},arrange:function(l,w){var i,v,vw,len=this.views.length,self=this;var c=(w<=0?len:this.findClient());var _2d3=function(v,l){var ds=v.domNode.style;var hs=v.headerNode.style;if(!self.grid.isLeftToRight()){ds.right=l+"px";if(has("ff")<4||has("webkit")){hs.right=l+v.getScrollbarWidth()+"px";hs.width=parseInt(hs.width,10)-v.getScrollbarWidth()+"px";}else{hs.right=l+"px";}}else{ds.left=l+"px";hs.left=l+"px";}ds.top=0+"px";hs.top=0;};for(i=0;(v=this.views[i])&&(i<c);i++){vw=this.getViewWidth(i);v.setSize(vw,0);_2d3(v,l);if(v.headerContentNode&&v.headerContentNode.firstChild){vw=v.getColumnsWidth()+v.getScrollbarWidth();}else{vw=v.domNode.offsetWidth;}l+=vw;}i++;var r=w;for(var j=len-1;(v=this.views[j])&&(i<=j);j--){vw=this.getViewWidth(j);v.setSize(vw,0);vw=v.domNode.offsetWidth;r-=vw;_2d3(v,r);}if(c<len){v=this.views[c];vw=Math.max(1,r-l);v.setSize(vw+"px",0);_2d3(v,l);}return l;},renderRow:function(_2d4,_2d5,_2d6){var _2d7=[];for(var i=0,v,n,_2d8;(v=this.views[i])&&(n=_2d5[i]);i++){_2d8=v.renderRow(_2d4);n.appendChild(_2d8);_2d7.push(_2d8);}if(!_2d6){this.normalizeRowNodeHeights(_2d7);}},rowRemoved:function(_2d9){this.onEach("rowRemoved",[_2d9]);},updateRow:function(_2da,_2db){for(var i=0,v;v=this.views[i];i++){v.updateRow(_2da);}if(!_2db){this.renormalizeRow(_2da);}},updateRowStyles:function(_2dc){this.onEach("updateRowStyles",[_2dc]);},setScrollTop:function(_2dd){var top=_2dd;for(var i=0,v;v=this.views[i];i++){top=v.setScrollTop(_2dd);if(has("ie")&&v.headerNode&&v.scrollboxNode){v.headerNode.scrollLeft=v.scrollboxNode.scrollLeft;}}return top;},getFirstScrollingView:function(){for(var i=0,v;(v=this.views[i]);i++){if(v.hasHScrollbar()||v.hasVScrollbar()){return v;}}return null;}});});},"dojox/grid/cells":function(){define("dojox/grid/cells",["../main","./cells/_base"],function(_2de){return _2de.grid.cells;});},"dijit/_Widget":function(){define("dijit/_Widget",["dojo/aspect","dojo/_base/config","dojo/_base/connect","dojo/_base/declare","dojo/_base/kernel","dojo/_base/lang","dojo/query","dojo/ready","./registry","./_WidgetBase","./_OnDijitClickMixin","./_FocusMixin","dojo/uacss","./hccss"],function(_2df,_2e0,_2e1,_2e2,_2e3,lang,_2e4,_2e5,_2e6,_2e7,_2e8,_2e9){function _2ea(){};function _2eb(_2ec){return function(obj,_2ed,_2ee,_2ef){if(obj&&typeof _2ed=="string"&&obj[_2ed]==_2ea){return obj.on(_2ed.substring(2).toLowerCase(),lang.hitch(_2ee,_2ef));}return _2ec.apply(_2e1,arguments);};};_2df.around(_2e1,"connect",_2eb);if(_2e3.connect){_2df.around(_2e3,"connect",_2eb);}var _2f0=_2e2("dijit._Widget",[_2e7,_2e8,_2e9],{onClick:_2ea,onDblClick:_2ea,onKeyDown:_2ea,onKeyPress:_2ea,onKeyUp:_2ea,onMouseDown:_2ea,onMouseMove:_2ea,onMouseOut:_2ea,onMouseOver:_2ea,onMouseLeave:_2ea,onMouseEnter:_2ea,onMouseUp:_2ea,constructor:function(_2f1){this._toConnect={};for(var name in _2f1){if(this[name]===_2ea){this._toConnect[name.replace(/^on/,"").toLowerCase()]=_2f1[name];delete _2f1[name];}}},postCreate:function(){this.inherited(arguments);for(var name in this._toConnect){this.on(name,this._toConnect[name]);}delete this._toConnect;},on:function(type,func){if(this[this._onMap(type)]===_2ea){return _2e1.connect(this.domNode,type.toLowerCase(),this,func);}return this.inherited(arguments);},_setFocusedAttr:function(val){this._focused=val;this._set("focused",val);},setAttribute:function(attr,_2f2){_2e3.deprecated(this.declaredClass+"::setAttribute(attr, value) is deprecated. Use set() instead.","","2.0");this.set(attr,_2f2);},attr:function(name,_2f3){if(_2e0.isDebug){var _2f4=arguments.callee._ach||(arguments.callee._ach={}),_2f5=(arguments.callee.caller||"unknown caller").toString();if(!_2f4[_2f5]){_2e3.deprecated(this.declaredClass+"::attr() is deprecated. Use get() or set() instead, called from "+_2f5,"","2.0");_2f4[_2f5]=true;}}var args=arguments.length;if(args>=2||typeof name==="object"){return this.set.apply(this,arguments);}else{return this.get(name);}},getDescendants:function(){_2e3.deprecated(this.declaredClass+"::getDescendants() is deprecated. Use getChildren() instead.","","2.0");return this.containerNode?_2e4("[widgetId]",this.containerNode).map(_2e6.byNode):[];},_onShow:function(){this.onShow();},onShow:function(){},onHide:function(){},onClose:function(){return true;}});if(!_2e3.isAsync){_2e5(0,function(){var _2f6=["dijit/_base"];require(_2f6);});}return _2f0;});},"dijit/_FocusMixin":function(){define("dijit/_FocusMixin",["./focus","./_WidgetBase","dojo/_base/declare","dojo/_base/lang"],function(_2f7,_2f8,_2f9,lang){lang.extend(_2f8,{focused:false,onFocus:function(){},onBlur:function(){},_onFocus:function(){this.onFocus();},_onBlur:function(){this.onBlur();}});return _2f9("dijit._FocusMixin",null,{_focusManager:_2f7});});},"dijit/_OnDijitClickMixin":function(){define("dijit/_OnDijitClickMixin",["dojo/on","dojo/_base/array","dojo/keys","dojo/_base/declare","dojo/_base/sniff","dojo/_base/unload","dojo/_base/window"],function(on,_2fa,keys,_2fb,has,_2fc,win){var _2fd=null;if(has("ie")){(function(){var _2fe=function(evt){_2fd=evt.srcElement;};win.doc.attachEvent("onkeydown",_2fe);_2fc.addOnWindowUnload(function(){win.doc.detachEvent("onkeydown",_2fe);});})();}else{win.doc.addEventListener("keydown",function(evt){_2fd=evt.target;},true);}var _2ff=function(node,_300){if(/input|button/i.test(node.nodeName)){return on(node,"click",_300);}else{function _301(e){return (e.keyCode==keys.ENTER||e.keyCode==keys.SPACE)&&!e.ctrlKey&&!e.shiftKey&&!e.altKey&&!e.metaKey;};var _302=[on(node,"keypress",function(e){if(_301(e)){_2fd=e.target;e.preventDefault();}}),on(node,"keyup",function(e){if(_301(e)&&e.target==_2fd){_2fd=null;_300.call(this,e);}}),on(node,"click",function(e){_300.call(this,e);})];return {remove:function(){_2fa.forEach(_302,function(h){h.remove();});}};}};return _2fb("dijit._OnDijitClickMixin",null,{connect:function(obj,_303,_304){return this.inherited(arguments,[obj,_303=="ondijitclick"?_2ff:_303,_304]);}});});},"dojo/cache":function(){define(["./_base/kernel","./text"],function(dojo,text){return dojo.cache;});},"dijit/focus":function(){define("dijit/focus",["dojo/aspect","dojo/_base/declare","dojo/dom","dojo/dom-attr","dojo/dom-construct","dojo/Evented","dojo/_base/lang","dojo/on","dojo/ready","dojo/_base/sniff","dojo/Stateful","dojo/_base/unload","dojo/_base/window","dojo/window","./a11y","./registry","."],function(_305,_306,dom,_307,_308,_309,lang,on,_30a,has,_30b,_30c,win,_30d,a11y,_30e,_30f){var _310=_306([_30b,_309],{curNode:null,activeStack:[],constructor:function(){var _311=lang.hitch(this,function(node){if(dom.isDescendant(this.curNode,node)){this.set("curNode",null);}if(dom.isDescendant(this.prevNode,node)){this.set("prevNode",null);}});_305.before(_308,"empty",_311);_305.before(_308,"destroy",_311);},registerIframe:function(_312){return this.registerWin(_312.contentWindow,_312);},registerWin:function(_313,_314){var _315=this;var _316=function(evt){_315._justMouseDowned=true;setTimeout(function(){_315._justMouseDowned=false;},0);if(has("ie")&&evt&&evt.srcElement&&evt.srcElement.parentNode==null){return;}_315._onTouchNode(_314||evt.target||evt.srcElement,"mouse");};var doc=has("ie")?_313.document.documentElement:_313.document;if(doc){if(has("ie")){_313.document.body.attachEvent("onmousedown",_316);var _317=function(evt){var tag=evt.srcElement.tagName.toLowerCase();if(tag=="#document"||tag=="body"){return;}if(a11y.isTabNavigable(evt.srcElement)){_315._onFocusNode(_314||evt.srcElement);}else{_315._onTouchNode(_314||evt.srcElement);}};doc.attachEvent("onactivate",_317);var _318=function(evt){_315._onBlurNode(_314||evt.srcElement);};doc.attachEvent("ondeactivate",_318);return {remove:function(){_313.document.detachEvent("onmousedown",_316);doc.detachEvent("onactivate",_317);doc.detachEvent("ondeactivate",_318);doc=null;}};}else{doc.body.addEventListener("mousedown",_316,true);doc.body.addEventListener("touchstart",_316,true);var _319=function(evt){_315._onFocusNode(_314||evt.target);};doc.addEventListener("focus",_319,true);var _31a=function(evt){_315._onBlurNode(_314||evt.target);};doc.addEventListener("blur",_31a,true);return {remove:function(){doc.body.removeEventListener("mousedown",_316,true);doc.body.removeEventListener("touchstart",_316,true);doc.removeEventListener("focus",_319,true);doc.removeEventListener("blur",_31a,true);doc=null;}};}}},_onBlurNode:function(){this.set("prevNode",this.curNode);this.set("curNode",null);if(this._justMouseDowned){return;}if(this._clearActiveWidgetsTimer){clearTimeout(this._clearActiveWidgetsTimer);}this._clearActiveWidgetsTimer=setTimeout(lang.hitch(this,function(){delete this._clearActiveWidgetsTimer;this._setStack([]);this.prevNode=null;}),100);},_onTouchNode:function(node,by){if(this._clearActiveWidgetsTimer){clearTimeout(this._clearActiveWidgetsTimer);delete this._clearActiveWidgetsTimer;}var _31b=[];try{while(node){var _31c=_307.get(node,"dijitPopupParent");if(_31c){node=_30e.byId(_31c).domNode;}else{if(node.tagName&&node.tagName.toLowerCase()=="body"){if(node===win.body()){break;}node=_30d.get(node.ownerDocument).frameElement;}else{var id=node.getAttribute&&node.getAttribute("widgetId"),_31d=id&&_30e.byId(id);if(_31d&&!(by=="mouse"&&_31d.get("disabled"))){_31b.unshift(id);}node=node.parentNode;}}}}catch(e){}this._setStack(_31b,by);},_onFocusNode:function(node){if(!node){return;}if(node.nodeType==9){return;}this._onTouchNode(node);if(node==this.curNode){return;}this.set("curNode",node);},_setStack:function(_31e,by){var _31f=this.activeStack;this.set("activeStack",_31e);for(var _320=0;_320<Math.min(_31f.length,_31e.length);_320++){if(_31f[_320]!=_31e[_320]){break;}}var _321;for(var i=_31f.length-1;i>=_320;i--){_321=_30e.byId(_31f[i]);if(_321){_321._hasBeenBlurred=true;_321.set("focused",false);if(_321._focusManager==this){_321._onBlur(by);}this.emit("widget-blur",_321,by);}}for(i=_320;i<_31e.length;i++){_321=_30e.byId(_31e[i]);if(_321){_321.set("focused",true);if(_321._focusManager==this){_321._onFocus(by);}this.emit("widget-focus",_321,by);}}},focus:function(node){if(node){try{node.focus();}catch(e){}}}});var _322=new _310();_30a(function(){var _323=_322.registerWin(win.doc.parentWindow||win.doc.defaultView);if(has("ie")){_30c.addOnWindowUnload(function(){_323.remove();_323=null;});}});_30f.focus=function(node){_322.focus(node);};for(var attr in _322){if(!/^_/.test(attr)){_30f.focus[attr]=typeof _322[attr]=="function"?lang.hitch(_322,attr):_322[attr];}}_322.watch(function(attr,_324,_325){_30f.focus[attr]=_325;});return _322;});},"dojox/grid/util":function(){define("dojox/grid/util",["../main","dojo/_base/lang","dojo/dom"],function(_326,lang,dom){var dgu=lang.getObject("grid.util",true,_326);dgu.na="...";dgu.rowIndexTag="gridRowIndex";dgu.gridViewTag="gridView";dgu.fire=function(ob,ev,args){var fn=ob&&ev&&ob[ev];return fn&&(args?fn.apply(ob,args):ob[ev]());};dgu.setStyleHeightPx=function(_327,_328){if(_328>=0){var s=_327.style;var v=_328+"px";if(_327&&s["height"]!=v){s["height"]=v;}}};dgu.mouseEvents=["mouseover","mouseout","mousedown","mouseup","click","dblclick","contextmenu"];dgu.keyEvents=["keyup","keydown","keypress"];dgu.funnelEvents=function(_329,_32a,_32b,_32c){var evts=(_32c?_32c:dgu.mouseEvents.concat(dgu.keyEvents));for(var i=0,l=evts.length;i<l;i++){_32a.connect(_329,"on"+evts[i],_32b);}};dgu.removeNode=function(_32d){_32d=dom.byId(_32d);_32d&&_32d.parentNode&&_32d.parentNode.removeChild(_32d);return _32d;};dgu.arrayCompare=function(inA,inB){for(var i=0,l=inA.length;i<l;i++){if(inA[i]!=inB[i]){return false;}}return (inA.length==inB.length);};dgu.arrayInsert=function(_32e,_32f,_330){if(_32e.length<=_32f){_32e[_32f]=_330;}else{_32e.splice(_32f,0,_330);}};dgu.arrayRemove=function(_331,_332){_331.splice(_332,1);};dgu.arraySwap=function(_333,inI,inJ){var _334=_333[inI];_333[inI]=_333[inJ];_333[inJ]=_334;};return _326.grid.util;});},"url:dijit/templates/MenuItem.html":"<tr class=\"dijitReset dijitMenuItem\" data-dojo-attach-point=\"focusNode\" role=\"menuitem\" tabIndex=\"-1\"\n\t\tdata-dojo-attach-event=\"onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick\">\n\t<td class=\"dijitReset dijitMenuItemIconCell\" role=\"presentation\">\n\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitIcon dijitMenuItemIcon\" data-dojo-attach-point=\"iconNode\"/>\n\t</td>\n\t<td class=\"dijitReset dijitMenuItemLabel\" colspan=\"2\" data-dojo-attach-point=\"containerNode\"></td>\n\t<td class=\"dijitReset dijitMenuItemAccelKey\" style=\"display: none\" data-dojo-attach-point=\"accelKeyNode\"></td>\n\t<td class=\"dijitReset dijitMenuArrowCell\" role=\"presentation\">\n\t\t<div data-dojo-attach-point=\"arrowWrapper\" style=\"visibility: hidden\">\n\t\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitMenuExpand\"/>\n\t\t\t<span class=\"dijitMenuExpandA11y\">+</span>\n\t\t</div>\n\t</td>\n</tr>\n","dijit/main":function(){define("dijit/main",["dojo/_base/kernel"],function(dojo){return dojo.dijit;});},"dojo/date/stamp":function(){define(["../_base/kernel","../_base/lang","../_base/array"],function(dojo,lang,_335){lang.getObject("date.stamp",true,dojo);dojo.date.stamp.fromISOString=function(_336,_337){if(!dojo.date.stamp._isoRegExp){dojo.date.stamp._isoRegExp=/^(?:(\d{4})(?:-(\d{2})(?:-(\d{2}))?)?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(.\d+)?)?((?:[+-](\d{2}):(\d{2}))|Z)?)?$/;}var _338=dojo.date.stamp._isoRegExp.exec(_336),_339=null;if(_338){_338.shift();if(_338[1]){_338[1]--;}if(_338[6]){_338[6]*=1000;}if(_337){_337=new Date(_337);_335.forEach(_335.map(["FullYear","Month","Date","Hours","Minutes","Seconds","Milliseconds"],function(prop){return _337["get"+prop]();}),function(_33a,_33b){_338[_33b]=_338[_33b]||_33a;});}_339=new Date(_338[0]||1970,_338[1]||0,_338[2]||1,_338[3]||0,_338[4]||0,_338[5]||0,_338[6]||0);if(_338[0]<100){_339.setFullYear(_338[0]||1970);}var _33c=0,_33d=_338[7]&&_338[7].charAt(0);if(_33d!="Z"){_33c=((_338[8]||0)*60)+(Number(_338[9])||0);if(_33d!="-"){_33c*=-1;}}if(_33d){_33c-=_339.getTimezoneOffset();}if(_33c){_339.setTime(_339.getTime()+_33c*60000);}}return _339;};dojo.date.stamp.toISOString=function(_33e,_33f){var _340=function(n){return (n<10)?"0"+n:n;};_33f=_33f||{};var _341=[],_342=_33f.zulu?"getUTC":"get",date="";if(_33f.selector!="time"){var year=_33e[_342+"FullYear"]();date=["0000".substr((year+"").length)+year,_340(_33e[_342+"Month"]()+1),_340(_33e[_342+"Date"]())].join("-");}_341.push(date);if(_33f.selector!="date"){var time=[_340(_33e[_342+"Hours"]()),_340(_33e[_342+"Minutes"]()),_340(_33e[_342+"Seconds"]())].join(":");var _343=_33e[_342+"Milliseconds"]();if(_33f.milliseconds){time+="."+(_343<100?"0":"")+_340(_343);}if(_33f.zulu){time+="Z";}else{if(_33f.selector!="time"){var _344=_33e.getTimezoneOffset();var _345=Math.abs(_344);time+=(_344>0?"-":"+")+_340(Math.floor(_345/60))+":"+_340(_345%60);}}_341.push(time);}return _341.join("T");};return dojo.date.stamp;});},"url:dojox/grid/resources/View.html":"<div class=\"dojoxGridView\" role=\"presentation\">\n\t<div class=\"dojoxGridHeader\" dojoAttachPoint=\"headerNode\" role=\"presentation\">\n\t\t<div dojoAttachPoint=\"headerNodeContainer\" style=\"width:9000em\" role=\"presentation\">\n\t\t\t<div dojoAttachPoint=\"headerContentNode\" role=\"row\"></div>\n\t\t</div>\n\t</div>\n\t<input type=\"checkbox\" class=\"dojoxGridHiddenFocus\" dojoAttachPoint=\"hiddenFocusNode\" role=\"presentation\" />\n\t<input type=\"checkbox\" class=\"dojoxGridHiddenFocus\" role=\"presentation\" />\n\t<div class=\"dojoxGridScrollbox\" dojoAttachPoint=\"scrollboxNode\" role=\"presentation\">\n\t\t<div class=\"dojoxGridContent\" dojoAttachPoint=\"contentNode\" hidefocus=\"hidefocus\" role=\"presentation\"></div>\n\t</div>\n</div>\n","dojox/grid/_FocusManager":function(){define("dojox/grid/_FocusManager",["dojo/_base/array","dojo/_base/lang","dojo/_base/declare","dojo/_base/connect","dojo/_base/event","dojo/_base/sniff","dojo/query","./util","dojo/_base/html"],function(_346,lang,_347,_348,_349,has,_34a,util,html){return _347("dojox.grid._FocusManager",null,{constructor:function(_34b){this.grid=_34b;this.cell=null;this.rowIndex=-1;this._connects=[];this._headerConnects=[];this.headerMenu=this.grid.headerMenu;this._connects.push(_348.connect(this.grid.domNode,"onfocus",this,"doFocus"));this._connects.push(_348.connect(this.grid.domNode,"onblur",this,"doBlur"));this._connects.push(_348.connect(this.grid.domNode,"mousedown",this,"_mouseDown"));this._connects.push(_348.connect(this.grid.domNode,"mouseup",this,"_mouseUp"));this._connects.push(_348.connect(this.grid.domNode,"oncontextmenu",this,"doContextMenu"));this._connects.push(_348.connect(this.grid.lastFocusNode,"onfocus",this,"doLastNodeFocus"));this._connects.push(_348.connect(this.grid.lastFocusNode,"onblur",this,"doLastNodeBlur"));this._connects.push(_348.connect(this.grid,"_onFetchComplete",this,"_delayedCellFocus"));this._connects.push(_348.connect(this.grid,"postrender",this,"_delayedHeaderFocus"));},destroy:function(){_346.forEach(this._connects,_348.disconnect);_346.forEach(this._headerConnects,_348.disconnect);delete this.grid;delete this.cell;},_colHeadNode:null,_colHeadFocusIdx:null,_contextMenuBindNode:null,tabbingOut:false,focusClass:"dojoxGridCellFocus",focusView:null,initFocusView:function(){this.focusView=this.grid.views.getFirstScrollingView()||this.focusView||this.grid.views.views[0];this._initColumnHeaders();},isFocusCell:function(_34c,_34d){return (this.cell==_34c)&&(this.rowIndex==_34d);},isLastFocusCell:function(){if(this.cell){return (this.rowIndex==this.grid.rowCount-1)&&(this.cell.index==this.grid.layout.cellCount-1);}return false;},isFirstFocusCell:function(){if(this.cell){return (this.rowIndex===0)&&(this.cell.index===0);}return false;},isNoFocusCell:function(){return (this.rowIndex<0)||!this.cell;},isNavHeader:function(){return (!!this._colHeadNode);},getHeaderIndex:function(){if(this._colHeadNode){return _346.indexOf(this._findHeaderCells(),this._colHeadNode);}else{return -1;}},_focusifyCellNode:function(_34e){var n=this.cell&&this.cell.getNode(this.rowIndex);if(n){html.toggleClass(n,this.focusClass,_34e);if(_34e){var sl=this.scrollIntoView();try{if(!this.grid.edit.isEditing()){util.fire(n,"focus");if(sl){this.cell.view.scrollboxNode.scrollLeft=sl;}}}catch(e){}}}},_delayedCellFocus:function(){if(this.isNavHeader()||!this.grid.focused){return;}var n=this.cell&&this.cell.getNode(this.rowIndex);if(n){try{if(!this.grid.edit.isEditing()){html.toggleClass(n,this.focusClass,true);if(this._colHeadNode){this.blurHeader();}util.fire(n,"focus");}}catch(e){}}},_delayedHeaderFocus:function(){if(this.isNavHeader()){this.focusHeader();this.grid.domNode.focus();}},_initColumnHeaders:function(){_346.forEach(this._headerConnects,_348.disconnect);this._headerConnects=[];var _34f=this._findHeaderCells();for(var i=0;i<_34f.length;i++){this._headerConnects.push(_348.connect(_34f[i],"onfocus",this,"doColHeaderFocus"));this._headerConnects.push(_348.connect(_34f[i],"onblur",this,"doColHeaderBlur"));}},_findHeaderCells:function(){var _350=_34a("th",this.grid.viewsHeaderNode);var _351=[];for(var i=0;i<_350.length;i++){var _352=_350[i];var _353=html.hasAttr(_352,"tabIndex");var _354=html.attr(_352,"tabIndex");if(_353&&_354<0){_351.push(_352);}}return _351;},_setActiveColHeader:function(_355,_356,_357){this.grid.domNode.setAttribute("aria-activedescendant",_355.id);if(_357!=null&&_357>=0&&_357!=_356){html.toggleClass(this._findHeaderCells()[_357],this.focusClass,false);}html.toggleClass(_355,this.focusClass,true);this._colHeadNode=_355;this._colHeadFocusIdx=_356;this._scrollHeader(this._colHeadFocusIdx);},scrollIntoView:function(){var info=(this.cell?this._scrollInfo(this.cell):null);if(!info||!info.s){return null;}var rt=this.grid.scroller.findScrollTop(this.rowIndex);if(info.n&&info.sr){if(info.n.offsetLeft+info.n.offsetWidth>info.sr.l+info.sr.w){info.s.scrollLeft=info.n.offsetLeft+info.n.offsetWidth-info.sr.w;}else{if(info.n.offsetLeft<info.sr.l){info.s.scrollLeft=info.n.offsetLeft;}}}if(info.r&&info.sr){if(rt+info.r.offsetHeight>info.sr.t+info.sr.h){this.grid.setScrollTop(rt+info.r.offsetHeight-info.sr.h);}else{if(rt<info.sr.t){this.grid.setScrollTop(rt);}}}return info.s.scrollLeft;},_scrollInfo:function(cell,_358){if(cell){var cl=cell,sbn=cl.view.scrollboxNode,sbnr={w:sbn.clientWidth,l:sbn.scrollLeft,t:sbn.scrollTop,h:sbn.clientHeight},rn=cl.view.getRowNode(this.rowIndex);return {c:cl,s:sbn,sr:sbnr,n:(_358?_358:cell.getNode(this.rowIndex)),r:rn};}return null;},_scrollHeader:function(_359){var info=null;if(this._colHeadNode){var cell=this.grid.getCell(_359);if(!cell){return;}info=this._scrollInfo(cell,cell.getNode(0));}if(info&&info.s&&info.sr&&info.n){var _35a=info.sr.l+info.sr.w;if(info.n.offsetLeft+info.n.offsetWidth>_35a){info.s.scrollLeft=info.n.offsetLeft+info.n.offsetWidth-info.sr.w;}else{if(info.n.offsetLeft<info.sr.l){info.s.scrollLeft=info.n.offsetLeft;}else{if(has("ie")<=7&&cell&&cell.view.headerNode){cell.view.headerNode.scrollLeft=info.s.scrollLeft;}}}}},_isHeaderHidden:function(){var _35b=this.focusView;if(!_35b){for(var i=0,_35c;(_35c=this.grid.views.views[i]);i++){if(_35c.headerNode){_35b=_35c;break;}}}return (_35b&&html.getComputedStyle(_35b.headerNode).display=="none");},colSizeAdjust:function(e,_35d,_35e){var _35f=this._findHeaderCells();var view=this.focusView;if(!view){for(var i=0,_360;(_360=this.grid.views.views[i]);i++){if(_360.header.tableMap.map){view=_360;break;}}}var _361=_35f[_35d];if(!view||(_35d==_35f.length-1&&_35d===0)){return;}view.content.baseDecorateEvent(e);e.cellNode=_361;e.cellIndex=view.content.getCellNodeIndex(e.cellNode);e.cell=(e.cellIndex>=0?this.grid.getCell(e.cellIndex):null);if(view.header.canResize(e)){var _362={l:_35e};var drag=view.header.colResizeSetup(e,false);view.header.doResizeColumn(drag,null,_362);view.update();}},styleRow:function(_363){return;},setFocusIndex:function(_364,_365){this.setFocusCell(this.grid.getCell(_365),_364);},setFocusCell:function(_366,_367){if(_366&&!this.isFocusCell(_366,_367)){this.tabbingOut=false;if(this._colHeadNode){this.blurHeader();}this._colHeadNode=this._colHeadFocusIdx=null;this.focusGridView();this._focusifyCellNode(false);this.cell=_366;this.rowIndex=_367;this._focusifyCellNode(true);}if(has("opera")){setTimeout(lang.hitch(this.grid,"onCellFocus",this.cell,this.rowIndex),1);}else{this.grid.onCellFocus(this.cell,this.rowIndex);}},next:function(){if(this.cell){var row=this.rowIndex,col=this.cell.index+1,cc=this.grid.layout.cellCount-1,rc=this.grid.rowCount-1;if(col>cc){col=0;row++;}if(row>rc){col=cc;row=rc;}if(this.grid.edit.isEditing()){var _368=this.grid.getCell(col);if(!this.isLastFocusCell()&&(!_368.editable||this.grid.canEdit&&!this.grid.canEdit(_368,row))){this.cell=_368;this.rowIndex=row;this.next();return;}}this.setFocusIndex(row,col);}},previous:function(){if(this.cell){var row=(this.rowIndex||0),col=(this.cell.index||0)-1;if(col<0){col=this.grid.layout.cellCount-1;row--;}if(row<0){row=0;col=0;}if(this.grid.edit.isEditing()){var _369=this.grid.getCell(col);if(!this.isFirstFocusCell()&&!_369.editable){this.cell=_369;this.rowIndex=row;this.previous();return;}}this.setFocusIndex(row,col);}},move:function(_36a,_36b){var _36c=_36b<0?-1:1;if(this.isNavHeader()){var _36d=this._findHeaderCells();var _36e=currentIdx=_346.indexOf(_36d,this._colHeadNode);currentIdx+=_36b;while(currentIdx>=0&&currentIdx<_36d.length&&_36d[currentIdx].style.display=="none"){currentIdx+=_36c;}if((currentIdx>=0)&&(currentIdx<_36d.length)){this._setActiveColHeader(_36d[currentIdx],currentIdx,_36e);}}else{if(this.cell){var sc=this.grid.scroller,r=this.rowIndex,rc=this.grid.rowCount-1,row=Math.min(rc,Math.max(0,r+_36a));if(_36a){if(_36a>0){if(row>sc.getLastPageRow(sc.page)){this.grid.setScrollTop(this.grid.scrollTop+sc.findScrollTop(row)-sc.findScrollTop(r));}}else{if(_36a<0){if(row<=sc.getPageRow(sc.page)){this.grid.setScrollTop(this.grid.scrollTop-sc.findScrollTop(r)-sc.findScrollTop(row));}}}}var cc=this.grid.layout.cellCount-1,i=this.cell.index,col=Math.min(cc,Math.max(0,i+_36b));var cell=this.grid.getCell(col);while(col>=0&&col<cc&&cell&&cell.hidden===true){col+=_36c;cell=this.grid.getCell(col);}if(!cell||cell.hidden===true){col=i;}var n=cell.getNode(row);if(!n&&_36a){if((row+_36a)>=0&&(row+_36a)<=rc){this.move(_36a>0?++_36a:--_36a,_36b);}return;}else{if((!n||html.style(n,"display")==="none")&&_36b){if((col+_36a)>=0&&(col+_36a)<=cc){this.move(_36a,_36b>0?++_36b:--_36b);}return;}}this.setFocusIndex(row,col);if(_36a){this.grid.updateRow(r);}}}},previousKey:function(e){if(this.grid.edit.isEditing()){_349.stop(e);this.previous();}else{if(!this.isNavHeader()&&!this._isHeaderHidden()){this.grid.domNode.focus();_349.stop(e);}else{this.tabOut(this.grid.domNode);if(this._colHeadFocusIdx!=null){html.toggleClass(this._findHeaderCells()[this._colHeadFocusIdx],this.focusClass,false);this._colHeadFocusIdx=null;}this._focusifyCellNode(false);}}},nextKey:function(e){var _36f=(this.grid.rowCount===0);if(e.target===this.grid.domNode&&this._colHeadFocusIdx==null){this.focusHeader();_349.stop(e);}else{if(this.isNavHeader()){this.blurHeader();if(!this.findAndFocusGridCell()){this.tabOut(this.grid.lastFocusNode);}this._colHeadNode=this._colHeadFocusIdx=null;}else{if(this.grid.edit.isEditing()){_349.stop(e);this.next();}else{this.tabOut(this.grid.lastFocusNode);}}}},tabOut:function(_370){this.tabbingOut=true;_370.focus();},focusGridView:function(){util.fire(this.focusView,"focus");},focusGrid:function(_371){this.focusGridView();this._focusifyCellNode(true);},findAndFocusGridCell:function(){var _372=true;var _373=(this.grid.rowCount===0);if(this.isNoFocusCell()&&!_373){var _374=0;var cell=this.grid.getCell(_374);if(cell.hidden){_374=this.isNavHeader()?this._colHeadFocusIdx:0;}this.setFocusIndex(0,_374);}else{if(this.cell&&!_373){if(this.focusView&&!this.focusView.rowNodes[this.rowIndex]){this.grid.scrollToRow(this.rowIndex);}this.focusGrid();}else{_372=false;}}this._colHeadNode=this._colHeadFocusIdx=null;return _372;},focusHeader:function(){var _375=this._findHeaderCells();var _376=this._colHeadFocusIdx;if(this._isHeaderHidden()){this.findAndFocusGridCell();}else{if(!this._colHeadFocusIdx){if(this.isNoFocusCell()){this._colHeadFocusIdx=0;}else{this._colHeadFocusIdx=this.cell.index;}}}this._colHeadNode=_375[this._colHeadFocusIdx];while(this._colHeadNode&&this._colHeadFocusIdx>=0&&this._colHeadFocusIdx<_375.length&&this._colHeadNode.style.display=="none"){this._colHeadFocusIdx++;this._colHeadNode=_375[this._colHeadFocusIdx];}if(this._colHeadNode&&this._colHeadNode.style.display!="none"){if(this.headerMenu&&this._contextMenuBindNode!=this.grid.domNode){this.headerMenu.unBindDomNode(this.grid.viewsHeaderNode);this.headerMenu.bindDomNode(this.grid.domNode);this._contextMenuBindNode=this.grid.domNode;}this._setActiveColHeader(this._colHeadNode,this._colHeadFocusIdx,_376);this._scrollHeader(this._colHeadFocusIdx);this._focusifyCellNode(false);}else{this.findAndFocusGridCell();}},blurHeader:function(){html.removeClass(this._colHeadNode,this.focusClass);html.removeAttr(this.grid.domNode,"aria-activedescendant");if(this.headerMenu&&this._contextMenuBindNode==this.grid.domNode){var _377=this.grid.viewsHeaderNode;this.headerMenu.unBindDomNode(this.grid.domNode);this.headerMenu.bindDomNode(_377);this._contextMenuBindNode=_377;}},doFocus:function(e){if(e&&e.target!=e.currentTarget){_349.stop(e);return;}if(this._clickFocus){return;}if(!this.tabbingOut){this.focusHeader();}this.tabbingOut=false;_349.stop(e);},doBlur:function(e){_349.stop(e);},doContextMenu:function(e){if(!this.headerMenu){_349.stop(e);}},doLastNodeFocus:function(e){if(this.tabbingOut){this._focusifyCellNode(false);}else{if(this.grid.rowCount>0){if(this.isNoFocusCell()){this.setFocusIndex(0,0);}this._focusifyCellNode(true);}else{this.focusHeader();}}this.tabbingOut=false;_349.stop(e);},doLastNodeBlur:function(e){_349.stop(e);},doColHeaderFocus:function(e){this._setActiveColHeader(e.target,html.attr(e.target,"idx"),this._colHeadFocusIdx);this._scrollHeader(this.getHeaderIndex());_349.stop(e);},doColHeaderBlur:function(e){html.toggleClass(e.target,this.focusClass,false);},_mouseDown:function(e){this._clickFocus=dojo.some(this.grid.views.views,function(v){return v.scrollboxNode===e.target;});},_mouseUp:function(e){this._clickFocus=false;}});});},"dijit/MenuItem":function(){require({cache:{"url:dijit/templates/MenuItem.html":"<tr class=\"dijitReset dijitMenuItem\" data-dojo-attach-point=\"focusNode\" role=\"menuitem\" tabIndex=\"-1\"\n\t\tdata-dojo-attach-event=\"onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick\">\n\t<td class=\"dijitReset dijitMenuItemIconCell\" role=\"presentation\">\n\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitIcon dijitMenuItemIcon\" data-dojo-attach-point=\"iconNode\"/>\n\t</td>\n\t<td class=\"dijitReset dijitMenuItemLabel\" colspan=\"2\" data-dojo-attach-point=\"containerNode\"></td>\n\t<td class=\"dijitReset dijitMenuItemAccelKey\" style=\"display: none\" data-dojo-attach-point=\"accelKeyNode\"></td>\n\t<td class=\"dijitReset dijitMenuArrowCell\" role=\"presentation\">\n\t\t<div data-dojo-attach-point=\"arrowWrapper\" style=\"visibility: hidden\">\n\t\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitMenuExpand\"/>\n\t\t\t<span class=\"dijitMenuExpandA11y\">+</span>\n\t\t</div>\n\t</td>\n</tr>\n"}});define("dijit/MenuItem",["dojo/_base/declare","dojo/dom","dojo/dom-attr","dojo/dom-class","dojo/_base/event","dojo/_base/kernel","dojo/_base/sniff","./_Widget","./_TemplatedMixin","./_Contained","./_CssStateMixin","dojo/text!./templates/MenuItem.html"],function(_378,dom,_379,_37a,_37b,_37c,has,_37d,_37e,_37f,_380,_381){return _378("dijit.MenuItem",[_37d,_37e,_37f,_380],{templateString:_381,baseClass:"dijitMenuItem",label:"",_setLabelAttr:{node:"containerNode",type:"innerHTML"},iconClass:"dijitNoIcon",_setIconClassAttr:{node:"iconNode",type:"class"},accelKey:"",disabled:false,_fillContent:function(_382){if(_382&&!("label" in this.params)){this.set("label",_382.innerHTML);}},buildRendering:function(){this.inherited(arguments);var _383=this.id+"_text";_379.set(this.containerNode,"id",_383);if(this.accelKeyNode){_379.set(this.accelKeyNode,"id",this.id+"_accel");_383+=" "+this.id+"_accel";}this.domNode.setAttribute("aria-labelledby",_383);dom.setSelectable(this.domNode,false);},_onHover:function(){this.getParent().onItemHover(this);},_onUnhover:function(){this.getParent().onItemUnhover(this);this._set("hovering",false);},_onClick:function(evt){this.getParent().onItemClick(this,evt);_37b.stop(evt);},onClick:function(){},focus:function(){try{if(has("ie")==8){this.containerNode.focus();}this.focusNode.focus();}catch(e){}},_onFocus:function(){this._setSelected(true);this.getParent()._onItemFocus(this);this.inherited(arguments);},_setSelected:function(_384){_37a.toggle(this.domNode,"dijitMenuItemSelected",_384);},setLabel:function(_385){_37c.deprecated("dijit.MenuItem.setLabel() is deprecated. Use set('label', ...) instead.","","2.0");this.set("label",_385);},setDisabled:function(_386){_37c.deprecated("dijit.Menu.setDisabled() is deprecated. Use set('disabled', bool) instead.","","2.0");this.set("disabled",_386);},_setDisabledAttr:function(_387){this.focusNode.setAttribute("aria-disabled",_387?"true":"false");this._set("disabled",_387);},_setAccelKeyAttr:function(_388){this.accelKeyNode.style.display=_388?"":"none";this.accelKeyNode.innerHTML=_388;_379.set(this.containerNode,"colSpan",_388?"1":"2");this._set("accelKey",_388);}});});},"dijit/_TemplatedMixin":function(){define("dijit/_TemplatedMixin",["dojo/_base/lang","dojo/touch","./_WidgetBase","dojo/string","dojo/cache","dojo/_base/array","dojo/_base/declare","dojo/dom-construct","dojo/_base/sniff","dojo/_base/unload","dojo/_base/window"],function(lang,_389,_38a,_38b,_38c,_38d,_38e,_38f,has,_390,win){var _391=_38e("dijit._TemplatedMixin",null,{templateString:null,templatePath:null,_skipNodeCache:false,_earlyTemplatedStartup:false,constructor:function(){this._attachPoints=[];this._attachEvents=[];},_stringRepl:function(tmpl){var _392=this.declaredClass,_393=this;return _38b.substitute(tmpl,this,function(_394,key){if(key.charAt(0)=="!"){_394=lang.getObject(key.substr(1),false,_393);}if(typeof _394=="undefined"){throw new Error(_392+" template:"+key);}if(_394==null){return "";}return key.charAt(0)=="!"?_394:_394.toString().replace(/"/g,"&quot;");},this);},buildRendering:function(){if(!this.templateString){this.templateString=_38c(this.templatePath,{sanitize:true});}var _395=_391.getCachedTemplate(this.templateString,this._skipNodeCache);var node;if(lang.isString(_395)){node=_38f.toDom(this._stringRepl(_395));if(node.nodeType!=1){throw new Error("Invalid template: "+_395);}}else{node=_395.cloneNode(true);}this.domNode=node;this.inherited(arguments);this._attachTemplateNodes(node,function(n,p){return n.getAttribute(p);});this._beforeFillContent();this._fillContent(this.srcNodeRef);},_beforeFillContent:function(){},_fillContent:function(_396){var dest=this.containerNode;if(_396&&dest){while(_396.hasChildNodes()){dest.appendChild(_396.firstChild);}}},_attachTemplateNodes:function(_397,_398){var _399=lang.isArray(_397)?_397:(_397.all||_397.getElementsByTagName("*"));var x=lang.isArray(_397)?0:-1;for(;x<_399.length;x++){var _39a=(x==-1)?_397:_399[x];if(this.widgetsInTemplate&&(_398(_39a,"dojoType")||_398(_39a,"data-dojo-type"))){continue;}var _39b=_398(_39a,"dojoAttachPoint")||_398(_39a,"data-dojo-attach-point");if(_39b){var _39c,_39d=_39b.split(/\s*,\s*/);while((_39c=_39d.shift())){if(lang.isArray(this[_39c])){this[_39c].push(_39a);}else{this[_39c]=_39a;}this._attachPoints.push(_39c);}}var _39e=_398(_39a,"dojoAttachEvent")||_398(_39a,"data-dojo-attach-event");if(_39e){var _39f,_3a0=_39e.split(/\s*,\s*/);var trim=lang.trim;while((_39f=_3a0.shift())){if(_39f){var _3a1=null;if(_39f.indexOf(":")!=-1){var _3a2=_39f.split(":");_39f=trim(_3a2[0]);_3a1=trim(_3a2[1]);}else{_39f=trim(_39f);}if(!_3a1){_3a1=_39f;}this._attachEvents.push(this.connect(_39a,_389[_39f]||_39f,_3a1));}}}}},destroyRendering:function(){_38d.forEach(this._attachPoints,function(_3a3){delete this[_3a3];},this);this._attachPoints=[];_38d.forEach(this._attachEvents,this.disconnect,this);this._attachEvents=[];this.inherited(arguments);}});_391._templateCache={};_391.getCachedTemplate=function(_3a4,_3a5){var _3a6=_391._templateCache;var key=_3a4;var _3a7=_3a6[key];if(_3a7){try{if(!_3a7.ownerDocument||_3a7.ownerDocument==win.doc){return _3a7;}}catch(e){}_38f.destroy(_3a7);}_3a4=_38b.trim(_3a4);if(_3a5||_3a4.match(/\$\{([^\}]+)\}/g)){return (_3a6[key]=_3a4);}else{var node=_38f.toDom(_3a4);if(node.nodeType!=1){throw new Error("Invalid template: "+_3a4);}return (_3a6[key]=node);}};if(has("ie")){_390.addOnWindowUnload(function(){var _3a8=_391._templateCache;for(var key in _3a8){var _3a9=_3a8[key];if(typeof _3a9=="object"){_38f.destroy(_3a9);}delete _3a8[key];}});}lang.extend(_38a,{dojoAttachEvent:"",dojoAttachPoint:""});return _391;});},"dojox/grid/_SelectionPreserver":function(){define("dojox/grid/_SelectionPreserver",["dojo/_base/declare","dojo/_base/connect","dojo/_base/lang","dojo/_base/array"],function(_3aa,_3ab,lang,_3ac){return _3aa("dojox.grid._SelectionPreserver",null,{constructor:function(_3ad){this.selection=_3ad;var grid=this.grid=_3ad.grid;this.reset();this._connects=[_3ab.connect(grid,"_setStore",this,"reset"),_3ab.connect(grid,"_addItem",this,"_reSelectById"),_3ab.connect(_3ad,"addToSelection",lang.hitch(this,"_selectById",true)),_3ab.connect(_3ad,"deselect",lang.hitch(this,"_selectById",false)),_3ab.connect(_3ad,"deselectAll",this,"reset")];},destroy:function(){this.reset();_3ac.forEach(this._connects,_3ab.disconnect);delete this._connects;},reset:function(){this._selectedById={};},_reSelectById:function(item,_3ae){if(item&&this.grid._hasIdentity){this.selection.selected[_3ae]=this._selectedById[this.grid.store.getIdentity(item)];}},_selectById:function(_3af,_3b0){if(this.selection.mode=="none"||!this.grid._hasIdentity){return;}var item=_3b0,g=this.grid;if(typeof _3b0=="number"||typeof _3b0=="string"){var _3b1=g._by_idx[_3b0];item=_3b1&&_3b1.item;}if(item){this._selectedById[g.store.getIdentity(item)]=!!_3af;}return item;}});});},"dojo/window":function(){define(["./_base/lang","./_base/sniff","./_base/window","./dom","./dom-geometry","./dom-style"],function(lang,has,_3b2,dom,geom,_3b3){var _3b4=lang.getObject("dojo.window",true);_3b4.getBox=function(){var _3b5=(_3b2.doc.compatMode=="BackCompat")?_3b2.body():_3b2.doc.documentElement,_3b6=geom.docScroll(),w,h;if(has("touch")){var _3b7=_3b2.doc.parentWindow||_3b2.doc.defaultView;w=_3b7.innerWidth||_3b5.clientWidth;h=_3b7.innerHeight||_3b5.clientHeight;}else{w=_3b5.clientWidth;h=_3b5.clientHeight;}return {l:_3b6.x,t:_3b6.y,w:w,h:h};};_3b4.get=function(doc){if(has("ie")&&_3b4!==document.parentWindow){doc.parentWindow.execScript("document._parentWindow = window;","Javascript");var win=doc._parentWindow;doc._parentWindow=null;return win;}return doc.parentWindow||doc.defaultView;};_3b4.scrollIntoView=function(node,pos){try{node=dom.byId(node);var doc=node.ownerDocument||_3b2.doc,body=doc.body||_3b2.body(),html=doc.documentElement||body.parentNode,isIE=has("ie"),isWK=has("webkit");if((!(has("mozilla")||isIE||isWK||has("opera"))||node==body||node==html)&&(typeof node.scrollIntoView!="undefined")){node.scrollIntoView(false);return;}var _3b8=doc.compatMode=="BackCompat",_3b9=(isIE>=9&&node.ownerDocument.parentWindow.frameElement)?((html.clientHeight>0&&html.clientWidth>0&&(body.clientHeight==0||body.clientWidth==0||body.clientHeight>html.clientHeight||body.clientWidth>html.clientWidth))?html:body):(_3b8?body:html),_3ba=isWK?body:_3b9,_3bb=_3b9.clientWidth,_3bc=_3b9.clientHeight,rtl=!geom.isBodyLtr(),_3bd=pos||geom.position(node),el=node.parentNode,_3be=function(el){return ((isIE<=6||(isIE&&_3b8))?false:(_3b3.get(el,"position").toLowerCase()=="fixed"));};if(_3be(node)){return;}while(el){if(el==body){el=_3ba;}var _3bf=geom.position(el),_3c0=_3be(el);if(el==_3ba){_3bf.w=_3bb;_3bf.h=_3bc;if(_3ba==html&&isIE&&rtl){_3bf.x+=_3ba.offsetWidth-_3bf.w;}if(_3bf.x<0||!isIE){_3bf.x=0;}if(_3bf.y<0||!isIE){_3bf.y=0;}}else{var pb=geom.getPadBorderExtents(el);_3bf.w-=pb.w;_3bf.h-=pb.h;_3bf.x+=pb.l;_3bf.y+=pb.t;var _3c1=el.clientWidth,_3c2=_3bf.w-_3c1;if(_3c1>0&&_3c2>0){_3bf.w=_3c1;_3bf.x+=(rtl&&(isIE||el.clientLeft>pb.l))?_3c2:0;}_3c1=el.clientHeight;_3c2=_3bf.h-_3c1;if(_3c1>0&&_3c2>0){_3bf.h=_3c1;}}if(_3c0){if(_3bf.y<0){_3bf.h+=_3bf.y;_3bf.y=0;}if(_3bf.x<0){_3bf.w+=_3bf.x;_3bf.x=0;}if(_3bf.y+_3bf.h>_3bc){_3bf.h=_3bc-_3bf.y;}if(_3bf.x+_3bf.w>_3bb){_3bf.w=_3bb-_3bf.x;}}var l=_3bd.x-_3bf.x,t=_3bd.y-Math.max(_3bf.y,0),r=l+_3bd.w-_3bf.w,bot=t+_3bd.h-_3bf.h;if(r*l>0){var s=Math[l<0?"max":"min"](l,r);if(rtl&&((isIE==8&&!_3b8)||isIE>=9)){s=-s;}_3bd.x+=el.scrollLeft;el.scrollLeft+=s;_3bd.x-=el.scrollLeft;}if(bot*t>0){_3bd.y+=el.scrollTop;el.scrollTop+=Math[t<0?"max":"min"](t,bot);_3bd.y-=el.scrollTop;}el=(el!=_3ba)&&!_3c0&&el.parentNode;}}catch(error){console.error("scrollIntoView: "+error);node.scrollIntoView(false);}};return _3b4;});},"dojox/grid/_Builder":function(){define("dojox/grid/_Builder",["../main","dojo/_base/array","dojo/_base/lang","dojo/_base/window","dojo/_base/event","dojo/_base/sniff","dojo/_base/connect","dojo/dnd/Moveable","dojox/html/metrics","./util","dojo/_base/html"],function(_3c3,_3c4,lang,win,_3c5,has,_3c6,_3c7,_3c8,util,html){var dg=_3c3.grid;var _3c9=function(td){return td.cellIndex>=0?td.cellIndex:_3c4.indexOf(td.parentNode.cells,td);};var _3ca=function(tr){return tr.rowIndex>=0?tr.rowIndex:_3c4.indexOf(tr.parentNode.childNodes,tr);};var _3cb=function(_3cc,_3cd){return _3cc&&((_3cc.rows||0)[_3cd]||_3cc.childNodes[_3cd]);};var _3ce=function(node){for(var n=node;n&&n.tagName!="TABLE";n=n.parentNode){}return n;};var _3cf=function(_3d0,_3d1){for(var n=_3d0;n&&_3d1(n);n=n.parentNode){}return n;};var _3d2=function(_3d3){var name=_3d3.toUpperCase();return function(node){return node.tagName!=name;};};var _3d4=util.rowIndexTag;var _3d5=util.gridViewTag;var _3d6=dg._Builder=lang.extend(function(view){if(view){this.view=view;this.grid=view.grid;}},{view:null,_table:"<table class=\"dojoxGridRowTable\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\" role=\"presentation\"",getTableArray:function(){var html=[this._table];if(this.view.viewWidth){html.push([" style=\"width:",this.view.viewWidth,";\""].join(""));}html.push(">");return html;},generateCellMarkup:function(_3d7,_3d8,_3d9,_3da){var _3db=[],html;if(_3da){var _3dc=_3d7.index!=_3d7.grid.getSortIndex()?"":_3d7.grid.sortInfo>0?"aria-sort=\"ascending\"":"aria-sort=\"descending\"";if(!_3d7.id){_3d7.id=this.grid.id+"Hdr"+_3d7.index;}html=["<th tabIndex=\"-1\" aria-readonly=\"true\" role=\"columnheader\"",_3dc,"id=\"",_3d7.id,"\""];}else{var _3dd=this.grid.editable&&!_3d7.editable?"aria-readonly=\"true\"":"";html=["<td tabIndex=\"-1\" role=\"gridcell\"",_3dd];}if(_3d7.colSpan){html.push(" colspan=\"",_3d7.colSpan,"\"");}if(_3d7.rowSpan){html.push(" rowspan=\"",_3d7.rowSpan,"\"");}html.push(" class=\"dojoxGridCell ");if(_3d7.classes){html.push(_3d7.classes," ");}if(_3d9){html.push(_3d9," ");}_3db.push(html.join(""));_3db.push("");html=["\" idx=\"",_3d7.index,"\" style=\""];if(_3d8&&_3d8[_3d8.length-1]!=";"){_3d8+=";";}html.push(_3d7.styles,_3d8||"",_3d7.hidden?"display:none;":"");if(_3d7.unitWidth){html.push("width:",_3d7.unitWidth,";");}_3db.push(html.join(""));_3db.push("");html=["\""];if(_3d7.attrs){html.push(" ",_3d7.attrs);}html.push(">");_3db.push(html.join(""));_3db.push("");_3db.push(_3da?"</th>":"</td>");return _3db;},isCellNode:function(_3de){return Boolean(_3de&&_3de!=win.doc&&html.attr(_3de,"idx"));},getCellNodeIndex:function(_3df){return _3df?Number(html.attr(_3df,"idx")):-1;},getCellNode:function(_3e0,_3e1){for(var i=0,row;((row=_3cb(_3e0.firstChild,i))&&row.cells);i++){for(var j=0,cell;(cell=row.cells[j]);j++){if(this.getCellNodeIndex(cell)==_3e1){return cell;}}}return null;},findCellTarget:function(_3e2,_3e3){var n=_3e2;while(n&&(!this.isCellNode(n)||(n.offsetParent&&_3d5 in n.offsetParent.parentNode&&n.offsetParent.parentNode[_3d5]!=this.view.id))&&(n!=_3e3)){n=n.parentNode;}return n!=_3e3?n:null;},baseDecorateEvent:function(e){e.dispatch="do"+e.type;e.grid=this.grid;e.sourceView=this.view;e.cellNode=this.findCellTarget(e.target,e.rowNode);e.cellIndex=this.getCellNodeIndex(e.cellNode);e.cell=(e.cellIndex>=0?this.grid.getCell(e.cellIndex):null);},findTarget:function(_3e4,_3e5){var n=_3e4;while(n&&(n!=this.domNode)&&(!(_3e5 in n)||(_3d5 in n&&n[_3d5]!=this.view.id))){n=n.parentNode;}return (n!=this.domNode)?n:null;},findRowTarget:function(_3e6){return this.findTarget(_3e6,_3d4);},isIntraNodeEvent:function(e){try{return (e.cellNode&&e.relatedTarget&&html.isDescendant(e.relatedTarget,e.cellNode));}catch(x){return false;}},isIntraRowEvent:function(e){try{var row=e.relatedTarget&&this.findRowTarget(e.relatedTarget);return !row&&(e.rowIndex==-1)||row&&(e.rowIndex==row.gridRowIndex);}catch(x){return false;}},dispatchEvent:function(e){if(e.dispatch in this){return this[e.dispatch](e);}return false;},domouseover:function(e){if(e.cellNode&&(e.cellNode!=this.lastOverCellNode)){this.lastOverCellNode=e.cellNode;this.grid.onMouseOver(e);}this.grid.onMouseOverRow(e);},domouseout:function(e){if(e.cellNode&&(e.cellNode==this.lastOverCellNode)&&!this.isIntraNodeEvent(e,this.lastOverCellNode)){this.lastOverCellNode=null;this.grid.onMouseOut(e);if(!this.isIntraRowEvent(e)){this.grid.onMouseOutRow(e);}}},domousedown:function(e){if(e.cellNode){this.grid.onMouseDown(e);}this.grid.onMouseDownRow(e);}});var _3e7=dg._ContentBuilder=lang.extend(function(view){_3d6.call(this,view);},_3d6.prototype,{update:function(){this.prepareHtml();},prepareHtml:function(){var _3e8=this.grid.get,_3e9=this.view.structure.cells;for(var j=0,row;(row=_3e9[j]);j++){for(var i=0,cell;(cell=row[i]);i++){cell.get=cell.get||(cell.value==undefined)&&_3e8;cell.markup=this.generateCellMarkup(cell,cell.cellStyles,cell.cellClasses,false);if(!this.grid.editable&&cell.editable){this.grid.editable=true;}}}},generateHtml:function(_3ea,_3eb){var html=this.getTableArray(),v=this.view,_3ec=v.structure.cells,item=this.grid.getItem(_3eb);util.fire(this.view,"onBeforeRow",[_3eb,_3ec]);for(var j=0,row;(row=_3ec[j]);j++){if(row.hidden||row.header){continue;}html.push(!row.invisible?"<tr>":"<tr class=\"dojoxGridInvisible\">");for(var i=0,cell,m,cc,cs;(cell=row[i]);i++){m=cell.markup;cc=cell.customClasses=[];cs=cell.customStyles=[];m[5]=cell.format(_3eb,item);if(has("ie")<8&&(m[5]===null||m[5]===""||/^\s+$/.test(m[5]))){m[5]="&nbsp;";}m[1]=cc.join(" ");m[3]=cs.join(";");html.push.apply(html,m);}html.push("</tr>");}html.push("</table>");return html.join("");},decorateEvent:function(e){e.rowNode=this.findRowTarget(e.target);if(!e.rowNode){return false;}e.rowIndex=e.rowNode[_3d4];this.baseDecorateEvent(e);e.cell=this.grid.getCell(e.cellIndex);return true;}});var _3ed=dg._HeaderBuilder=lang.extend(function(view){this.moveable=null;_3d6.call(this,view);},_3d6.prototype,{_skipBogusClicks:false,overResizeWidth:4,minColWidth:1,update:function(){if(this.tableMap){this.tableMap.mapRows(this.view.structure.cells);}else{this.tableMap=new dg._TableMap(this.view.structure.cells);}},generateHtml:function(_3ee,_3ef){var html=this.getTableArray(),_3f0=this.view.structure.cells;util.fire(this.view,"onBeforeRow",[-1,_3f0]);for(var j=0,row;(row=_3f0[j]);j++){if(row.hidden){continue;}html.push(!row.invisible?"<tr>":"<tr class=\"dojoxGridInvisible\">");for(var i=0,cell,_3f1;(cell=row[i]);i++){cell.customClasses=[];cell.customStyles=[];if(this.view.simpleStructure){if(cell.draggable){if(cell.headerClasses){if(cell.headerClasses.indexOf("dojoDndItem")==-1){cell.headerClasses+=" dojoDndItem";}}else{cell.headerClasses="dojoDndItem";}}if(cell.attrs){if(cell.attrs.indexOf("dndType='gridColumn_")==-1){cell.attrs+=" dndType='gridColumn_"+this.grid.id+"'";}}else{cell.attrs="dndType='gridColumn_"+this.grid.id+"'";}}_3f1=this.generateCellMarkup(cell,cell.headerStyles,cell.headerClasses,true);_3f1[5]=(_3ef!=undefined?_3ef:_3ee(cell));_3f1[3]=cell.customStyles.join(";");_3f1[1]=cell.customClasses.join(" ");html.push(_3f1.join(""));}html.push("</tr>");}html.push("</table>");return html.join("");},getCellX:function(e){var n,x=e.layerX;if(has("mozilla")||has("ie")>=9){n=_3cf(e.target,_3d2("th"));x-=(n&&n.offsetLeft)||0;var t=e.sourceView.getScrollbarWidth();if(!this.grid.isLeftToRight()){table=_3cf(n,_3d2("table"));x-=(table&&table.offsetLeft)||0;}}n=_3cf(e.target,function(){if(!n||n==e.cellNode){return false;}x+=(n.offsetLeft<0?0:n.offsetLeft);return true;});return x;},decorateEvent:function(e){this.baseDecorateEvent(e);e.rowIndex=-1;e.cellX=this.getCellX(e);return true;},prepareResize:function(e,mod){do{var i=e.cellIndex;e.cellNode=(i?e.cellNode.parentNode.cells[i+mod]:null);e.cellIndex=(e.cellNode?this.getCellNodeIndex(e.cellNode):-1);}while(e.cellNode&&e.cellNode.style.display=="none");return Boolean(e.cellNode);},canResize:function(e){if(!e.cellNode||e.cellNode.colSpan>1){return false;}var cell=this.grid.getCell(e.cellIndex);return !cell.noresize&&cell.canResize();},overLeftResizeArea:function(e){if(html.hasClass(win.body(),"dojoDndMove")){return false;}if(has("ie")){var tN=e.target;if(html.hasClass(tN,"dojoxGridArrowButtonNode")||html.hasClass(tN,"dojoxGridArrowButtonChar")||html.hasClass(tN,"dojoxGridColCaption")){return false;}}if(this.grid.isLeftToRight()){return (e.cellIndex>0)&&(e.cellX>0&&e.cellX<this.overResizeWidth)&&this.prepareResize(e,-1);}var t=e.cellNode&&(e.cellX>0&&e.cellX<this.overResizeWidth);return t;},overRightResizeArea:function(e){if(html.hasClass(win.body(),"dojoDndMove")){return false;}if(has("ie")){var tN=e.target;if(html.hasClass(tN,"dojoxGridArrowButtonNode")||html.hasClass(tN,"dojoxGridArrowButtonChar")||html.hasClass(tN,"dojoxGridColCaption")){return false;}}if(this.grid.isLeftToRight()){return e.cellNode&&(e.cellX>=e.cellNode.offsetWidth-this.overResizeWidth);}return (e.cellIndex>0)&&(e.cellX>=e.cellNode.offsetWidth-this.overResizeWidth)&&this.prepareResize(e,-1);},domousemove:function(e){if(!this.moveable){var c=(this.overRightResizeArea(e)?"dojoxGridColResize":(this.overLeftResizeArea(e)?"dojoxGridColResize":""));if(c&&!this.canResize(e)){c="dojoxGridColNoResize";}html.toggleClass(e.sourceView.headerNode,"dojoxGridColNoResize",(c=="dojoxGridColNoResize"));html.toggleClass(e.sourceView.headerNode,"dojoxGridColResize",(c=="dojoxGridColResize"));if(c){_3c5.stop(e);}}},domousedown:function(e){if(!this.moveable){if((this.overRightResizeArea(e)||this.overLeftResizeArea(e))&&this.canResize(e)){this.beginColumnResize(e);}else{this.grid.onMouseDown(e);this.grid.onMouseOverRow(e);}}},doclick:function(e){if(this._skipBogusClicks){_3c5.stop(e);return true;}return false;},colResizeSetup:function(e,_3f2){var _3f3=html.contentBox(e.sourceView.headerNode);if(_3f2){this.lineDiv=document.createElement("div");var vw=html.position(e.sourceView.headerNode,true);var _3f4=html.contentBox(e.sourceView.domNode);var l=e.pageX;if(!this.grid.isLeftToRight()&&has("ie")<8){l-=_3c8.getScrollbar().w;}html.style(this.lineDiv,{top:vw.y+"px",left:l+"px",height:(_3f4.h+_3f3.h)+"px"});html.addClass(this.lineDiv,"dojoxGridResizeColLine");this.lineDiv._origLeft=l;win.body().appendChild(this.lineDiv);}var _3f5=[],_3f6=this.tableMap.findOverlappingNodes(e.cellNode);for(var i=0,cell;(cell=_3f6[i]);i++){_3f5.push({node:cell,index:this.getCellNodeIndex(cell),width:cell.offsetWidth});}var view=e.sourceView;var adj=this.grid.isLeftToRight()?1:-1;var _3f7=e.grid.views.views;var _3f8=[];for(var j=view.idx+adj,_3f9;(_3f9=_3f7[j]);j=j+adj){_3f8.push({node:_3f9.headerNode,left:window.parseInt(_3f9.headerNode.style.left)});}var _3fa=view.headerContentNode.firstChild;var drag={scrollLeft:e.sourceView.headerNode.scrollLeft,view:view,node:e.cellNode,index:e.cellIndex,w:html.contentBox(e.cellNode).w,vw:_3f3.w,table:_3fa,tw:html.contentBox(_3fa).w,spanners:_3f5,followers:_3f8};return drag;},beginColumnResize:function(e){this.moverDiv=document.createElement("div");html.style(this.moverDiv,{position:"absolute",left:0});win.body().appendChild(this.moverDiv);html.addClass(this.grid.domNode,"dojoxGridColumnResizing");var m=(this.moveable=new _3c7(this.moverDiv));var drag=this.colResizeSetup(e,true);m.onMove=lang.hitch(this,"doResizeColumn",drag);_3c6.connect(m,"onMoveStop",lang.hitch(this,function(){this.endResizeColumn(drag);if(drag.node.releaseCapture){drag.node.releaseCapture();}this.moveable.destroy();delete this.moveable;this.moveable=null;html.removeClass(this.grid.domNode,"dojoxGridColumnResizing");}));if(e.cellNode.setCapture){e.cellNode.setCapture();}m.onMouseDown(e);},doResizeColumn:function(_3fb,_3fc,_3fd){var _3fe=_3fd.l;var data={deltaX:_3fe,w:_3fb.w+(this.grid.isLeftToRight()?_3fe:-_3fe),vw:_3fb.vw+_3fe,tw:_3fb.tw+_3fe};this.dragRecord={inDrag:_3fb,mover:_3fc,leftTop:_3fd};if(data.w>=this.minColWidth){if(!_3fc){this.doResizeNow(_3fb,data);}else{html.style(this.lineDiv,"left",(this.lineDiv._origLeft+data.deltaX)+"px");}}},endResizeColumn:function(_3ff){if(this.dragRecord){var _400=this.dragRecord.leftTop;var _401=this.grid.isLeftToRight()?_400.l:-_400.l;_401+=Math.max(_3ff.w+_401,this.minColWidth)-(_3ff.w+_401);if(has("webkit")&&_3ff.spanners.length){_401+=html._getPadBorderExtents(_3ff.spanners[0].node).w;}var data={deltaX:_401,w:_3ff.w+_401,vw:_3ff.vw+_401,tw:_3ff.tw+_401};this.doResizeNow(_3ff,data);delete this.dragRecord;}html.destroy(this.lineDiv);html.destroy(this.moverDiv);html.destroy(this.moverDiv);delete this.moverDiv;this._skipBogusClicks=true;_3ff.view.update();this._skipBogusClicks=false;this.grid.onResizeColumn(_3ff.index);},doResizeNow:function(_402,data){_402.view.convertColPctToFixed();if(_402.view.flexCells&&!_402.view.testFlexCells()){var t=_3ce(_402.node);if(t){(t.style.width="");}}var i,s,sw,f,fl;for(i=0;(s=_402.spanners[i]);i++){sw=s.width+data.deltaX;if(sw>0){s.node.style.width=sw+"px";_402.view.setColWidth(s.index,sw);}}if(this.grid.isLeftToRight()||!has("ie")){for(i=0;(f=_402.followers[i]);i++){fl=f.left+data.deltaX;f.node.style.left=fl+"px";}}_402.node.style.width=data.w+"px";_402.view.setColWidth(_402.index,data.w);_402.view.headerNode.style.width=data.vw+"px";_402.view.setColumnsWidth(data.tw);if(!this.grid.isLeftToRight()){_402.view.headerNode.scrollLeft=_402.scrollLeft+data.deltaX;}}});dg._TableMap=lang.extend(function(rows){this.mapRows(rows);},{map:null,mapRows:function(_403){var _404=_403.length;if(!_404){return;}this.map=[];var row;for(var k=0;(row=_403[k]);k++){this.map[k]=[];}for(var j=0;(row=_403[j]);j++){for(var i=0,x=0,cell,_405,_406;(cell=row[i]);i++){while(this.map[j][x]){x++;}this.map[j][x]={c:i,r:j};_406=cell.rowSpan||1;_405=cell.colSpan||1;for(var y=0;y<_406;y++){for(var s=0;s<_405;s++){this.map[j+y][x+s]=this.map[j][x];}}x+=_405;}}},dumpMap:function(){for(var j=0,row,h="";(row=this.map[j]);j++,h=""){for(var i=0,cell;(cell=row[i]);i++){h+=cell.r+","+cell.c+" ";}}},getMapCoords:function(_407,_408){for(var j=0,row;(row=this.map[j]);j++){for(var i=0,cell;(cell=row[i]);i++){if(cell.c==_408&&cell.r==_407){return {j:j,i:i};}}}return {j:-1,i:-1};},getNode:function(_409,_40a,_40b){var row=_409&&_409.rows[_40a];return row&&row.cells[_40b];},_findOverlappingNodes:function(_40c,_40d,_40e){var _40f=[];var m=this.getMapCoords(_40d,_40e);for(var j=0,row;(row=this.map[j]);j++){if(j==m.j){continue;}var rw=row[m.i];var n=(rw?this.getNode(_40c,rw.r,rw.c):null);if(n){_40f.push(n);}}return _40f;},findOverlappingNodes:function(_410){return this._findOverlappingNodes(_3ce(_410),_3ca(_410.parentNode),_3c9(_410));}});return {_Builder:_3d6,_HeaderBuilder:_3ed,_ContentBuilder:_3e7};});},"dojo/dnd/Source":function(){define(["../main","./Selector","./Manager"],function(dojo,_411,_412){if(!dojo.isAsync){dojo.ready(0,function(){var _413=["dojo/dnd/AutoSource","dojo/dnd/Target"];require(_413);});}return dojo.declare("dojo.dnd.Source",_411,{isSource:true,horizontal:false,copyOnly:false,selfCopy:false,selfAccept:true,skipForm:false,withHandles:false,autoSync:false,delay:0,accept:["text"],generateText:true,constructor:function(node,_414){dojo.mixin(this,dojo.mixin({},_414));var type=this.accept;if(type.length){this.accept={};for(var i=0;i<type.length;++i){this.accept[type[i]]=1;}}this.isDragging=false;this.mouseDown=false;this.targetAnchor=null;this.targetBox=null;this.before=true;this._lastX=0;this._lastY=0;this.sourceState="";if(this.isSource){dojo.addClass(this.node,"dojoDndSource");}this.targetState="";if(this.accept){dojo.addClass(this.node,"dojoDndTarget");}if(this.horizontal){dojo.addClass(this.node,"dojoDndHorizontal");}this.topics=[dojo.subscribe("/dnd/source/over",this,"onDndSourceOver"),dojo.subscribe("/dnd/start",this,"onDndStart"),dojo.subscribe("/dnd/drop",this,"onDndDrop"),dojo.subscribe("/dnd/cancel",this,"onDndCancel")];},checkAcceptance:function(_415,_416){if(this==_415){return !this.copyOnly||this.selfAccept;}for(var i=0;i<_416.length;++i){var type=_415.getItem(_416[i].id).type;var flag=false;for(var j=0;j<type.length;++j){if(type[j] in this.accept){flag=true;break;}}if(!flag){return false;}}return true;},copyState:function(_417,self){if(_417){return true;}if(arguments.length<2){self=this==_412.manager().target;}if(self){if(this.copyOnly){return this.selfCopy;}}else{return this.copyOnly;}return false;},destroy:function(){dojo.dnd.Source.superclass.destroy.call(this);dojo.forEach(this.topics,dojo.unsubscribe);this.targetAnchor=null;},onMouseMove:function(e){if(this.isDragging&&this.targetState=="Disabled"){return;}dojo.dnd.Source.superclass.onMouseMove.call(this,e);var m=_412.manager();if(!this.isDragging){if(this.mouseDown&&this.isSource&&(Math.abs(e.pageX-this._lastX)>this.delay||Math.abs(e.pageY-this._lastY)>this.delay)){var _418=this.getSelectedNodes();if(_418.length){m.startDrag(this,_418,this.copyState(dojo.isCopyKey(e),true));}}}if(this.isDragging){var _419=false;if(this.current){if(!this.targetBox||this.targetAnchor!=this.current){this.targetBox=dojo.position(this.current,true);}if(this.horizontal){_419=(e.pageX-this.targetBox.x)<(this.targetBox.w/2);}else{_419=(e.pageY-this.targetBox.y)<(this.targetBox.h/2);}}if(this.current!=this.targetAnchor||_419!=this.before){this._markTargetAnchor(_419);m.canDrop(!this.current||m.source!=this||!(this.current.id in this.selection));}}},onMouseDown:function(e){if(!this.mouseDown&&this._legalMouseDown(e)&&(!this.skipForm||!dojo.dnd.isFormElement(e))){this.mouseDown=true;this._lastX=e.pageX;this._lastY=e.pageY;dojo.dnd.Source.superclass.onMouseDown.call(this,e);}},onMouseUp:function(e){if(this.mouseDown){this.mouseDown=false;dojo.dnd.Source.superclass.onMouseUp.call(this,e);}},onDndSourceOver:function(_41a){if(this!=_41a){this.mouseDown=false;if(this.targetAnchor){this._unmarkTargetAnchor();}}else{if(this.isDragging){var m=_412.manager();m.canDrop(this.targetState!="Disabled"&&(!this.current||m.source!=this||!(this.current.id in this.selection)));}}},onDndStart:function(_41b,_41c,copy){if(this.autoSync){this.sync();}if(this.isSource){this._changeState("Source",this==_41b?(copy?"Copied":"Moved"):"");}var _41d=this.accept&&this.checkAcceptance(_41b,_41c);this._changeState("Target",_41d?"":"Disabled");if(this==_41b){_412.manager().overSource(this);}this.isDragging=true;},onDndDrop:function(_41e,_41f,copy,_420){if(this==_420){this.onDrop(_41e,_41f,copy);}this.onDndCancel();},onDndCancel:function(){if(this.targetAnchor){this._unmarkTargetAnchor();this.targetAnchor=null;}this.before=true;this.isDragging=false;this.mouseDown=false;this._changeState("Source","");this._changeState("Target","");},onDrop:function(_421,_422,copy){if(this!=_421){this.onDropExternal(_421,_422,copy);}else{this.onDropInternal(_422,copy);}},onDropExternal:function(_423,_424,copy){var _425=this._normalizedCreator;if(this.creator){this._normalizedCreator=function(node,hint){return _425.call(this,_423.getItem(node.id).data,hint);};}else{if(copy){this._normalizedCreator=function(node,hint){var t=_423.getItem(node.id);var n=node.cloneNode(true);n.id=dojo.dnd.getUniqueId();return {node:n,data:t.data,type:t.type};};}else{this._normalizedCreator=function(node,hint){var t=_423.getItem(node.id);_423.delItem(node.id);return {node:node,data:t.data,type:t.type};};}}this.selectNone();if(!copy&&!this.creator){_423.selectNone();}this.insertNodes(true,_424,this.before,this.current);if(!copy&&this.creator){_423.deleteSelectedNodes();}this._normalizedCreator=_425;},onDropInternal:function(_426,copy){var _427=this._normalizedCreator;if(this.current&&this.current.id in this.selection){return;}if(copy){if(this.creator){this._normalizedCreator=function(node,hint){return _427.call(this,this.getItem(node.id).data,hint);};}else{this._normalizedCreator=function(node,hint){var t=this.getItem(node.id);var n=node.cloneNode(true);n.id=dojo.dnd.getUniqueId();return {node:n,data:t.data,type:t.type};};}}else{if(!this.current){return;}this._normalizedCreator=function(node,hint){var t=this.getItem(node.id);return {node:node,data:t.data,type:t.type};};}this._removeSelection();this.insertNodes(true,_426,this.before,this.current);this._normalizedCreator=_427;},onDraggingOver:function(){},onDraggingOut:function(){},onOverEvent:function(){dojo.dnd.Source.superclass.onOverEvent.call(this);_412.manager().overSource(this);if(this.isDragging&&this.targetState!="Disabled"){this.onDraggingOver();}},onOutEvent:function(){dojo.dnd.Source.superclass.onOutEvent.call(this);_412.manager().outSource(this);if(this.isDragging&&this.targetState!="Disabled"){this.onDraggingOut();}},_markTargetAnchor:function(_428){if(this.current==this.targetAnchor&&this.before==_428){return;}if(this.targetAnchor){this._removeItemClass(this.targetAnchor,this.before?"Before":"After");}this.targetAnchor=this.current;this.targetBox=null;this.before=_428;if(this.targetAnchor){this._addItemClass(this.targetAnchor,this.before?"Before":"After");}},_unmarkTargetAnchor:function(){if(!this.targetAnchor){return;}this._removeItemClass(this.targetAnchor,this.before?"Before":"After");this.targetAnchor=null;this.targetBox=null;this.before=true;},_markDndStatus:function(copy){this._changeState("Source",copy?"Copied":"Moved");},_legalMouseDown:function(e){if(!dojo.mouseButtons.isLeft(e)){return false;}if(!this.withHandles){return true;}for(var node=e.target;node&&node!==this.node;node=node.parentNode){if(dojo.hasClass(node,"dojoDndHandle")){return true;}if(dojo.hasClass(node,"dojoDndItem")||dojo.hasClass(node,"dojoDndIgnore")){break;}}return false;}});});},"dojox/grid/cells/_base":function(){define("dojox/grid/cells/_base",["dojo/_base/kernel","dojo/_base/declare","dojo/_base/lang","dojo/_base/event","dojo/_base/connect","dojo/_base/array","dojo/_base/sniff","dojo/dom","dojo/dom-attr","dojo/dom-construct","dijit/_Widget","../util"],function(dojo,_429,lang,_42a,_42b,_42c,has,dom,_42d,_42e,_42f,util){var _430=_429("dojox.grid._DeferredTextWidget",_42f,{deferred:null,_destroyOnRemove:true,postCreate:function(){if(this.deferred){this.deferred.addBoth(lang.hitch(this,function(text){if(this.domNode){this.domNode.innerHTML=text;}}));}}});var _431=function(_432){try{util.fire(_432,"focus");util.fire(_432,"select");}catch(e){}};var _433=function(){setTimeout(lang.hitch.apply(dojo,arguments),0);};var _434=_429("dojox.grid.cells._Base",null,{styles:"",classes:"",editable:false,alwaysEditing:false,formatter:null,defaultValue:"...",value:null,hidden:false,noresize:false,draggable:true,_valueProp:"value",_formatPending:false,constructor:function(_435){this._props=_435||{};lang.mixin(this,_435);if(this.draggable===undefined){this.draggable=true;}},_defaultFormat:function(_436,_437){var s=this.grid.formatterScope||this;var f=this.formatter;if(f&&s&&typeof f=="string"){f=this.formatter=s[f];}var v=(_436!=this.defaultValue&&f)?f.apply(s,_437):_436;if(typeof v=="undefined"){return this.defaultValue;}if(v&&v.addBoth){v=new _430({deferred:v},_42e.create("span",{innerHTML:this.defaultValue}));}if(v&&v.declaredClass&&v.startup){return "<div class='dojoxGridStubNode' linkWidget='"+v.id+"' cellIdx='"+this.index+"'>"+this.defaultValue+"</div>";}return v;},format:function(_438,_439){var f,i=this.grid.edit.info,d=this.get?this.get(_438,_439):(this.value||this.defaultValue);d=(d&&d.replace&&this.grid.escapeHTMLInData)?d.replace(/&/g,"&amp;").replace(/</g,"&lt;"):d;if(this.editable&&(this.alwaysEditing||(i.rowIndex==_438&&i.cell==this))){return this.formatEditing(d,_438);}else{return this._defaultFormat(d,[d,_438,this]);}},formatEditing:function(_43a,_43b){},getNode:function(_43c){return this.view.getCellNode(_43c,this.index);},getHeaderNode:function(){return this.view.getHeaderCellNode(this.index);},getEditNode:function(_43d){return (this.getNode(_43d)||0).firstChild||0;},canResize:function(){var uw=this.unitWidth;return uw&&(uw!=="auto");},isFlex:function(){var uw=this.unitWidth;return uw&&lang.isString(uw)&&(uw=="auto"||uw.slice(-1)=="%");},applyEdit:function(_43e,_43f){this.grid.edit.applyCellEdit(_43e,this,_43f);},cancelEdit:function(_440){this.grid.doCancelEdit(_440);},_onEditBlur:function(_441){if(this.grid.edit.isEditCell(_441,this.index)){this.grid.edit.apply();}},registerOnBlur:function(_442,_443){if(this.commitOnBlur){_42b.connect(_442,"onblur",function(e){setTimeout(lang.hitch(this,"_onEditBlur",_443),250);});}},needFormatNode:function(_444,_445){this._formatPending=true;_433(this,"_formatNode",_444,_445);},cancelFormatNode:function(){this._formatPending=false;},_formatNode:function(_446,_447){if(this._formatPending){this._formatPending=false;if(!has("ie")){dom.setSelectable(this.grid.domNode,true);}this.formatNode(this.getEditNode(_447),_446,_447);}},formatNode:function(_448,_449,_44a){if(has("ie")){_433(this,"focus",_44a,_448);}else{this.focus(_44a,_448);}},dispatchEvent:function(m,e){if(m in this){return this[m](e);}},getValue:function(_44b){return this.getEditNode(_44b)[this._valueProp];},setValue:function(_44c,_44d){var n=this.getEditNode(_44c);if(n){n[this._valueProp]=_44d;}},focus:function(_44e,_44f){_431(_44f||this.getEditNode(_44e));},save:function(_450){this.value=this.value||this.getValue(_450);},restore:function(_451){this.setValue(_451,this.value);},_finish:function(_452){dom.setSelectable(this.grid.domNode,false);this.cancelFormatNode();},apply:function(_453){this.applyEdit(this.getValue(_453),_453);this._finish(_453);},cancel:function(_454){this.cancelEdit(_454);this._finish(_454);}});_434.markupFactory=function(node,_455){var _456=lang.trim(_42d.get(node,"formatter")||"");if(_456){_455.formatter=lang.getObject(_456)||_456;}var get=lang.trim(_42d.get(node,"get")||"");if(get){_455.get=lang.getObject(get);}var _457=function(attr,cell,_458){var _459=lang.trim(_42d.get(node,attr)||"");if(_459){cell[_458||attr]=!(_459.toLowerCase()=="false");}};_457("sortDesc",_455);_457("editable",_455);_457("alwaysEditing",_455);_457("noresize",_455);_457("draggable",_455);var _45a=lang.trim(_42d.get(node,"loadingText")||_42d.get(node,"defaultValue")||"");if(_45a){_455.defaultValue=_45a;}var _45b=function(attr,cell,_45c){var _45d=lang.trim(_42d.get(node,attr)||"")||undefined;if(_45d){cell[_45c||attr]=_45d;}};_45b("styles",_455);_45b("headerStyles",_455);_45b("cellStyles",_455);_45b("classes",_455);_45b("headerClasses",_455);_45b("cellClasses",_455);};var Cell=_429("dojox.grid.cells.Cell",_434,{constructor:function(){this.keyFilter=this.keyFilter;},keyFilter:null,formatEditing:function(_45e,_45f){this.needFormatNode(_45e,_45f);return "<input class=\"dojoxGridInput\" type=\"text\" value=\""+_45e+"\">";},formatNode:function(_460,_461,_462){this.inherited(arguments);this.registerOnBlur(_460,_462);},doKey:function(e){if(this.keyFilter){var key=String.fromCharCode(e.charCode);if(key.search(this.keyFilter)==-1){_42a.stop(e);}}},_finish:function(_463){this.inherited(arguments);var n=this.getEditNode(_463);try{util.fire(n,"blur");}catch(e){}}});Cell.markupFactory=function(node,_464){_434.markupFactory(node,_464);var _465=lang.trim(_42d.get(node,"keyFilter")||"");if(_465){_464.keyFilter=new RegExp(_465);}};var _466=_429("dojox.grid.cells.RowIndex",Cell,{name:"Row",postscript:function(){this.editable=false;},get:function(_467){return _467+1;}});_466.markupFactory=function(node,_468){Cell.markupFactory(node,_468);};var _469=_429("dojox.grid.cells.Select",Cell,{options:null,values:null,returnIndex:-1,constructor:function(_46a){this.values=this.values||this.options;},formatEditing:function(_46b,_46c){this.needFormatNode(_46b,_46c);var h=["<select class=\"dojoxGridSelect\">"];for(var i=0,o,v;((o=this.options[i])!==undefined)&&((v=this.values[i])!==undefined);i++){v=v.replace?v.replace(/&/g,"&amp;").replace(/</g,"&lt;"):v;o=o.replace?o.replace(/&/g,"&amp;").replace(/</g,"&lt;"):o;h.push("<option",(_46b==v?" selected":"")," value=\""+v+"\"",">",o,"</option>");}h.push("</select>");return h.join("");},_defaultFormat:function(_46d,_46e){var v=this.inherited(arguments);if(!this.formatter&&this.values&&this.options){var i=_42c.indexOf(this.values,v);if(i>=0){v=this.options[i];}}return v;},getValue:function(_46f){var n=this.getEditNode(_46f);if(n){var i=n.selectedIndex,o=n.options[i];return this.returnIndex>-1?i:o.value||o.innerHTML;}}});_469.markupFactory=function(node,cell){Cell.markupFactory(node,cell);var _470=lang.trim(_42d.get(node,"options")||"");if(_470){var o=_470.split(",");if(o[0]!=_470){cell.options=o;}}var _471=lang.trim(_42d.get(node,"values")||"");if(_471){var v=_471.split(",");if(v[0]!=_471){cell.values=v;}}};var _472=_429("dojox.grid.cells.AlwaysEdit",Cell,{alwaysEditing:true,_formatNode:function(_473,_474){this.formatNode(this.getEditNode(_474),_473,_474);},applyStaticValue:function(_475){var e=this.grid.edit;e.applyCellEdit(this.getValue(_475),this,_475);e.start(this,_475,true);}});_472.markupFactory=function(node,cell){Cell.markupFactory(node,cell);};var Bool=_429("dojox.grid.cells.Bool",_472,{_valueProp:"checked",formatEditing:function(_476,_477){return "<input class=\"dojoxGridInput\" type=\"checkbox\""+(_476?" checked=\"checked\"":"")+" style=\"width: auto\" />";},doclick:function(e){if(e.target.tagName=="INPUT"){this.applyStaticValue(e.rowIndex);}}});Bool.markupFactory=function(node,cell){_472.markupFactory(node,cell);};return _434;});},"dijit/_WidgetBase":function(){define("dijit/_WidgetBase",["require","dojo/_base/array","dojo/aspect","dojo/_base/config","dojo/_base/connect","dojo/_base/declare","dojo/dom","dojo/dom-attr","dojo/dom-class","dojo/dom-construct","dojo/dom-geometry","dojo/dom-style","dojo/_base/kernel","dojo/_base/lang","dojo/on","dojo/ready","dojo/Stateful","dojo/topic","dojo/_base/window","./registry"],function(_478,_479,_47a,_47b,_47c,_47d,dom,_47e,_47f,_480,_481,_482,_483,lang,on,_484,_485,_486,win,_487){if(!_483.isAsync){_484(0,function(){var _488=["dijit/_base/manager"];_478(_488);});}var _489={};function _48a(obj){var ret={};for(var attr in obj){ret[attr.toLowerCase()]=true;}return ret;};function _48b(attr){return function(val){_47e[val?"set":"remove"](this.domNode,attr,val);this._set(attr,val);};};return _47d("dijit._WidgetBase",_485,{id:"",_setIdAttr:"domNode",lang:"",_setLangAttr:_48b("lang"),dir:"",_setDirAttr:_48b("dir"),textDir:"","class":"",_setClassAttr:{node:"domNode",type:"class"},style:"",title:"",tooltip:"",baseClass:"",srcNodeRef:null,domNode:null,containerNode:null,attributeMap:{},_blankGif:_47b.blankGif||_478.toUrl("dojo/resources/blank.gif"),postscript:function(_48c,_48d){this.create(_48c,_48d);},create:function(_48e,_48f){this.srcNodeRef=dom.byId(_48f);this._connects=[];this._supportingWidgets=[];if(this.srcNodeRef&&(typeof this.srcNodeRef.id=="string")){this.id=this.srcNodeRef.id;}if(_48e){this.params=_48e;lang.mixin(this,_48e);}this.postMixInProperties();if(!this.id){this.id=_487.getUniqueId(this.declaredClass.replace(/\./g,"_"));}_487.add(this);this.buildRendering();if(this.domNode){this._applyAttributes();var _490=this.srcNodeRef;if(_490&&_490.parentNode&&this.domNode!==_490){_490.parentNode.replaceChild(this.domNode,_490);}}if(this.domNode){this.domNode.setAttribute("widgetId",this.id);}this.postCreate();if(this.srcNodeRef&&!this.srcNodeRef.parentNode){delete this.srcNodeRef;}this._created=true;},_applyAttributes:function(){var ctor=this.constructor,list=ctor._setterAttrs;if(!list){list=(ctor._setterAttrs=[]);for(var attr in this.attributeMap){list.push(attr);}var _491=ctor.prototype;for(var _492 in _491){if(_492 in this.attributeMap){continue;}var _493="_set"+_492.replace(/^[a-z]|-[a-zA-Z]/g,function(c){return c.charAt(c.length-1).toUpperCase();})+"Attr";if(_493 in _491){list.push(_492);}}}_479.forEach(list,function(attr){if(this.params&&attr in this.params){}else{if(this[attr]){this.set(attr,this[attr]);}}},this);for(var _494 in this.params){this.set(_494,this[_494]);}},postMixInProperties:function(){},buildRendering:function(){if(!this.domNode){this.domNode=this.srcNodeRef||_480.create("div");}if(this.baseClass){var _495=this.baseClass.split(" ");if(!this.isLeftToRight()){_495=_495.concat(_479.map(_495,function(name){return name+"Rtl";}));}_47f.add(this.domNode,_495);}},postCreate:function(){},startup:function(){if(this._started){return;}this._started=true;_479.forEach(this.getChildren(),function(obj){if(!obj._started&&!obj._destroyed&&lang.isFunction(obj.startup)){obj.startup();obj._started=true;}});},destroyRecursive:function(_496){this._beingDestroyed=true;this.destroyDescendants(_496);this.destroy(_496);},destroy:function(_497){this._beingDestroyed=true;this.uninitialize();var c;while(c=this._connects.pop()){c.remove();}var w;while(w=this._supportingWidgets.pop()){if(w.destroyRecursive){w.destroyRecursive();}else{if(w.destroy){w.destroy();}}}this.destroyRendering(_497);_487.remove(this.id);this._destroyed=true;},destroyRendering:function(_498){if(this.bgIframe){this.bgIframe.destroy(_498);delete this.bgIframe;}if(this.domNode){if(_498){_47e.remove(this.domNode,"widgetId");}else{_480.destroy(this.domNode);}delete this.domNode;}if(this.srcNodeRef){if(!_498){_480.destroy(this.srcNodeRef);}delete this.srcNodeRef;}},destroyDescendants:function(_499){_479.forEach(this.getChildren(),function(_49a){if(_49a.destroyRecursive){_49a.destroyRecursive(_499);}});},uninitialize:function(){return false;},_setStyleAttr:function(_49b){var _49c=this.domNode;if(lang.isObject(_49b)){_482.set(_49c,_49b);}else{if(_49c.style.cssText){_49c.style.cssText+="; "+_49b;}else{_49c.style.cssText=_49b;}}this._set("style",_49b);},_attrToDom:function(attr,_49d,_49e){_49e=arguments.length>=3?_49e:this.attributeMap[attr];_479.forEach(lang.isArray(_49e)?_49e:[_49e],function(_49f){var _4a0=this[_49f.node||_49f||"domNode"];var type=_49f.type||"attribute";switch(type){case "attribute":if(lang.isFunction(_49d)){_49d=lang.hitch(this,_49d);}var _4a1=_49f.attribute?_49f.attribute:(/^on[A-Z][a-zA-Z]*$/.test(attr)?attr.toLowerCase():attr);_47e.set(_4a0,_4a1,_49d);break;case "innerText":_4a0.innerHTML="";_4a0.appendChild(win.doc.createTextNode(_49d));break;case "innerHTML":_4a0.innerHTML=_49d;break;case "class":_47f.replace(_4a0,_49d,this[attr]);break;}},this);},get:function(name){var _4a2=this._getAttrNames(name);return this[_4a2.g]?this[_4a2.g]():this[name];},set:function(name,_4a3){if(typeof name==="object"){for(var x in name){this.set(x,name[x]);}return this;}var _4a4=this._getAttrNames(name),_4a5=this[_4a4.s];if(lang.isFunction(_4a5)){var _4a6=_4a5.apply(this,Array.prototype.slice.call(arguments,1));}else{var _4a7=this.focusNode&&!lang.isFunction(this.focusNode)?"focusNode":"domNode",tag=this[_4a7].tagName,_4a8=_489[tag]||(_489[tag]=_48a(this[_4a7])),map=name in this.attributeMap?this.attributeMap[name]:_4a4.s in this?this[_4a4.s]:((_4a4.l in _4a8&&typeof _4a3!="function")||/^aria-|^data-|^role$/.test(name))?_4a7:null;if(map!=null){this._attrToDom(name,_4a3,map);}this._set(name,_4a3);}return _4a6||this;},_attrPairNames:{},_getAttrNames:function(name){var apn=this._attrPairNames;if(apn[name]){return apn[name];}var uc=name.replace(/^[a-z]|-[a-zA-Z]/g,function(c){return c.charAt(c.length-1).toUpperCase();});return (apn[name]={n:name+"Node",s:"_set"+uc+"Attr",g:"_get"+uc+"Attr",l:uc.toLowerCase()});},_set:function(name,_4a9){var _4aa=this[name];this[name]=_4a9;if(this._watchCallbacks&&this._created&&_4a9!==_4aa){this._watchCallbacks(name,_4aa,_4a9);}},on:function(type,func){return _47a.after(this,this._onMap(type),func,true);},_onMap:function(type){var ctor=this.constructor,map=ctor._onMap;if(!map){map=(ctor._onMap={});for(var attr in ctor.prototype){if(/^on/.test(attr)){map[attr.replace(/^on/,"").toLowerCase()]=attr;}}}return map[type.toLowerCase()];},toString:function(){return "[Widget "+this.declaredClass+", "+(this.id||"NO ID")+"]";},getChildren:function(){return this.containerNode?_487.findWidgets(this.containerNode):[];},getParent:function(){return _487.getEnclosingWidget(this.domNode.parentNode);},connect:function(obj,_4ab,_4ac){var _4ad=_47c.connect(obj,_4ab,this,_4ac);this._connects.push(_4ad);return _4ad;},disconnect:function(_4ae){var i=_479.indexOf(this._connects,_4ae);if(i!=-1){_4ae.remove();this._connects.splice(i,1);}},subscribe:function(t,_4af){var _4b0=_486.subscribe(t,lang.hitch(this,_4af));this._connects.push(_4b0);return _4b0;},unsubscribe:function(_4b1){this.disconnect(_4b1);},isLeftToRight:function(){return this.dir?(this.dir=="ltr"):_481.isBodyLtr();},isFocusable:function(){return this.focus&&(_482.get(this.domNode,"display")!="none");},placeAt:function(_4b2,_4b3){if(_4b2.declaredClass&&_4b2.addChild){_4b2.addChild(this,_4b3);}else{_480.place(this.domNode,_4b2,_4b3);}return this;},getTextDir:function(text,_4b4){return _4b4;},applyTextDir:function(){}});});},"dojo/dnd/Moveable":function(){define(["../main","../Evented","../touch","./Mover"],function(dojo,_4b5,_4b6){dojo.declare("dojo.dnd.Moveable",[_4b5],{handle:"",delay:0,skip:false,constructor:function(node,_4b7){this.node=dojo.byId(node);if(!_4b7){_4b7={};}this.handle=_4b7.handle?dojo.byId(_4b7.handle):null;if(!this.handle){this.handle=this.node;}this.delay=_4b7.delay>0?_4b7.delay:0;this.skip=_4b7.skip;this.mover=_4b7.mover?_4b7.mover:dojo.dnd.Mover;this.events=[dojo.connect(this.handle,_4b6.press,this,"onMouseDown"),dojo.connect(this.handle,"ondragstart",this,"onSelectStart"),dojo.connect(this.handle,"onselectstart",this,"onSelectStart")];},markupFactory:function(_4b8,node,ctor){return new ctor(node,_4b8);},destroy:function(){dojo.forEach(this.events,dojo.disconnect);this.events=this.node=this.handle=null;},onMouseDown:function(e){if(this.skip&&dojo.dnd.isFormElement(e)){return;}if(this.delay){this.events.push(dojo.connect(this.handle,_4b6.move,this,"onMouseMove"),dojo.connect(this.handle,_4b6.release,this,"onMouseUp"));this._lastX=e.pageX;this._lastY=e.pageY;}else{this.onDragDetected(e);}dojo.stopEvent(e);},onMouseMove:function(e){if(Math.abs(e.pageX-this._lastX)>this.delay||Math.abs(e.pageY-this._lastY)>this.delay){this.onMouseUp(e);this.onDragDetected(e);}dojo.stopEvent(e);},onMouseUp:function(e){for(var i=0;i<2;++i){dojo.disconnect(this.events.pop());}dojo.stopEvent(e);},onSelectStart:function(e){if(!this.skip||!dojo.dnd.isFormElement(e)){dojo.stopEvent(e);}},onDragDetected:function(e){new this.mover(this.node,e,this);},onMoveStart:function(_4b9){dojo.publish("/dnd/move/start",[_4b9]);dojo.addClass(dojo.body(),"dojoMove");dojo.addClass(this.node,"dojoMoveItem");},onMoveStop:function(_4ba){dojo.publish("/dnd/move/stop",[_4ba]);dojo.removeClass(dojo.body(),"dojoMove");dojo.removeClass(this.node,"dojoMoveItem");},onFirstMove:function(_4bb,e){},onMove:function(_4bc,_4bd,e){this.onMoving(_4bc,_4bd);var s=_4bc.node.style;s.left=_4bd.l+"px";s.top=_4bd.t+"px";this.onMoved(_4bc,_4bd);},onMoving:function(_4be,_4bf){},onMoved:function(_4c0,_4c1){}});return dojo.dnd.Moveable;});}}});require(["dojo/i18n"],function(i18n){i18n._preloadLocalizations("dojox/grid/nls/DataGrid",["nl-nl","en-us","da","fi-fi","pt-pt","hu","sk","sl","pl","ca","sv","zh-tw","ar","en-gb","he-il","de-de","ko-kr","ja-jp","nb","ru","es-es","th","cs","it-it","pt-br","fr-fr","el","tr","zh-cn"]);});define("dojox/grid/DataGrid",["../main","dojo/_base/array","dojo/_base/lang","dojo/_base/json","dojo/_base/sniff","dojo/_base/declare","./_Grid","./DataSelection","dojo/_base/html"],function(_4c2,_4c3,lang,json,has,_4c4,_4c5,_4c6,html){var _4c7=_4c4("dojox.grid.DataGrid",_4c5,{store:null,query:null,queryOptions:null,fetchText:"...",sortFields:null,updateDelay:1,items:null,_store_connects:null,_by_idty:null,_by_idx:null,_cache:null,_pages:null,_pending_requests:null,_bop:-1,_eop:-1,_requests:0,rowCount:0,_isLoaded:false,_isLoading:false,keepSelection:false,postCreate:function(){this._pages=[];this._store_connects=[];this._by_idty={};this._by_idx=[];this._cache=[];this._pending_requests={};this._setStore(this.store);this.inherited(arguments);},destroy:function(){this.selection.destroy();this.inherited(arguments);},createSelection:function(){this.selection=new _4c6(this);},get:function(_4c8,_4c9){if(_4c9&&this.field=="_item"&&!this.fields){return _4c9;}else{if(_4c9&&this.fields){var ret=[];var s=this.grid.store;_4c3.forEach(this.fields,function(f){ret=ret.concat(s.getValues(_4c9,f));});return ret;}else{if(!_4c9&&typeof _4c8==="string"){return this.inherited(arguments);}}}return (!_4c9?this.defaultValue:(!this.field?this.value:(this.field=="_item"?_4c9:this.grid.store.getValue(_4c9,this.field))));},_checkUpdateStatus:function(){if(this.updateDelay>0){var _4ca=false;if(this._endUpdateDelay){clearTimeout(this._endUpdateDelay);delete this._endUpdateDelay;_4ca=true;}if(!this.updating){this.beginUpdate();_4ca=true;}if(_4ca){var _4cb=this;this._endUpdateDelay=setTimeout(function(){delete _4cb._endUpdateDelay;_4cb.endUpdate();},this.updateDelay);}}},_onSet:function(item,_4cc,_4cd,_4ce){this._checkUpdateStatus();var idx=this.getItemIndex(item);if(idx>-1){this.updateRow(idx);}},_createItem:function(item,_4cf){var idty=this._hasIdentity?this.store.getIdentity(item):json.toJson(this.query)+":idx:"+_4cf+":sort:"+json.toJson(this.getSortProps());var o=this._by_idty[idty]={idty:idty,item:item};return o;},_addItem:function(item,_4d0,_4d1){this._by_idx[_4d0]=this._createItem(item,_4d0);if(!_4d1){this.updateRow(_4d0);}},_onNew:function(item,_4d2){this._checkUpdateStatus();var _4d3=this.get("rowCount");this._addingItem=true;this.updateRowCount(_4d3+1);this._addingItem=false;this._addItem(item,_4d3);this.showMessage();},_onDelete:function(item){this._checkUpdateStatus();var idx=this._getItemIndex(item,true);if(idx>=0){this._pages=[];this._bop=-1;this._eop=-1;var o=this._by_idx[idx];this._by_idx.splice(idx,1);delete this._by_idty[o.idty];this.updateRowCount(this.get("rowCount")-1);if(this.get("rowCount")===0){this.showMessage(this.noDataMessage);}}if(this.selection.isSelected(idx)){this.selection.deselect(idx);this.selection.selected.splice(idx,1);}},_onRevert:function(){this._refresh();},setStore:function(_4d4,_4d5,_4d6){if(this._requestsPending(0)){return;}this._setQuery(_4d5,_4d6);this._setStore(_4d4);this._refresh(true);},setQuery:function(_4d7,_4d8){if(this._requestsPending(0)){return;}this._setQuery(_4d7,_4d8);this._refresh(true);},setItems:function(_4d9){this.items=_4d9;this._setStore(this.store);this._refresh(true);},_setQuery:function(_4da,_4db){this.query=_4da;this.queryOptions=_4db||this.queryOptions;},_setStore:function(_4dc){if(this.store&&this._store_connects){_4c3.forEach(this._store_connects,this.disconnect,this);}this.store=_4dc;if(this.store){var f=this.store.getFeatures();var h=[];this._canEdit=!!f["dojo.data.api.Write"]&&!!f["dojo.data.api.Identity"];this._hasIdentity=!!f["dojo.data.api.Identity"];if(!!f["dojo.data.api.Notification"]&&!this.items){h.push(this.connect(this.store,"onSet","_onSet"));h.push(this.connect(this.store,"onNew","_onNew"));h.push(this.connect(this.store,"onDelete","_onDelete"));}if(this._canEdit){h.push(this.connect(this.store,"revert","_onRevert"));}this._store_connects=h;}},_onFetchBegin:function(size,req){if(!this.scroller){return;}if(this.rowCount!=size){if(req.isRender){this.scroller.init(size,this.keepRows,this.rowsPerPage);this.rowCount=size;this._setAutoHeightAttr(this.autoHeight,true);this._skipRowRenormalize=true;this.prerender();this._skipRowRenormalize=false;}else{this.updateRowCount(size);}}if(!size){this.views.render();this._resize();this.showMessage(this.noDataMessage);this.focus.initFocusView();}else{this.showMessage();}},_onFetchComplete:function(_4dd,req){if(!this.scroller){return;}if(_4dd&&_4dd.length>0){_4c3.forEach(_4dd,function(item,idx){this._addItem(item,req.start+idx,true);},this);this.updateRows(req.start,_4dd.length);if(req.isRender){this.setScrollTop(0);this.postrender();}else{if(this._lastScrollTop){this.setScrollTop(this._lastScrollTop);}}if(has("ie")){html.setSelectable(this.domNode,this.selectable);}}delete this._lastScrollTop;if(!this._isLoaded){this._isLoading=false;this._isLoaded=true;}this._pending_requests[req.start]=false;},_onFetchError:function(err,req){delete this._lastScrollTop;if(!this._isLoaded){this._isLoading=false;this._isLoaded=true;this.showMessage(this.errorMessage);}this._pending_requests[req.start]=false;this.onFetchError(err,req);},onFetchError:function(err,req){},_fetch:function(_4de,_4df){_4de=_4de||0;if(this.store&&!this._pending_requests[_4de]){if(!this._isLoaded&&!this._isLoading){this._isLoading=true;this.showMessage(this.loadingMessage);}this._pending_requests[_4de]=true;try{if(this.items){var _4e0=this.items;var _4e1=this.store;this.rowsPerPage=_4e0.length;var req={start:_4de,count:this.rowsPerPage,isRender:_4df};this._onFetchBegin(_4e0.length,req);var _4e2=0;_4c3.forEach(_4e0,function(i){if(!_4e1.isItemLoaded(i)){_4e2++;}});if(_4e2===0){this._onFetchComplete(_4e0,req);}else{var _4e3=function(item){_4e2--;if(_4e2===0){this._onFetchComplete(_4e0,req);}};_4c3.forEach(_4e0,function(i){if(!_4e1.isItemLoaded(i)){_4e1.loadItem({item:i,onItem:_4e3,scope:this});}},this);}}else{this.store.fetch({start:_4de,count:this.rowsPerPage,query:this.query,sort:this.getSortProps(),queryOptions:this.queryOptions,isRender:_4df,onBegin:lang.hitch(this,"_onFetchBegin"),onComplete:lang.hitch(this,"_onFetchComplete"),onError:lang.hitch(this,"_onFetchError")});}}catch(e){this._onFetchError(e,{start:_4de,count:this.rowsPerPage});}}},_clearData:function(){this.updateRowCount(0);this._by_idty={};this._by_idx=[];this._pages=[];this._bop=this._eop=-1;this._isLoaded=false;this._isLoading=false;},getItem:function(idx){var data=this._by_idx[idx];if(!data||(data&&!data.item)){this._preparePage(idx);return null;}return data.item;},getItemIndex:function(item){return this._getItemIndex(item,false);},_getItemIndex:function(item,_4e4){if(!_4e4&&!this.store.isItem(item)){return -1;}var idty=this._hasIdentity?this.store.getIdentity(item):null;for(var i=0,l=this._by_idx.length;i<l;i++){var d=this._by_idx[i];if(d&&((idty&&d.idty==idty)||(d.item===item))){return i;}}return -1;},filter:function(_4e5,_4e6){this.query=_4e5;if(_4e6){this._clearData();}this._fetch();},_getItemAttr:function(idx,attr){var item=this.getItem(idx);return (!item?this.fetchText:this.store.getValue(item,attr));},_render:function(){if(this.domNode.parentNode){this.scroller.init(this.get("rowCount"),this.keepRows,this.rowsPerPage);this.prerender();this._fetch(0,true);}},_requestsPending:function(_4e7){return this._pending_requests[_4e7];},_rowToPage:function(_4e8){return (this.rowsPerPage?Math.floor(_4e8/this.rowsPerPage):_4e8);},_pageToRow:function(_4e9){return (this.rowsPerPage?this.rowsPerPage*_4e9:_4e9);},_preparePage:function(_4ea){if((_4ea<this._bop||_4ea>=this._eop)&&!this._addingItem){var _4eb=this._rowToPage(_4ea);this._needPage(_4eb);this._bop=_4eb*this.rowsPerPage;this._eop=this._bop+(this.rowsPerPage||this.get("rowCount"));}},_needPage:function(_4ec){if(!this._pages[_4ec]){this._pages[_4ec]=true;this._requestPage(_4ec);}},_requestPage:function(_4ed){var row=this._pageToRow(_4ed);var _4ee=Math.min(this.rowsPerPage,this.get("rowCount")-row);if(_4ee>0){this._requests++;if(!this._requestsPending(row)){setTimeout(lang.hitch(this,"_fetch",row,false),1);}}},getCellName:function(_4ef){return _4ef.field;},_refresh:function(_4f0){this._clearData();this._fetch(0,_4f0);},sort:function(){this.edit.apply();this._lastScrollTop=this.scrollTop;this._refresh();},canSort:function(){return (!this._isLoading);},getSortProps:function(){var c=this.getCell(this.getSortIndex());if(!c){if(this.sortFields){return this.sortFields;}return null;}else{var desc=c["sortDesc"];var si=!(this.sortInfo>0);if(typeof desc=="undefined"){desc=si;}else{desc=si?!desc:desc;}return [{attribute:c.field,descending:desc}];}},styleRowState:function(_4f1){if(this.store&&this.store.getState){var _4f2=this.store.getState(_4f1.index),c="";for(var i=0,ss=["inflight","error","inserting"],s;s=ss[i];i++){if(_4f2[s]){c=" dojoxGridRow-"+s;break;}}_4f1.customClasses+=c;}},onStyleRow:function(_4f3){this.styleRowState(_4f3);this.inherited(arguments);},canEdit:function(_4f4,_4f5){return this._canEdit;},_copyAttr:function(idx,attr){var row={};var _4f6={};var src=this.getItem(idx);return this.store.getValue(src,attr);},doStartEdit:function(_4f7,_4f8){if(!this._cache[_4f8]){this._cache[_4f8]=this._copyAttr(_4f8,_4f7.field);}this.onStartEdit(_4f7,_4f8);},doApplyCellEdit:function(_4f9,_4fa,_4fb){this.store.fetchItemByIdentity({identity:this._by_idx[_4fa].idty,onItem:lang.hitch(this,function(item){var _4fc=this.store.getValue(item,_4fb);if(typeof _4fc=="number"){_4f9=isNaN(_4f9)?_4f9:parseFloat(_4f9);}else{if(typeof _4fc=="boolean"){_4f9=_4f9=="true"?true:_4f9=="false"?false:_4f9;}else{if(_4fc instanceof Date){var _4fd=new Date(_4f9);_4f9=isNaN(_4fd.getTime())?_4f9:_4fd;}}}this.store.setValue(item,_4fb,_4f9);this.onApplyCellEdit(_4f9,_4fa,_4fb);})});},doCancelEdit:function(_4fe){var _4ff=this._cache[_4fe];if(_4ff){this.updateRow(_4fe);delete this._cache[_4fe];}this.onCancelEdit.apply(this,arguments);},doApplyEdit:function(_500,_501){var _502=this._cache[_500];this.onApplyEdit(_500);},removeSelectedRows:function(){if(this._canEdit){this.edit.apply();var fx=lang.hitch(this,function(_503){if(_503.length){_4c3.forEach(_503,this.store.deleteItem,this.store);this.selection.clear();}});if(this.allItemsSelected){this.store.fetch({query:this.query,queryOptions:this.queryOptions,onComplete:fx});}else{fx(this.selection.getSelected());}}}});_4c7.cell_markupFactory=function(_504,node,_505){var _506=lang.trim(html.attr(node,"field")||"");if(_506){_505.field=_506;}_505.field=_505.field||_505.name;var _507=lang.trim(html.attr(node,"fields")||"");if(_507){_505.fields=_507.split(",");}if(_504){_504(node,_505);}};_4c7.markupFactory=function(_508,node,ctor,_509){return _4c5.markupFactory(_508,node,ctor,lang.partial(_4c7.cell_markupFactory,_509));};return _4c7;}); \ No newline at end of file
diff --git a/js/dojo-1.7.2/dojox/grid/DataGrid.js.uncompressed.js b/js/dojo-1.7.2/dojox/grid/DataGrid.js.uncompressed.js
new file mode 100644
index 0000000..de77929
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/DataGrid.js.uncompressed.js
@@ -0,0 +1,14486 @@
+/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+/*
+ This is an optimized version of Dojo, built for deployment and not for
+ development. To get sources and documentation, please visit:
+
+ http://dojotoolkit.org
+*/
+
+//>>built
+require({cache:{
+'dojo/uacss':function(){
+define(["./dom-geometry", "./_base/lang", "./ready", "./_base/sniff", "./_base/window"],
+ function(geometry, lang, ready, has, baseWindow){
+ // module:
+ // dojo/uacss
+ // summary:
+ // Applies pre-set CSS classes to the top-level HTML node, based on:
+ // - browser (ex: dj_ie)
+ // - browser version (ex: dj_ie6)
+ // - box model (ex: dj_contentBox)
+ // - text direction (ex: dijitRtl)
+ //
+ // In addition, browser, browser version, and box model are
+ // combined with an RTL flag when browser text is RTL. ex: dj_ie-rtl.
+
+ var
+ html = baseWindow.doc.documentElement,
+ ie = has("ie"),
+ opera = has("opera"),
+ maj = Math.floor,
+ ff = has("ff"),
+ boxModel = geometry.boxModel.replace(/-/,''),
+
+ classes = {
+ "dj_ie": ie,
+ "dj_ie6": maj(ie) == 6,
+ "dj_ie7": maj(ie) == 7,
+ "dj_ie8": maj(ie) == 8,
+ "dj_ie9": maj(ie) == 9,
+ "dj_quirks": has("quirks"),
+ "dj_iequirks": ie && has("quirks"),
+
+ // NOTE: Opera not supported by dijit
+ "dj_opera": opera,
+
+ "dj_khtml": has("khtml"),
+
+ "dj_webkit": has("webkit"),
+ "dj_safari": has("safari"),
+ "dj_chrome": has("chrome"),
+
+ "dj_gecko": has("mozilla"),
+ "dj_ff3": maj(ff) == 3
+ }; // no dojo unsupported browsers
+
+ classes["dj_" + boxModel] = true;
+
+ // apply browser, browser version, and box model class names
+ var classStr = "";
+ for(var clz in classes){
+ if(classes[clz]){
+ classStr += clz + " ";
+ }
+ }
+ html.className = lang.trim(html.className + " " + classStr);
+
+ // If RTL mode, then add dj_rtl flag plus repeat existing classes with -rtl extension.
+ // We can't run the code below until the <body> tag has loaded (so we can check for dir=rtl).
+ // priority is 90 to run ahead of parser priority of 100
+ ready(90, function(){
+ if(!geometry.isBodyLtr()){
+ var rtlClassStr = "dj_rtl dijitRtl " + classStr.replace(/ /g, "-rtl ");
+ html.className = lang.trim(html.className + " " + rtlClassStr + "dj_rtl dijitRtl " + classStr.replace(/ /g, "-rtl "));
+ }
+ });
+ return has;
+});
+
+},
+'dijit/hccss':function(){
+define("dijit/hccss", [
+ "require", // require.toUrl
+ "dojo/_base/config", // config.blankGif
+ "dojo/dom-class", // domClass.add domConstruct.create domStyle.getComputedStyle
+ "dojo/dom-construct", // domClass.add domConstruct.create domStyle.getComputedStyle
+ "dojo/dom-style", // domClass.add domConstruct.create domStyle.getComputedStyle
+ "dojo/ready", // ready
+ "dojo/_base/sniff", // has("ie") has("mozilla")
+ "dojo/_base/window" // win.body
+], function(require, config, domClass, domConstruct, domStyle, ready, has, win){
+
+ // module:
+ // dijit/hccss
+ // summary:
+ // Test if computer is in high contrast mode, and sets dijit_a11y flag on <body> if it is.
+
+ if(has("ie") || has("mozilla")){ // NOTE: checking in Safari messes things up
+ // priority is 90 to run ahead of parser priority of 100
+ ready(90, function(){
+ // summary:
+ // Detects if we are in high-contrast mode or not
+
+ // create div for testing if high contrast mode is on or images are turned off
+ var div = domConstruct.create("div",{
+ id: "a11yTestNode",
+ style:{
+ cssText:'border: 1px solid;'
+ + 'border-color:red green;'
+ + 'position: absolute;'
+ + 'height: 5px;'
+ + 'top: -999px;'
+ + 'background-image: url("' + (config.blankGif || require.toUrl("dojo/resources/blank.gif")) + '");'
+ }
+ }, win.body());
+
+ // test it
+ var cs = domStyle.getComputedStyle(div);
+ if(cs){
+ var bkImg = cs.backgroundImage;
+ var needsA11y = (cs.borderTopColor == cs.borderRightColor) || (bkImg != null && (bkImg == "none" || bkImg == "url(invalid-url:)" ));
+ if(needsA11y){
+ domClass.add(win.body(), "dijit_a11y");
+ }
+ if(has("ie")){
+ div.outerHTML = ""; // prevent mixed-content warning, see http://support.microsoft.com/kb/925014
+ }else{
+ win.body().removeChild(div);
+ }
+ }
+ });
+ }
+});
+
+},
+'dojox/grid/_View':function(){
+require({cache:{
+'url:dojox/grid/resources/View.html':"<div class=\"dojoxGridView\" role=\"presentation\">\n\t<div class=\"dojoxGridHeader\" dojoAttachPoint=\"headerNode\" role=\"presentation\">\n\t\t<div dojoAttachPoint=\"headerNodeContainer\" style=\"width:9000em\" role=\"presentation\">\n\t\t\t<div dojoAttachPoint=\"headerContentNode\" role=\"row\"></div>\n\t\t</div>\n\t</div>\n\t<input type=\"checkbox\" class=\"dojoxGridHiddenFocus\" dojoAttachPoint=\"hiddenFocusNode\" role=\"presentation\" />\n\t<input type=\"checkbox\" class=\"dojoxGridHiddenFocus\" role=\"presentation\" />\n\t<div class=\"dojoxGridScrollbox\" dojoAttachPoint=\"scrollboxNode\" role=\"presentation\">\n\t\t<div class=\"dojoxGridContent\" dojoAttachPoint=\"contentNode\" hidefocus=\"hidefocus\" role=\"presentation\"></div>\n\t</div>\n</div>\n"}});
+define("dojox/grid/_View", [
+ "dojo",
+ "dijit/registry",
+ "../main",
+ "dojo/_base/declare",
+ "dojo/_base/array",
+ "dojo/_base/lang",
+ "dojo/_base/connect",
+ "dojo/_base/sniff",
+ "dojo/query",
+ "dojo/_base/window",
+ "dojo/text!./resources/View.html",
+ "dojo/dnd/Source",
+ "dijit/_Widget",
+ "dijit/_TemplatedMixin",
+ "dojox/html/metrics",
+ "./util",
+ "dojo/_base/html",
+ "./_Builder",
+ "dojo/dnd/Avatar",
+ "dojo/dnd/Manager"
+], function(dojo, dijit, dojox, declare, array, lang, connect, has, query,
+ win, template, Source, _Widget, _TemplatedMixin, metrics, util, html, _Builder, Avatar){
+
+ // a private function
+ var getStyleText = function(inNode, inStyleText){
+ return inNode.style.cssText == undefined ? inNode.getAttribute("style") : inNode.style.cssText;
+ };
+
+ // some public functions
+ var _View = declare('dojox.grid._View', [_Widget, _TemplatedMixin], {
+ // summary:
+ // A collection of grid columns. A grid is comprised of a set of views that stack horizontally.
+ // Grid creates views automatically based on grid's layout structure.
+ // Users should typically not need to access individual views directly.
+ //
+ // defaultWidth: String
+ // Default width of the view
+ defaultWidth: "18em",
+
+ // viewWidth: String
+ // Width for the view, in valid css unit
+ viewWidth: "",
+
+ templateString: template,
+
+ themeable: false,
+ classTag: 'dojoxGrid',
+ marginBottom: 0,
+ rowPad: 2,
+
+ // _togglingColumn: int
+ // Width of the column being toggled (-1 for none)
+ _togglingColumn: -1,
+
+ // _headerBuilderClass: Object
+ // The class to use for our header builder
+ _headerBuilderClass: _Builder._HeaderBuilder,
+
+ // _contentBuilderClass: Object
+ // The class to use for our content builder
+ _contentBuilderClass: _Builder._ContentBuilder,
+
+ postMixInProperties: function(){
+ this.rowNodes = {};
+ },
+
+ postCreate: function(){
+ this.connect(this.scrollboxNode,"onscroll","doscroll");
+ util.funnelEvents(this.contentNode, this, "doContentEvent", [ 'mouseover', 'mouseout', 'click', 'dblclick', 'contextmenu', 'mousedown' ]);
+ util.funnelEvents(this.headerNode, this, "doHeaderEvent", [ 'dblclick', 'mouseover', 'mouseout', 'mousemove', 'mousedown', 'click', 'contextmenu' ]);
+ this.content = new this._contentBuilderClass(this);
+ this.header = new this._headerBuilderClass(this);
+ //BiDi: in RTL case, style width='9000em' causes scrolling problem in head node
+ if(!this.grid.isLeftToRight()){
+ this.headerNodeContainer.style.width = "";
+ }
+ },
+
+ destroy: function(){
+ html.destroy(this.headerNode);
+ delete this.headerNode;
+ for(var i in this.rowNodes){
+ this._cleanupRowWidgets(this.rowNodes[i]);
+ html.destroy(this.rowNodes[i]);
+ }
+ this.rowNodes = {};
+ if(this.source){
+ this.source.destroy();
+ }
+ this.inherited(arguments);
+ },
+
+ // focus
+ focus: function(){
+ if(has("ie") || has("webkit") || has("opera")){
+ this.hiddenFocusNode.focus();
+ }else{
+ this.scrollboxNode.focus();
+ }
+ },
+
+ setStructure: function(inStructure){
+ var vs = (this.structure = inStructure);
+ // FIXME: similar logic is duplicated in layout
+ if(vs.width && !isNaN(vs.width)){
+ this.viewWidth = vs.width + 'em';
+ }else{
+ this.viewWidth = vs.width || (vs.noscroll ? 'auto' : this.viewWidth); //|| this.defaultWidth;
+ }
+ this._onBeforeRow = vs.onBeforeRow||function(){};
+ this._onAfterRow = vs.onAfterRow||function(){};
+ this.noscroll = vs.noscroll;
+ if(this.noscroll){
+ this.scrollboxNode.style.overflow = "hidden";
+ }
+ this.simpleStructure = Boolean(vs.cells.length == 1);
+ // bookkeeping
+ this.testFlexCells();
+ // accomodate new structure
+ this.updateStructure();
+ },
+
+ _cleanupRowWidgets: function(inRowNode){
+ // Summary:
+ // Cleans up the widgets for the given row node so that
+ // we can reattach them if needed
+ if(inRowNode){
+ array.forEach(query("[widgetId]", inRowNode).map(dijit.byNode), function(w){
+ if(w._destroyOnRemove){
+ w.destroy();
+ delete w;
+ }else if(w.domNode && w.domNode.parentNode){
+ w.domNode.parentNode.removeChild(w.domNode);
+ }
+ });
+ }
+ },
+
+ onBeforeRow: function(inRowIndex, cells){
+ this._onBeforeRow(inRowIndex, cells);
+ if(inRowIndex >= 0){
+ this._cleanupRowWidgets(this.getRowNode(inRowIndex));
+ }
+ },
+
+ onAfterRow: function(inRowIndex, cells, inRowNode){
+ this._onAfterRow(inRowIndex, cells, inRowNode);
+ var g = this.grid;
+ array.forEach(query(".dojoxGridStubNode", inRowNode), function(n){
+ if(n && n.parentNode){
+ var lw = n.getAttribute("linkWidget");
+ var cellIdx = window.parseInt(html.attr(n, "cellIdx"), 10);
+ var cellDef = g.getCell(cellIdx);
+ var w = dijit.byId(lw);
+ if(w){
+ n.parentNode.replaceChild(w.domNode, n);
+ if(!w._started){
+ w.startup();
+ }
+ dojo.destroy(n);
+ }else{
+ n.innerHTML = "";
+ }
+ }
+ }, this);
+ },
+
+ testFlexCells: function(){
+ // FIXME: cheater, this function does double duty as initializer and tester
+ this.flexCells = false;
+ for(var j=0, row; (row=this.structure.cells[j]); j++){
+ for(var i=0, cell; (cell=row[i]); i++){
+ cell.view = this;
+ this.flexCells = this.flexCells || cell.isFlex();
+ }
+ }
+ return this.flexCells;
+ },
+
+ updateStructure: function(){
+ // header builder needs to update table map
+ this.header.update();
+ // content builder needs to update markup cache
+ this.content.update();
+ },
+
+ getScrollbarWidth: function(){
+ var hasScrollSpace = this.hasVScrollbar();
+ var overflow = html.style(this.scrollboxNode, "overflow");
+ if(this.noscroll || !overflow || overflow == "hidden"){
+ hasScrollSpace = false;
+ }else if(overflow == "scroll"){
+ hasScrollSpace = true;
+ }
+ return (hasScrollSpace ? metrics.getScrollbar().w : 0); // Integer
+ },
+
+ getColumnsWidth: function(){
+ var h = this.headerContentNode;
+ return h && h.firstChild ? h.firstChild.offsetWidth : 0; // Integer
+ },
+
+ setColumnsWidth: function(width){
+ this.headerContentNode.firstChild.style.width = width + 'px';
+ if(this.viewWidth){
+ this.viewWidth = width + 'px';
+ }
+ },
+
+ getWidth: function(){
+ return this.viewWidth || (this.getColumnsWidth()+this.getScrollbarWidth()) +'px'; // String
+ },
+
+ getContentWidth: function(){
+ return Math.max(0, html._getContentBox(this.domNode).w - this.getScrollbarWidth()) + 'px'; // String
+ },
+
+ render: function(){
+ this.scrollboxNode.style.height = '';
+ this.renderHeader();
+ if(this._togglingColumn >= 0){
+ this.setColumnsWidth(this.getColumnsWidth() - this._togglingColumn);
+ this._togglingColumn = -1;
+ }
+ var cells = this.grid.layout.cells;
+ var getSibling = lang.hitch(this, function(node, before){
+ !this.grid.isLeftToRight() && (before = !before);
+ var inc = before?-1:1;
+ var idx = this.header.getCellNodeIndex(node) + inc;
+ var cell = cells[idx];
+ while(cell && cell.getHeaderNode() && cell.getHeaderNode().style.display == "none"){
+ idx += inc;
+ cell = cells[idx];
+ }
+ if(cell){
+ return cell.getHeaderNode();
+ }
+ return null;
+ });
+ if(this.grid.columnReordering && this.simpleStructure){
+ if(this.source){
+ this.source.destroy();
+ }
+
+ // Create the top and bottom markers
+ var bottomMarkerId = "dojoxGrid_bottomMarker";
+ var topMarkerId = "dojoxGrid_topMarker";
+ if(this.bottomMarker){
+ html.destroy(this.bottomMarker);
+ }
+ this.bottomMarker = html.byId(bottomMarkerId);
+ if(this.topMarker){
+ html.destroy(this.topMarker);
+ }
+ this.topMarker = html.byId(topMarkerId);
+ if (!this.bottomMarker) {
+ this.bottomMarker = html.create("div", {
+ "id": bottomMarkerId,
+ "class": "dojoxGridColPlaceBottom"
+ }, win.body());
+ this._hide(this.bottomMarker);
+
+
+ this.topMarker = html.create("div", {
+ "id": topMarkerId,
+ "class": "dojoxGridColPlaceTop"
+ }, win.body());
+ this._hide(this.topMarker);
+ }
+ this.arrowDim = html.contentBox(this.bottomMarker);
+
+ var headerHeight = html.contentBox(this.headerContentNode.firstChild.rows[0]).h;
+
+ this.source = new Source(this.headerContentNode.firstChild.rows[0], {
+ horizontal: true,
+ accept: [ "gridColumn_" + this.grid.id ],
+ viewIndex: this.index,
+ generateText: false,
+ onMouseDown: lang.hitch(this, function(e){
+ this.header.decorateEvent(e);
+ if((this.header.overRightResizeArea(e) || this.header.overLeftResizeArea(e)) &&
+ this.header.canResize(e) && !this.header.moveable){
+ this.header.beginColumnResize(e);
+ }else{
+ if(this.grid.headerMenu){
+ this.grid.headerMenu.onCancel(true);
+ }
+ // IE reports a left click as 1, where everything else reports 0
+ if(e.button === (has("ie") < 9 ? 1 : 0)){
+ Source.prototype.onMouseDown.call(this.source, e);
+ }
+ }
+ }),
+ onMouseOver: lang.hitch(this, function(e){
+ var src = this.source;
+ if(src._getChildByEvent(e)){
+ Source.prototype.onMouseOver.apply(src, arguments);
+ }
+ }),
+ _markTargetAnchor: lang.hitch(this, function(before){
+ var src = this.source;
+ if(src.current == src.targetAnchor && src.before == before){ return; }
+ if(src.targetAnchor && getSibling(src.targetAnchor, src.before)){
+ src._removeItemClass(getSibling(src.targetAnchor, src.before), src.before ? "After" : "Before");
+ }
+ Source.prototype._markTargetAnchor.call(src, before);
+
+ var target = before ? src.targetAnchor : getSibling(src.targetAnchor, src.before);
+ var endAdd = 0;
+
+ if (!target) {
+ target = src.targetAnchor;
+ endAdd = html.contentBox(target).w + this.arrowDim.w/2 + 2;
+ }
+
+ var pos = html.position(target, true);
+ var left = Math.floor(pos.x - this.arrowDim.w/2 + endAdd);
+
+ html.style(this.bottomMarker, "visibility", "visible");
+ html.style(this.topMarker, "visibility", "visible");
+ html.style(this.bottomMarker, {
+ "left": left + "px",
+ "top" : (headerHeight + pos.y) + "px"
+ });
+
+ html.style(this.topMarker, {
+ "left": left + "px",
+ "top" : (pos.y - this.arrowDim.h) + "px"
+ });
+
+ if(src.targetAnchor && getSibling(src.targetAnchor, src.before)){
+ src._addItemClass(getSibling(src.targetAnchor, src.before), src.before ? "After" : "Before");
+ }
+ }),
+ _unmarkTargetAnchor: lang.hitch(this, function(){
+ var src = this.source;
+ if(!src.targetAnchor){ return; }
+ if(src.targetAnchor && getSibling(src.targetAnchor, src.before)){
+ src._removeItemClass(getSibling(src.targetAnchor, src.before), src.before ? "After" : "Before");
+ }
+ this._hide(this.bottomMarker);
+ this._hide(this.topMarker);
+ Source.prototype._unmarkTargetAnchor.call(src);
+ }),
+ destroy: lang.hitch(this, function(){
+ connect.disconnect(this._source_conn);
+ connect.unsubscribe(this._source_sub);
+ Source.prototype.destroy.call(this.source);
+ if(this.bottomMarker){
+ html.destroy(this.bottomMarker);
+ delete this.bottomMarker;
+ }
+ if(this.topMarker){
+ html.destroy(this.topMarker);
+ delete this.topMarker;
+ }
+ }),
+ onDndCancel: lang.hitch(this, function(){
+ Source.prototype.onDndCancel.call(this.source);
+ this._hide(this.bottomMarker);
+ this._hide(this.topMarker);
+ })
+ });
+
+ this._source_conn = connect.connect(this.source, "onDndDrop", this, "_onDndDrop");
+ this._source_sub = connect.subscribe("/dnd/drop/before", this, "_onDndDropBefore");
+ this.source.startup();
+ }
+ },
+
+ _hide: function(node){
+ html.style(node, {
+ top: "-10000px",
+ "visibility": "hidden"
+ });
+ },
+
+ _onDndDropBefore: function(source, nodes, copy){
+ if(dojo.dnd.manager().target !== this.source){
+ return;
+ }
+ this.source._targetNode = this.source.targetAnchor;
+ this.source._beforeTarget = this.source.before;
+ var views = this.grid.views.views;
+ var srcView = views[source.viewIndex];
+ var tgtView = views[this.index];
+ if(tgtView != srcView){
+ srcView.convertColPctToFixed();
+ tgtView.convertColPctToFixed();
+ }
+ },
+
+ _onDndDrop: function(source, nodes, copy){
+ if(dojo.dnd.manager().target !== this.source){
+ if(dojo.dnd.manager().source === this.source){
+ this._removingColumn = true;
+ }
+ return;
+ }
+ this._hide(this.bottomMarker);
+ this._hide(this.topMarker);
+
+ var getIdx = function(n){
+ return n ? html.attr(n, "idx") : null;
+ };
+ var w = html.marginBox(nodes[0]).w;
+ if(source.viewIndex !== this.index){
+ var views = this.grid.views.views;
+ var srcView = views[source.viewIndex];
+ var tgtView = views[this.index];
+ if(srcView.viewWidth && srcView.viewWidth != "auto"){
+ srcView.setColumnsWidth(srcView.getColumnsWidth() - w);
+ }
+ if(tgtView.viewWidth && tgtView.viewWidth != "auto"){
+ tgtView.setColumnsWidth(tgtView.getColumnsWidth());
+ }
+ }
+ var stn = this.source._targetNode;
+ var stb = this.source._beforeTarget;
+ !this.grid.isLeftToRight() && (stb = !stb);
+ var layout = this.grid.layout;
+ var idx = this.index;
+ delete this.source._targetNode;
+ delete this.source._beforeTarget;
+
+ layout.moveColumn(
+ source.viewIndex,
+ idx,
+ getIdx(nodes[0]),
+ getIdx(stn),
+ stb);
+ },
+
+ renderHeader: function(){
+ this.headerContentNode.innerHTML = this.header.generateHtml(this._getHeaderContent);
+ if(this.flexCells){
+ this.contentWidth = this.getContentWidth();
+ this.headerContentNode.firstChild.style.width = this.contentWidth;
+ }
+ util.fire(this, "onAfterRow", [-1, this.structure.cells, this.headerContentNode]);
+ },
+
+ // note: not called in 'view' context
+ _getHeaderContent: function(inCell){
+ var n = inCell.name || inCell.grid.getCellName(inCell);
+ if(/^\s+$/.test(n)){
+ n = '&nbsp;'//otherwise arrow styles will be messed up
+ }
+ var ret = [ '<div class="dojoxGridSortNode' ];
+
+ if(inCell.index != inCell.grid.getSortIndex()){
+ ret.push('">');
+ }else{
+ ret = ret.concat([ ' ',
+ inCell.grid.sortInfo > 0 ? 'dojoxGridSortUp' : 'dojoxGridSortDown',
+ '"><div class="dojoxGridArrowButtonChar">',
+ inCell.grid.sortInfo > 0 ? '&#9650;' : '&#9660;',
+ '</div><div class="dojoxGridArrowButtonNode" role="presentation"></div>',
+ '<div class="dojoxGridColCaption">']);
+ }
+ ret = ret.concat([n, '</div></div>']);
+ return ret.join('');
+ },
+
+ resize: function(){
+ this.adaptHeight();
+ this.adaptWidth();
+ },
+
+ hasHScrollbar: function(reset){
+ var hadScroll = this._hasHScroll||false;
+ if(this._hasHScroll == undefined || reset){
+ if(this.noscroll){
+ this._hasHScroll = false;
+ }else{
+ var style = html.style(this.scrollboxNode, "overflow");
+ if(style == "hidden"){
+ this._hasHScroll = false;
+ }else if(style == "scroll"){
+ this._hasHScroll = true;
+ }else{
+ this._hasHScroll = (this.scrollboxNode.offsetWidth - this.getScrollbarWidth() < this.contentNode.offsetWidth );
+ }
+ }
+ }
+ if(hadScroll !== this._hasHScroll){
+ this.grid.update();
+ }
+ return this._hasHScroll; // Boolean
+ },
+
+ hasVScrollbar: function(reset){
+ var hadScroll = this._hasVScroll||false;
+ if(this._hasVScroll == undefined || reset){
+ if(this.noscroll){
+ this._hasVScroll = false;
+ }else{
+ var style = html.style(this.scrollboxNode, "overflow");
+ if(style == "hidden"){
+ this._hasVScroll = false;
+ }else if(style == "scroll"){
+ this._hasVScroll = true;
+ }else{
+ this._hasVScroll = (this.scrollboxNode.scrollHeight > this.scrollboxNode.clientHeight);
+ }
+ }
+ }
+ if(hadScroll !== this._hasVScroll){
+ this.grid.update();
+ }
+ return this._hasVScroll; // Boolean
+ },
+
+ convertColPctToFixed: function(){
+ // Fix any percentage widths to be pixel values
+ var hasPct = false;
+ this.grid.initialWidth = "";
+ var cellNodes = query("th", this.headerContentNode);
+ var fixedWidths = array.map(cellNodes, function(c, vIdx){
+ var w = c.style.width;
+ html.attr(c, "vIdx", vIdx);
+ if(w && w.slice(-1) == "%"){
+ hasPct = true;
+ }else if(w && w.slice(-2) == "px"){
+ return window.parseInt(w, 10);
+ }
+ return html.contentBox(c).w;
+ });
+ if(hasPct){
+ array.forEach(this.grid.layout.cells, function(cell, idx){
+ if(cell.view == this){
+ var cellNode = cell.view.getHeaderCellNode(cell.index);
+ if(cellNode && html.hasAttr(cellNode, "vIdx")){
+ var vIdx = window.parseInt(html.attr(cellNode, "vIdx"));
+ this.setColWidth(idx, fixedWidths[vIdx]);
+ html.removeAttr(cellNode, "vIdx");
+ }
+ }
+ }, this);
+ return true;
+ }
+ return false;
+ },
+
+ adaptHeight: function(minusScroll){
+ if(!this.grid._autoHeight){
+ var h = (this.domNode.style.height && parseInt(this.domNode.style.height.replace(/px/,''), 10)) || this.domNode.clientHeight;
+ var self = this;
+ var checkOtherViewScrollers = function(){
+ var v;
+ for(var i in self.grid.views.views){
+ v = self.grid.views.views[i];
+ if(v !== self && v.hasHScrollbar()){
+ return true;
+ }
+ }
+ return false;
+ };
+ if(minusScroll || (this.noscroll && checkOtherViewScrollers())){
+ h -= metrics.getScrollbar().h;
+ }
+ util.setStyleHeightPx(this.scrollboxNode, h);
+ }
+ this.hasVScrollbar(true);
+ },
+
+ adaptWidth: function(){
+ if(this.flexCells){
+ // the view content width
+ this.contentWidth = this.getContentWidth();
+ this.headerContentNode.firstChild.style.width = this.contentWidth;
+ }
+ // FIXME: it should be easier to get w from this.scrollboxNode.clientWidth,
+ // but clientWidth seemingly does not include scrollbar width in some cases
+ var w = this.scrollboxNode.offsetWidth - this.getScrollbarWidth();
+ if(!this._removingColumn){
+ w = Math.max(w, this.getColumnsWidth()) + 'px';
+ }else{
+ w = Math.min(w, this.getColumnsWidth()) + 'px';
+ this._removingColumn = false;
+ }
+ var cn = this.contentNode;
+ cn.style.width = w;
+ this.hasHScrollbar(true);
+ },
+
+ setSize: function(w, h){
+ var ds = this.domNode.style;
+ var hs = this.headerNode.style;
+
+ if(w){
+ ds.width = w;
+ hs.width = w;
+ }
+ ds.height = (h >= 0 ? h + 'px' : '');
+ },
+
+ renderRow: function(inRowIndex){
+ var rowNode = this.createRowNode(inRowIndex);
+ this.buildRow(inRowIndex, rowNode);
+ //this.grid.edit.restore(this, inRowIndex);
+ return rowNode;
+ },
+
+ createRowNode: function(inRowIndex){
+ var node = document.createElement("div");
+ node.className = this.classTag + 'Row';
+ if (this instanceof dojox.grid._RowSelector){
+ html.attr(node,"role","presentation");
+ }else{
+ html.attr(node,"role","row");
+ if (this.grid.selectionMode != "none") {
+ node.setAttribute("aria-selected", "false"); //rows can be selected so add aria-selected prop
+ }
+ }
+ node[util.gridViewTag] = this.id;
+ node[util.rowIndexTag] = inRowIndex;
+ this.rowNodes[inRowIndex] = node;
+ return node;
+ },
+
+ buildRow: function(inRowIndex, inRowNode){
+
+ this.buildRowContent(inRowIndex, inRowNode);
+
+ this.styleRow(inRowIndex, inRowNode);
+
+
+ },
+
+ buildRowContent: function(inRowIndex, inRowNode){
+ inRowNode.innerHTML = this.content.generateHtml(inRowIndex, inRowIndex);
+ if(this.flexCells && this.contentWidth){
+ // FIXME: accessing firstChild here breaks encapsulation
+ inRowNode.firstChild.style.width = this.contentWidth;
+ }
+ util.fire(this, "onAfterRow", [inRowIndex, this.structure.cells, inRowNode]);
+ },
+
+ rowRemoved:function(inRowIndex){
+ if(inRowIndex >= 0){
+ this._cleanupRowWidgets(this.getRowNode(inRowIndex));
+ }
+ this.grid.edit.save(this, inRowIndex);
+ delete this.rowNodes[inRowIndex];
+ },
+
+ getRowNode: function(inRowIndex){
+ return this.rowNodes[inRowIndex];
+ },
+
+ getCellNode: function(inRowIndex, inCellIndex){
+ var row = this.getRowNode(inRowIndex);
+ if(row){
+ return this.content.getCellNode(row, inCellIndex);
+ }
+ },
+
+ getHeaderCellNode: function(inCellIndex){
+ if(this.headerContentNode){
+ return this.header.getCellNode(this.headerContentNode, inCellIndex);
+ }
+ },
+
+ // styling
+ styleRow: function(inRowIndex, inRowNode){
+ inRowNode._style = getStyleText(inRowNode);
+ this.styleRowNode(inRowIndex, inRowNode);
+ },
+
+ styleRowNode: function(inRowIndex, inRowNode){
+ if(inRowNode){
+ this.doStyleRowNode(inRowIndex, inRowNode);
+ }
+ },
+
+ doStyleRowNode: function(inRowIndex, inRowNode){
+ this.grid.styleRowNode(inRowIndex, inRowNode);
+ },
+
+ // updating
+ updateRow: function(inRowIndex){
+ var rowNode = this.getRowNode(inRowIndex);
+ if(rowNode){
+ rowNode.style.height = '';
+ this.buildRow(inRowIndex, rowNode);
+ }
+ return rowNode;
+ },
+
+ updateRowStyles: function(inRowIndex){
+ this.styleRowNode(inRowIndex, this.getRowNode(inRowIndex));
+ },
+
+ // scrolling
+ lastTop: 0,
+ firstScroll:0,
+
+ doscroll: function(inEvent){
+ //var s = dojo.marginBox(this.headerContentNode.firstChild);
+ var isLtr = this.grid.isLeftToRight();
+ if(this.firstScroll < 2){
+ if((!isLtr && this.firstScroll == 1) || (isLtr && this.firstScroll === 0)){
+ var s = html.marginBox(this.headerNodeContainer);
+ if(has("ie")){
+ this.headerNodeContainer.style.width = s.w + this.getScrollbarWidth() + 'px';
+ }else if(has("mozilla")){
+ //TODO currently only for FF, not sure for safari and opera
+ this.headerNodeContainer.style.width = s.w - this.getScrollbarWidth() + 'px';
+ //this.headerNodeContainer.style.width = s.w + 'px';
+ //set scroll to right in FF
+ this.scrollboxNode.scrollLeft = isLtr ?
+ this.scrollboxNode.clientWidth - this.scrollboxNode.scrollWidth :
+ this.scrollboxNode.scrollWidth - this.scrollboxNode.clientWidth;
+ }
+ }
+ this.firstScroll++;
+ }
+ this.headerNode.scrollLeft = this.scrollboxNode.scrollLeft;
+ // 'lastTop' is a semaphore to prevent feedback-loop with setScrollTop below
+ var top = this.scrollboxNode.scrollTop;
+ if(top !== this.lastTop){
+ this.grid.scrollTo(top);
+ }
+ },
+
+ setScrollTop: function(inTop){
+ // 'lastTop' is a semaphore to prevent feedback-loop with doScroll above
+ this.lastTop = inTop;
+ this.scrollboxNode.scrollTop = inTop;
+ return this.scrollboxNode.scrollTop;
+ },
+
+ // event handlers (direct from DOM)
+ doContentEvent: function(e){
+ if(this.content.decorateEvent(e)){
+ this.grid.onContentEvent(e);
+ }
+ },
+
+ doHeaderEvent: function(e){
+ if(this.header.decorateEvent(e)){
+ this.grid.onHeaderEvent(e);
+ }
+ },
+
+ // event dispatch(from Grid)
+ dispatchContentEvent: function(e){
+ return this.content.dispatchEvent(e);
+ },
+
+ dispatchHeaderEvent: function(e){
+ return this.header.dispatchEvent(e);
+ },
+
+ // column resizing
+ setColWidth: function(inIndex, inWidth){
+ this.grid.setCellWidth(inIndex, inWidth + 'px');
+ },
+
+ update: function(){
+ if(!this.domNode){
+ return;
+ }
+ this.content.update();
+ this.grid.update();
+ //get scroll after update or scroll left setting goes wrong on IE.
+ //See trac: #8040
+ var left = this.scrollboxNode.scrollLeft;
+ this.scrollboxNode.scrollLeft = left;
+ this.headerNode.scrollLeft = left;
+ }
+ });
+
+ var _GridAvatar = declare("dojox.grid._GridAvatar", Avatar, {
+ construct: function(){
+ var dd = win.doc;
+
+ var a = dd.createElement("table");
+ a.cellPadding = a.cellSpacing = "0";
+ a.className = "dojoxGridDndAvatar";
+ a.style.position = "absolute";
+ a.style.zIndex = 1999;
+ a.style.margin = "0px"; // to avoid dojo.marginBox() problems with table's margins
+ var b = dd.createElement("tbody");
+ var tr = dd.createElement("tr");
+ var td = dd.createElement("td");
+ var img = dd.createElement("td");
+ tr.className = "dojoxGridDndAvatarItem";
+ img.className = "dojoxGridDndAvatarItemImage";
+ img.style.width = "16px";
+ var source = this.manager.source, node;
+ if(source.creator){
+ // create an avatar representation of the node
+ node = source._normalizedCreator(source.getItem(this.manager.nodes[0].id).data, "avatar").node;
+ }else{
+ // or just clone the node and hope it works
+ node = this.manager.nodes[0].cloneNode(true);
+ var table, tbody;
+ if(node.tagName.toLowerCase() == "tr"){
+ // insert extra table nodes
+ table = dd.createElement("table");
+ tbody = dd.createElement("tbody");
+ tbody.appendChild(node);
+ table.appendChild(tbody);
+ node = table;
+ }else if(node.tagName.toLowerCase() == "th"){
+ // insert extra table nodes
+ table = dd.createElement("table");
+ tbody = dd.createElement("tbody");
+ var r = dd.createElement("tr");
+ table.cellPadding = table.cellSpacing = "0";
+ r.appendChild(node);
+ tbody.appendChild(r);
+ table.appendChild(tbody);
+ node = table;
+ }
+ }
+ node.id = "";
+ td.appendChild(node);
+ tr.appendChild(img);
+ tr.appendChild(td);
+ html.style(tr, "opacity", 0.9);
+ b.appendChild(tr);
+
+ a.appendChild(b);
+ this.node = a;
+
+ var m = dojo.dnd.manager();
+ this.oldOffsetY = m.OFFSET_Y;
+ m.OFFSET_Y = 1;
+ },
+ destroy: function(){
+ dojo.dnd.manager().OFFSET_Y = this.oldOffsetY;
+ this.inherited(arguments);
+ }
+ });
+
+ var oldMakeAvatar = dojo.dnd.manager().makeAvatar;
+ dojo.dnd.manager().makeAvatar = function(){
+ var src = this.source;
+ if(src.viewIndex !== undefined && !html.hasClass(win.body(),"dijit_a11y")){
+ return new _GridAvatar(this);
+ }
+ return oldMakeAvatar.call(dojo.dnd.manager());
+ };
+
+ return _View;
+
+});
+},
+'dijit/_Contained':function(){
+define("dijit/_Contained", [
+ "dojo/_base/declare", // declare
+ "./registry" // registry.getEnclosingWidget(), registry.byNode()
+], function(declare, registry){
+
+ // module:
+ // dijit/_Contained
+ // summary:
+ // Mixin for widgets that are children of a container widget
+
+ return declare("dijit._Contained", null, {
+ // summary:
+ // Mixin for widgets that are children of a container widget
+ //
+ // example:
+ // | // make a basic custom widget that knows about it's parents
+ // | declare("my.customClass",[dijit._Widget,dijit._Contained],{});
+
+ _getSibling: function(/*String*/ which){
+ // summary:
+ // Returns next or previous sibling
+ // which:
+ // Either "next" or "previous"
+ // tags:
+ // private
+ var node = this.domNode;
+ do{
+ node = node[which+"Sibling"];
+ }while(node && node.nodeType != 1);
+ return node && registry.byNode(node); // dijit._Widget
+ },
+
+ getPreviousSibling: function(){
+ // summary:
+ // Returns null if this is the first child of the parent,
+ // otherwise returns the next element sibling to the "left".
+
+ return this._getSibling("previous"); // dijit._Widget
+ },
+
+ getNextSibling: function(){
+ // summary:
+ // Returns null if this is the last child of the parent,
+ // otherwise returns the next element sibling to the "right".
+
+ return this._getSibling("next"); // dijit._Widget
+ },
+
+ getIndexInParent: function(){
+ // summary:
+ // Returns the index of this widget within its container parent.
+ // It returns -1 if the parent does not exist, or if the parent
+ // is not a dijit._Container
+
+ var p = this.getParent();
+ if(!p || !p.getIndexOfChild){
+ return -1; // int
+ }
+ return p.getIndexOfChild(this); // int
+ }
+ });
+});
+
+},
+'dojo/dnd/Selector':function(){
+define(["../main", "./common", "./Container"], function(dojo) {
+ // module:
+ // dojo/dnd/Selector
+ // summary:
+ // TODOC
+
+
+/*
+ Container item states:
+ "" - an item is not selected
+ "Selected" - an item is selected
+ "Anchor" - an item is selected, and is an anchor for a "shift" selection
+*/
+
+/*=====
+dojo.declare("dojo.dnd.__SelectorArgs", [dojo.dnd.__ContainerArgs], {
+ // singular: Boolean
+ // allows selection of only one element, if true
+ singular: false,
+
+ // autoSync: Boolean
+ // autosynchronizes the source with its list of DnD nodes,
+ autoSync: false
+});
+=====*/
+
+dojo.declare("dojo.dnd.Selector", dojo.dnd.Container, {
+ // summary:
+ // a Selector object, which knows how to select its children
+
+ /*=====
+ // selection: Set<String>
+ // The set of id's that are currently selected, such that this.selection[id] == 1
+ // if the node w/that id is selected. Can iterate over selected node's id's like:
+ // | for(var id in this.selection)
+ selection: {},
+ =====*/
+
+ constructor: function(node, params){
+ // summary:
+ // constructor of the Selector
+ // node: Node||String
+ // node or node's id to build the selector on
+ // params: dojo.dnd.__SelectorArgs?
+ // a dictionary of parameters
+ if(!params){ params = {}; }
+ this.singular = params.singular;
+ this.autoSync = params.autoSync;
+ // class-specific variables
+ this.selection = {};
+ this.anchor = null;
+ this.simpleSelection = false;
+ // set up events
+ this.events.push(
+ dojo.connect(this.node, "onmousedown", this, "onMouseDown"),
+ dojo.connect(this.node, "onmouseup", this, "onMouseUp"));
+ },
+
+ // object attributes (for markup)
+ singular: false, // is singular property
+
+ // methods
+ getSelectedNodes: function(){
+ // summary:
+ // returns a list (an array) of selected nodes
+ var t = new dojo.NodeList();
+ var e = dojo.dnd._empty;
+ for(var i in this.selection){
+ if(i in e){ continue; }
+ t.push(dojo.byId(i));
+ }
+ return t; // NodeList
+ },
+ selectNone: function(){
+ // summary:
+ // unselects all items
+ return this._removeSelection()._removeAnchor(); // self
+ },
+ selectAll: function(){
+ // summary:
+ // selects all items
+ this.forInItems(function(data, id){
+ this._addItemClass(dojo.byId(id), "Selected");
+ this.selection[id] = 1;
+ }, this);
+ return this._removeAnchor(); // self
+ },
+ deleteSelectedNodes: function(){
+ // summary:
+ // deletes all selected items
+ var e = dojo.dnd._empty;
+ for(var i in this.selection){
+ if(i in e){ continue; }
+ var n = dojo.byId(i);
+ this.delItem(i);
+ dojo.destroy(n);
+ }
+ this.anchor = null;
+ this.selection = {};
+ return this; // self
+ },
+ forInSelectedItems: function(/*Function*/ f, /*Object?*/ o){
+ // summary:
+ // iterates over selected items;
+ // see `dojo.dnd.Container.forInItems()` for details
+ o = o || dojo.global;
+ var s = this.selection, e = dojo.dnd._empty;
+ for(var i in s){
+ if(i in e){ continue; }
+ f.call(o, this.getItem(i), i, this);
+ }
+ },
+ sync: function(){
+ // summary:
+ // sync up the node list with the data map
+
+ dojo.dnd.Selector.superclass.sync.call(this);
+
+ // fix the anchor
+ if(this.anchor){
+ if(!this.getItem(this.anchor.id)){
+ this.anchor = null;
+ }
+ }
+
+ // fix the selection
+ var t = [], e = dojo.dnd._empty;
+ for(var i in this.selection){
+ if(i in e){ continue; }
+ if(!this.getItem(i)){
+ t.push(i);
+ }
+ }
+ dojo.forEach(t, function(i){
+ delete this.selection[i];
+ }, this);
+
+ return this; // self
+ },
+ insertNodes: function(addSelected, data, before, anchor){
+ // summary:
+ // inserts new data items (see `dojo.dnd.Container.insertNodes()` method for details)
+ // addSelected: Boolean
+ // all new nodes will be added to selected items, if true, no selection change otherwise
+ // data: Array
+ // a list of data items, which should be processed by the creator function
+ // before: Boolean
+ // insert before the anchor, if true, and after the anchor otherwise
+ // anchor: Node
+ // the anchor node to be used as a point of insertion
+ var oldCreator = this._normalizedCreator;
+ this._normalizedCreator = function(item, hint){
+ var t = oldCreator.call(this, item, hint);
+ if(addSelected){
+ if(!this.anchor){
+ this.anchor = t.node;
+ this._removeItemClass(t.node, "Selected");
+ this._addItemClass(this.anchor, "Anchor");
+ }else if(this.anchor != t.node){
+ this._removeItemClass(t.node, "Anchor");
+ this._addItemClass(t.node, "Selected");
+ }
+ this.selection[t.node.id] = 1;
+ }else{
+ this._removeItemClass(t.node, "Selected");
+ this._removeItemClass(t.node, "Anchor");
+ }
+ return t;
+ };
+ dojo.dnd.Selector.superclass.insertNodes.call(this, data, before, anchor);
+ this._normalizedCreator = oldCreator;
+ return this; // self
+ },
+ destroy: function(){
+ // summary:
+ // prepares the object to be garbage-collected
+ dojo.dnd.Selector.superclass.destroy.call(this);
+ this.selection = this.anchor = null;
+ },
+
+ // mouse events
+ onMouseDown: function(e){
+ // summary:
+ // event processor for onmousedown
+ // e: Event
+ // mouse event
+ if(this.autoSync){ this.sync(); }
+ if(!this.current){ return; }
+ if(!this.singular && !dojo.isCopyKey(e) && !e.shiftKey && (this.current.id in this.selection)){
+ this.simpleSelection = true;
+ if(e.button === dojo.mouseButtons.LEFT){
+ // accept the left button and stop the event
+ // for IE we don't stop event when multiple buttons are pressed
+ dojo.stopEvent(e);
+ }
+ return;
+ }
+ if(!this.singular && e.shiftKey){
+ if(!dojo.isCopyKey(e)){
+ this._removeSelection();
+ }
+ var c = this.getAllNodes();
+ if(c.length){
+ if(!this.anchor){
+ this.anchor = c[0];
+ this._addItemClass(this.anchor, "Anchor");
+ }
+ this.selection[this.anchor.id] = 1;
+ if(this.anchor != this.current){
+ var i = 0;
+ for(; i < c.length; ++i){
+ var node = c[i];
+ if(node == this.anchor || node == this.current){ break; }
+ }
+ for(++i; i < c.length; ++i){
+ var node = c[i];
+ if(node == this.anchor || node == this.current){ break; }
+ this._addItemClass(node, "Selected");
+ this.selection[node.id] = 1;
+ }
+ this._addItemClass(this.current, "Selected");
+ this.selection[this.current.id] = 1;
+ }
+ }
+ }else{
+ if(this.singular){
+ if(this.anchor == this.current){
+ if(dojo.isCopyKey(e)){
+ this.selectNone();
+ }
+ }else{
+ this.selectNone();
+ this.anchor = this.current;
+ this._addItemClass(this.anchor, "Anchor");
+ this.selection[this.current.id] = 1;
+ }
+ }else{
+ if(dojo.isCopyKey(e)){
+ if(this.anchor == this.current){
+ delete this.selection[this.anchor.id];
+ this._removeAnchor();
+ }else{
+ if(this.current.id in this.selection){
+ this._removeItemClass(this.current, "Selected");
+ delete this.selection[this.current.id];
+ }else{
+ if(this.anchor){
+ this._removeItemClass(this.anchor, "Anchor");
+ this._addItemClass(this.anchor, "Selected");
+ }
+ this.anchor = this.current;
+ this._addItemClass(this.current, "Anchor");
+ this.selection[this.current.id] = 1;
+ }
+ }
+ }else{
+ if(!(this.current.id in this.selection)){
+ this.selectNone();
+ this.anchor = this.current;
+ this._addItemClass(this.current, "Anchor");
+ this.selection[this.current.id] = 1;
+ }
+ }
+ }
+ }
+ dojo.stopEvent(e);
+ },
+ onMouseUp: function(e){
+ // summary:
+ // event processor for onmouseup
+ // e: Event
+ // mouse event
+ if(!this.simpleSelection){ return; }
+ this.simpleSelection = false;
+ this.selectNone();
+ if(this.current){
+ this.anchor = this.current;
+ this._addItemClass(this.anchor, "Anchor");
+ this.selection[this.current.id] = 1;
+ }
+ },
+ onMouseMove: function(e){
+ // summary:
+ // event processor for onmousemove
+ // e: Event
+ // mouse event
+ this.simpleSelection = false;
+ },
+
+ // utilities
+ onOverEvent: function(){
+ // summary:
+ // this function is called once, when mouse is over our container
+ this.onmousemoveEvent = dojo.connect(this.node, "onmousemove", this, "onMouseMove");
+ },
+ onOutEvent: function(){
+ // summary:
+ // this function is called once, when mouse is out of our container
+ dojo.disconnect(this.onmousemoveEvent);
+ delete this.onmousemoveEvent;
+ },
+ _removeSelection: function(){
+ // summary:
+ // unselects all items
+ var e = dojo.dnd._empty;
+ for(var i in this.selection){
+ if(i in e){ continue; }
+ var node = dojo.byId(i);
+ if(node){ this._removeItemClass(node, "Selected"); }
+ }
+ this.selection = {};
+ return this; // self
+ },
+ _removeAnchor: function(){
+ if(this.anchor){
+ this._removeItemClass(this.anchor, "Anchor");
+ this.anchor = null;
+ }
+ return this; // self
+ }
+});
+
+return dojo.dnd.Selector;
+});
+
+},
+'dojo/parser':function(){
+define(
+ ["./_base/kernel", "./_base/lang", "./_base/array", "./_base/html", "./_base/window", "./_base/url",
+ "./_base/json", "./aspect", "./date/stamp", "./query", "./on", "./ready"],
+ function(dojo, dlang, darray, dhtml, dwindow, _Url, djson, aspect, dates, query, don){
+
+// module:
+// dojo/parser
+// summary:
+// The Dom/Widget parsing package
+
+new Date("X"); // workaround for #11279, new Date("") == NaN
+
+var features = {
+ // Feature detection for when node.attributes only lists the attributes specified in the markup
+ // rather than old IE/quirks behavior where it lists every default value too
+ "dom-attributes-explicit": document.createElement("div").attributes.length < 40
+};
+function has(feature){
+ return features[feature];
+}
+
+
+dojo.parser = new function(){
+ // summary:
+ // The Dom/Widget parsing package
+
+ var _nameMap = {
+ // Map from widget name (ex: "dijit.form.Button") to structure mapping
+ // lowercase version of attribute names to the version in the widget ex:
+ // {
+ // label: "label",
+ // onclick: "onClick"
+ // }
+ };
+ function getNameMap(proto){
+ // summary:
+ // Returns map from lowercase name to attribute name in class, ex: {onclick: "onClick"}
+ var map = {};
+ for(var name in proto){
+ if(name.charAt(0)=="_"){ continue; } // skip internal properties
+ map[name.toLowerCase()] = name;
+ }
+ return map;
+ }
+ // Widgets like BorderContainer add properties to _Widget via dojo.extend().
+ // If BorderContainer is loaded after _Widget's parameter list has been cached,
+ // we need to refresh that parameter list (for _Widget and all widgets that extend _Widget).
+ aspect.after(dlang, "extend", function(){
+ _nameMap = {};
+ }, true);
+
+ // Map from widget name (ex: "dijit.form.Button") to constructor
+ var _ctorMap = {};
+
+ this._functionFromScript = function(script, attrData){
+ // summary:
+ // Convert a <script type="dojo/method" args="a, b, c"> ... </script>
+ // into a function
+ // script: DOMNode
+ // The <script> DOMNode
+ // attrData: String
+ // For HTML5 compliance, searches for attrData + "args" (typically
+ // "data-dojo-args") instead of "args"
+ var preamble = "";
+ var suffix = "";
+ var argsStr = (script.getAttribute(attrData + "args") || script.getAttribute("args"));
+ if(argsStr){
+ darray.forEach(argsStr.split(/\s*,\s*/), function(part, idx){
+ preamble += "var "+part+" = arguments["+idx+"]; ";
+ });
+ }
+ var withStr = script.getAttribute("with");
+ if(withStr && withStr.length){
+ darray.forEach(withStr.split(/\s*,\s*/), function(part){
+ preamble += "with("+part+"){";
+ suffix += "}";
+ });
+ }
+ return new Function(preamble+script.innerHTML+suffix);
+ };
+
+ this.instantiate = /*====== dojo.parser.instantiate= ======*/function(nodes, mixin, args){
+ // summary:
+ // Takes array of nodes, and turns them into class instances and
+ // potentially calls a startup method to allow them to connect with
+ // any children.
+ // nodes: Array
+ // Array of nodes or objects like
+ // | {
+ // | type: "dijit.form.Button",
+ // | node: DOMNode,
+ // | scripts: [ ... ], // array of <script type="dojo/..."> children of node
+ // | inherited: { ... } // settings inherited from ancestors like dir, theme, etc.
+ // | }
+ // mixin: Object?
+ // An object that will be mixed in with each node in the array.
+ // Values in the mixin will override values in the node, if they
+ // exist.
+ // args: Object?
+ // An object used to hold kwArgs for instantiation.
+ // See parse.args argument for details.
+
+ var thelist = [],
+ mixin = mixin||{};
+ args = args||{};
+
+ // Precompute names of special attributes we are looking for
+ // TODO: for 2.0 default to data-dojo- regardless of scopeName (or maybe scopeName won't exist in 2.0)
+ var dojoType = (args.scope || dojo._scopeName) + "Type", // typically "dojoType"
+ attrData = "data-" + (args.scope || dojo._scopeName) + "-",// typically "data-dojo-"
+ dataDojoType = attrData + "type", // typically "data-dojo-type"
+ dataDojoProps = attrData + "props", // typically "data-dojo-props"
+ dataDojoAttachPoint = attrData + "attach-point",
+ dataDojoAttachEvent = attrData + "attach-event",
+ dataDojoId = attrData + "id";
+
+ // And make hash to quickly check if a given attribute is special, and to map the name to something friendly
+ var specialAttrs = {};
+ darray.forEach([dataDojoProps, dataDojoType, dojoType, dataDojoId, "jsId", dataDojoAttachPoint,
+ dataDojoAttachEvent, "dojoAttachPoint", "dojoAttachEvent", "class", "style"], function(name){
+ specialAttrs[name.toLowerCase()] = name.replace(args.scope, "dojo");
+ });
+
+ darray.forEach(nodes, function(obj){
+ if(!obj){ return; }
+
+ var node = obj.node || obj,
+ type = dojoType in mixin ? mixin[dojoType] : obj.node ? obj.type : (node.getAttribute(dataDojoType) || node.getAttribute(dojoType)),
+ ctor = _ctorMap[type] || (_ctorMap[type] = dlang.getObject(type)),
+ proto = ctor && ctor.prototype;
+ if(!ctor){
+ throw new Error("Could not load class '" + type);
+ }
+
+ // Setup hash to hold parameter settings for this widget. Start with the parameter
+ // settings inherited from ancestors ("dir" and "lang").
+ // Inherited setting may later be overridden by explicit settings on node itself.
+ var params = {};
+
+ if(args.defaults){
+ // settings for the document itself (or whatever subtree is being parsed)
+ dlang.mixin(params, args.defaults);
+ }
+ if(obj.inherited){
+ // settings from dir=rtl or lang=... on a node above this node
+ dlang.mixin(params, obj.inherited);
+ }
+
+ // Get list of attributes explicitly listed in the markup
+ var attributes;
+ if(has("dom-attributes-explicit")){
+ // Standard path to get list of user specified attributes
+ attributes = node.attributes;
+ }else{
+ // Special path for IE, avoid (sometimes >100) bogus entries in node.attributes
+ var clone = /^input$|^img$/i.test(node.nodeName) ? node : node.cloneNode(false),
+ attrs = clone.outerHTML.replace(/=[^\s"']+|="[^"]*"|='[^']*'/g, "").replace(/^\s*<[a-zA-Z0-9]*/, "").replace(/>.*$/, "");
+
+ attributes = darray.map(attrs.split(/\s+/), function(name){
+ var lcName = name.toLowerCase();
+ return {
+ name: name,
+ // getAttribute() doesn't work for button.value, returns innerHTML of button.
+ // but getAttributeNode().value doesn't work for the form.encType or li.value
+ value: (node.nodeName == "LI" && name == "value") || lcName == "enctype" ?
+ node.getAttribute(lcName) : node.getAttributeNode(lcName).value,
+ specified: true
+ };
+ });
+ }
+
+ // Read in attributes and process them, including data-dojo-props, data-dojo-type,
+ // dojoAttachPoint, etc., as well as normal foo=bar attributes.
+ var i=0, item;
+ while(item = attributes[i++]){
+ if(!item || !item.specified){
+ continue;
+ }
+
+ var name = item.name,
+ lcName = name.toLowerCase(),
+ value = item.value;
+
+ if(lcName in specialAttrs){
+ switch(specialAttrs[lcName]){
+
+ // Data-dojo-props. Save for later to make sure it overrides direct foo=bar settings
+ case "data-dojo-props":
+ var extra = value;
+ break;
+
+ // data-dojo-id or jsId. TODO: drop jsId in 2.0
+ case "data-dojo-id":
+ case "jsId":
+ var jsname = value;
+ break;
+
+ // For the benefit of _Templated
+ case "data-dojo-attach-point":
+ case "dojoAttachPoint":
+ params.dojoAttachPoint = value;
+ break;
+ case "data-dojo-attach-event":
+ case "dojoAttachEvent":
+ params.dojoAttachEvent = value;
+ break;
+
+ // Special parameter handling needed for IE
+ case "class":
+ params["class"] = node.className;
+ break;
+ case "style":
+ params["style"] = node.style && node.style.cssText;
+ break;
+ }
+ }else{
+ // Normal attribute, ex: value="123"
+
+ // Find attribute in widget corresponding to specified name.
+ // May involve case conversion, ex: onclick --> onClick
+ if(!(name in proto)){
+ var map = (_nameMap[type] || (_nameMap[type] = getNameMap(proto)));
+ name = map[lcName] || name;
+ }
+
+ // Set params[name] to value, doing type conversion
+ if(name in proto){
+ switch(typeof proto[name]){
+ case "string":
+ params[name] = value;
+ break;
+ case "number":
+ params[name] = value.length ? Number(value) : NaN;
+ break;
+ case "boolean":
+ // for checked/disabled value might be "" or "checked". interpret as true.
+ params[name] = value.toLowerCase() != "false";
+ break;
+ case "function":
+ if(value === "" || value.search(/[^\w\.]+/i) != -1){
+ // The user has specified some text for a function like "return x+5"
+ params[name] = new Function(value);
+ }else{
+ // The user has specified the name of a function like "myOnClick"
+ // or a single word function "return"
+ params[name] = dlang.getObject(value, false) || new Function(value);
+ }
+ break;
+ default:
+ var pVal = proto[name];
+ params[name] =
+ (pVal && "length" in pVal) ? (value ? value.split(/\s*,\s*/) : []) : // array
+ (pVal instanceof Date) ?
+ (value == "" ? new Date("") : // the NaN of dates
+ value == "now" ? new Date() : // current date
+ dates.fromISOString(value)) :
+ (pVal instanceof dojo._Url) ? (dojo.baseUrl + value) :
+ djson.fromJson(value);
+ }
+ }else{
+ params[name] = value;
+ }
+ }
+ }
+
+ // Mix things found in data-dojo-props into the params, overriding any direct settings
+ if(extra){
+ try{
+ extra = djson.fromJson.call(args.propsThis, "{" + extra + "}");
+ dlang.mixin(params, extra);
+ }catch(e){
+ // give the user a pointer to their invalid parameters. FIXME: can we kill this in production?
+ throw new Error(e.toString() + " in data-dojo-props='" + extra + "'");
+ }
+ }
+
+ // Any parameters specified in "mixin" override everything else.
+ dlang.mixin(params, mixin);
+
+ var scripts = obj.node ? obj.scripts : (ctor && (ctor._noScript || proto._noScript) ? [] :
+ query("> script[type^='dojo/']", node));
+
+ // Process <script type="dojo/*"> script tags
+ // <script type="dojo/method" event="foo"> tags are added to params, and passed to
+ // the widget on instantiation.
+ // <script type="dojo/method"> tags (with no event) are executed after instantiation
+ // <script type="dojo/connect" data-dojo-event="foo"> tags are dojo.connected after instantiation
+ // <script type="dojo/watch" data-dojo-prop="foo"> tags are dojo.watch after instantiation
+ // <script type="dojo/on" data-dojo-event="foo"> tags are dojo.on after instantiation
+ // note: dojo/* script tags cannot exist in self closing widgets, like <input />
+ var connects = [], // functions to connect after instantiation
+ calls = [], // functions to call after instantiation
+ watch = [], //functions to watch after instantiation
+ on = []; //functions to on after instantiation
+
+ if(scripts){
+ for(i=0; i<scripts.length; i++){
+ var script = scripts[i];
+ node.removeChild(script);
+ // FIXME: drop event="" support in 2.0. use data-dojo-event="" instead
+ var event = (script.getAttribute(attrData + "event") || script.getAttribute("event")),
+ prop = script.getAttribute(attrData + "prop"),
+ type = script.getAttribute("type"),
+ nf = this._functionFromScript(script, attrData);
+ if(event){
+ if(type == "dojo/connect"){
+ connects.push({event: event, func: nf});
+ }else if(type == "dojo/on"){
+ on.push({event: event, func: nf});
+ }else{
+ params[event] = nf;
+ }
+ }else if(type == "dojo/watch"){
+ watch.push({prop: prop, func: nf});
+ }else{
+ calls.push(nf);
+ }
+ }
+ }
+
+ // create the instance
+ var markupFactory = ctor.markupFactory || proto.markupFactory;
+ var instance = markupFactory ? markupFactory(params, node, ctor) : new ctor(params, node);
+ thelist.push(instance);
+
+ // map it to the JS namespace if that makes sense
+ if(jsname){
+ dlang.setObject(jsname, instance);
+ }
+
+ // process connections and startup functions
+ for(i=0; i<connects.length; i++){
+ aspect.after(instance, connects[i].event, dojo.hitch(instance, connects[i].func), true);
+ }
+ for(i=0; i<calls.length; i++){
+ calls[i].call(instance);
+ }
+ for(i=0; i<watch.length; i++){
+ instance.watch(watch[i].prop, watch[i].func);
+ }
+ for(i=0; i<on.length; i++){
+ don(instance, on[i].event, on[i].func);
+ }
+ }, this);
+
+ // Call startup on each top level instance if it makes sense (as for
+ // widgets). Parent widgets will recursively call startup on their
+ // (non-top level) children
+ if(!mixin._started){
+ darray.forEach(thelist, function(instance){
+ if( !args.noStart && instance &&
+ dlang.isFunction(instance.startup) &&
+ !instance._started
+ ){
+ instance.startup();
+ }
+ });
+ }
+ return thelist;
+ };
+
+ this.parse = /*====== dojo.parser.parse= ======*/ function(rootNode, args){
+ // summary:
+ // Scan the DOM for class instances, and instantiate them.
+ //
+ // description:
+ // Search specified node (or root node) recursively for class instances,
+ // and instantiate them. Searches for either data-dojo-type="Class" or
+ // dojoType="Class" where "Class" is a a fully qualified class name,
+ // like `dijit.form.Button`
+ //
+ // Using `data-dojo-type`:
+ // Attributes using can be mixed into the parameters used to instantiate the
+ // Class by using a `data-dojo-props` attribute on the node being converted.
+ // `data-dojo-props` should be a string attribute to be converted from JSON.
+ //
+ // Using `dojoType`:
+ // Attributes are read from the original domNode and converted to appropriate
+ // types by looking up the Class prototype values. This is the default behavior
+ // from Dojo 1.0 to Dojo 1.5. `dojoType` support is deprecated, and will
+ // go away in Dojo 2.0.
+ //
+ // rootNode: DomNode?
+ // A default starting root node from which to start the parsing. Can be
+ // omitted, defaulting to the entire document. If omitted, the `args`
+ // object can be passed in this place. If the `args` object has a
+ // `rootNode` member, that is used.
+ //
+ // args: Object
+ // a kwArgs object passed along to instantiate()
+ //
+ // * noStart: Boolean?
+ // when set will prevent the parser from calling .startup()
+ // when locating the nodes.
+ // * rootNode: DomNode?
+ // identical to the function's `rootNode` argument, though
+ // allowed to be passed in via this `args object.
+ // * template: Boolean
+ // If true, ignores ContentPane's stopParser flag and parses contents inside of
+ // a ContentPane inside of a template. This allows dojoAttachPoint on widgets/nodes
+ // nested inside the ContentPane to work.
+ // * inherited: Object
+ // Hash possibly containing dir and lang settings to be applied to
+ // parsed widgets, unless there's another setting on a sub-node that overrides
+ // * scope: String
+ // Root for attribute names to search for. If scopeName is dojo,
+ // will search for data-dojo-type (or dojoType). For backwards compatibility
+ // reasons defaults to dojo._scopeName (which is "dojo" except when
+ // multi-version support is used, when it will be something like dojo16, dojo20, etc.)
+ // * propsThis: Object
+ // If specified, "this" referenced from data-dojo-props will refer to propsThis.
+ // Intended for use from the widgets-in-template feature of `dijit._WidgetsInTemplateMixin`
+ //
+ // example:
+ // Parse all widgets on a page:
+ // | dojo.parser.parse();
+ //
+ // example:
+ // Parse all classes within the node with id="foo"
+ // | dojo.parser.parse(dojo.byId('foo'));
+ //
+ // example:
+ // Parse all classes in a page, but do not call .startup() on any
+ // child
+ // | dojo.parser.parse({ noStart: true })
+ //
+ // example:
+ // Parse all classes in a node, but do not call .startup()
+ // | dojo.parser.parse(someNode, { noStart:true });
+ // | // or
+ // | dojo.parser.parse({ noStart:true, rootNode: someNode });
+
+ // determine the root node based on the passed arguments.
+ var root;
+ if(!args && rootNode && rootNode.rootNode){
+ args = rootNode;
+ root = args.rootNode;
+ }else{
+ root = rootNode;
+ }
+ root = root ? dhtml.byId(root) : dwindow.body();
+ args = args || {};
+
+ var dojoType = (args.scope || dojo._scopeName) + "Type", // typically "dojoType"
+ attrData = "data-" + (args.scope || dojo._scopeName) + "-", // typically "data-dojo-"
+ dataDojoType = attrData + "type", // typically "data-dojo-type"
+ dataDojoTextDir = attrData + "textdir"; // typically "data-dojo-textdir"
+
+ // List of all nodes on page w/dojoType specified
+ var list = [];
+
+ // Info on DOMNode currently being processed
+ var node = root.firstChild;
+
+ // Info on parent of DOMNode currently being processed
+ // - inherited: dir, lang, and textDir setting of parent, or inherited by parent
+ // - parent: pointer to identical structure for my parent (or null if no parent)
+ // - scripts: if specified, collects <script type="dojo/..."> type nodes from children
+ var inherited = args && args.inherited;
+ if(!inherited){
+ function findAncestorAttr(node, attr){
+ return (node.getAttribute && node.getAttribute(attr)) ||
+ (node !== dwindow.doc && node !== dwindow.doc.documentElement && node.parentNode ? findAncestorAttr(node.parentNode, attr) : null);
+ }
+ inherited = {
+ dir: findAncestorAttr(root, "dir"),
+ lang: findAncestorAttr(root, "lang"),
+ textDir: findAncestorAttr(root, dataDojoTextDir)
+ };
+ for(var key in inherited){
+ if(!inherited[key]){ delete inherited[key]; }
+ }
+ }
+ var parent = {
+ inherited: inherited
+ };
+
+ // For collecting <script type="dojo/..."> type nodes (when null, we don't need to collect)
+ var scripts;
+
+ // when true, only look for <script type="dojo/..."> tags, and don't recurse to children
+ var scriptsOnly;
+
+ function getEffective(parent){
+ // summary:
+ // Get effective dir, lang, textDir settings for specified obj
+ // (matching "parent" object structure above), and do caching.
+ // Take care not to return null entries.
+ if(!parent.inherited){
+ parent.inherited = {};
+ var node = parent.node,
+ grandparent = getEffective(parent.parent);
+ var inherited = {
+ dir: node.getAttribute("dir") || grandparent.dir,
+ lang: node.getAttribute("lang") || grandparent.lang,
+ textDir: node.getAttribute(dataDojoTextDir) || grandparent.textDir
+ };
+ for(var key in inherited){
+ if(inherited[key]){
+ parent.inherited[key] = inherited[key];
+ }
+ }
+ }
+ return parent.inherited;
+ }
+
+ // DFS on DOM tree, collecting nodes with data-dojo-type specified.
+ while(true){
+ if(!node){
+ // Finished this level, continue to parent's next sibling
+ if(!parent || !parent.node){
+ break;
+ }
+ node = parent.node.nextSibling;
+ scripts = parent.scripts;
+ scriptsOnly = false;
+ parent = parent.parent;
+ continue;
+ }
+
+ if(node.nodeType != 1){
+ // Text or comment node, skip to next sibling
+ node = node.nextSibling;
+ continue;
+ }
+
+ if(scripts && node.nodeName.toLowerCase() == "script"){
+ // Save <script type="dojo/..."> for parent, then continue to next sibling
+ type = node.getAttribute("type");
+ if(type && /^dojo\/\w/i.test(type)){
+ scripts.push(node);
+ }
+ node = node.nextSibling;
+ continue;
+ }
+ if(scriptsOnly){
+ node = node.nextSibling;
+ continue;
+ }
+
+ // Check for data-dojo-type attribute, fallback to backward compatible dojoType
+ var type = node.getAttribute(dataDojoType) || node.getAttribute(dojoType);
+
+ // Short circuit for leaf nodes containing nothing [but text]
+ var firstChild = node.firstChild;
+ if(!type && (!firstChild || (firstChild.nodeType == 3 && !firstChild.nextSibling))){
+ node = node.nextSibling;
+ continue;
+ }
+
+ // Setup data structure to save info on current node for when we return from processing descendant nodes
+ var current = {
+ node: node,
+ scripts: scripts,
+ parent: parent
+ };
+
+ // If dojoType/data-dojo-type specified, add to output array of nodes to instantiate
+ var ctor = type && (_ctorMap[type] || (_ctorMap[type] = dlang.getObject(type))), // note: won't find classes declared via dojo.Declaration
+ childScripts = ctor && !ctor.prototype._noScript ? [] : null; // <script> nodes that are parent's children
+ if(type){
+ list.push({
+ "type": type,
+ node: node,
+ scripts: childScripts,
+ inherited: getEffective(current) // dir & lang settings for current node, explicit or inherited
+ });
+ }
+
+ // Recurse, collecting <script type="dojo/..."> children, and also looking for
+ // descendant nodes with dojoType specified (unless the widget has the stopParser flag).
+ // When finished with children, go to my next sibling.
+ node = firstChild;
+ scripts = childScripts;
+ scriptsOnly = ctor && ctor.prototype.stopParser && !(args && args.template);
+ parent = current;
+
+ }
+
+ // go build the object instances
+ var mixin = args && args.template ? {template: true} : null;
+ return this.instantiate(list, mixin, args); // Array
+ };
+}();
+
+
+//Register the parser callback. It should be the first callback
+//after the a11y test.
+if(dojo.config.parseOnLoad){
+ dojo.ready(100, dojo.parser, "parse");
+}
+
+return dojo.parser;
+});
+
+},
+'dojox/grid/DataSelection':function(){
+define("dojox/grid/DataSelection", [
+ "dojo/_base/declare",
+ "./_SelectionPreserver",
+ "./Selection"
+], function(declare, _SelectionPreserver, Selection){
+
+return declare("dojox.grid.DataSelection", Selection, {
+ constructor: function(grid){
+ if(grid.keepSelection){
+ this.preserver = new _SelectionPreserver(this);
+ }
+ },
+
+ destroy: function(){
+ if(this.preserver){
+ this.preserver.destroy();
+ }
+ },
+
+ getFirstSelected: function(){
+ var idx = Selection.prototype.getFirstSelected.call(this);
+
+ if(idx == -1){ return null; }
+ return this.grid.getItem(idx);
+ },
+
+ getNextSelected: function(inPrev){
+ var old_idx = this.grid.getItemIndex(inPrev);
+ var idx = Selection.prototype.getNextSelected.call(this, old_idx);
+
+ if(idx == -1){ return null; }
+ return this.grid.getItem(idx);
+ },
+
+ getSelected: function(){
+ var result = [];
+ for(var i=0, l=this.selected.length; i<l; i++){
+ if(this.selected[i]){
+ result.push(this.grid.getItem(i));
+ }
+ }
+ return result;
+ },
+
+ addToSelection: function(inItemOrIndex){
+ if(this.mode == 'none'){ return; }
+ var idx = null;
+ if(typeof inItemOrIndex == "number" || typeof inItemOrIndex == "string"){
+ idx = inItemOrIndex;
+ }else{
+ idx = this.grid.getItemIndex(inItemOrIndex);
+ }
+ Selection.prototype.addToSelection.call(this, idx);
+ },
+
+ deselect: function(inItemOrIndex){
+ if(this.mode == 'none'){ return; }
+ var idx = null;
+ if(typeof inItemOrIndex == "number" || typeof inItemOrIndex == "string"){
+ idx = inItemOrIndex;
+ }else{
+ idx = this.grid.getItemIndex(inItemOrIndex);
+ }
+ Selection.prototype.deselect.call(this, idx);
+ },
+
+ deselectAll: function(inItemOrIndex){
+ var idx = null;
+ if(inItemOrIndex || typeof inItemOrIndex == "number"){
+ if(typeof inItemOrIndex == "number" || typeof inItemOrIndex == "string"){
+ idx = inItemOrIndex;
+ }else{
+ idx = this.grid.getItemIndex(inItemOrIndex);
+ }
+ Selection.prototype.deselectAll.call(this, idx);
+ }else{
+ this.inherited(arguments);
+ }
+ }
+});
+});
+},
+'url:dijit/templates/CheckedMenuItem.html':"<tr class=\"dijitReset dijitMenuItem\" data-dojo-attach-point=\"focusNode\" role=\"menuitemcheckbox\" tabIndex=\"-1\"\n\t\tdata-dojo-attach-event=\"onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick\">\n\t<td class=\"dijitReset dijitMenuItemIconCell\" role=\"presentation\">\n\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitMenuItemIcon dijitCheckedMenuItemIcon\" data-dojo-attach-point=\"iconNode\"/>\n\t\t<span class=\"dijitCheckedMenuItemIconChar\">&#10003;</span>\n\t</td>\n\t<td class=\"dijitReset dijitMenuItemLabel\" colspan=\"2\" data-dojo-attach-point=\"containerNode,labelNode\"></td>\n\t<td class=\"dijitReset dijitMenuItemAccelKey\" style=\"display: none\" data-dojo-attach-point=\"accelKeyNode\"></td>\n\t<td class=\"dijitReset dijitMenuArrowCell\" role=\"presentation\">&#160;</td>\n</tr>\n",
+'dojo/dnd/Manager':function(){
+define(["../main", "../Evented", "./common", "./autoscroll", "./Avatar"], function(dojo, Evented) {
+ // module:
+ // dojo/dnd/Manager
+ // summary:
+ // TODOC
+
+
+var Manager = dojo.declare("dojo.dnd.Manager", [Evented], {
+ // summary:
+ // the manager of DnD operations (usually a singleton)
+ constructor: function(){
+ this.avatar = null;
+ this.source = null;
+ this.nodes = [];
+ this.copy = true;
+ this.target = null;
+ this.canDropFlag = false;
+ this.events = [];
+ },
+
+ // avatar's offset from the mouse
+ OFFSET_X: 16,
+ OFFSET_Y: 16,
+
+ // methods
+ overSource: function(source){
+ // summary:
+ // called when a source detected a mouse-over condition
+ // source: Object
+ // the reporter
+ if(this.avatar){
+ this.target = (source && source.targetState != "Disabled") ? source : null;
+ this.canDropFlag = Boolean(this.target);
+ this.avatar.update();
+ }
+ dojo.publish("/dnd/source/over", [source]);
+ },
+ outSource: function(source){
+ // summary:
+ // called when a source detected a mouse-out condition
+ // source: Object
+ // the reporter
+ if(this.avatar){
+ if(this.target == source){
+ this.target = null;
+ this.canDropFlag = false;
+ this.avatar.update();
+ dojo.publish("/dnd/source/over", [null]);
+ }
+ }else{
+ dojo.publish("/dnd/source/over", [null]);
+ }
+ },
+ startDrag: function(source, nodes, copy){
+ // summary:
+ // called to initiate the DnD operation
+ // source: Object
+ // the source which provides items
+ // nodes: Array
+ // the list of transferred items
+ // copy: Boolean
+ // copy items, if true, move items otherwise
+ this.source = source;
+ this.nodes = nodes;
+ this.copy = Boolean(copy); // normalizing to true boolean
+ this.avatar = this.makeAvatar();
+ dojo.body().appendChild(this.avatar.node);
+ dojo.publish("/dnd/start", [source, nodes, this.copy]);
+ this.events = [
+ dojo.connect(dojo.doc, "onmousemove", this, "onMouseMove"),
+ dojo.connect(dojo.doc, "onmouseup", this, "onMouseUp"),
+ dojo.connect(dojo.doc, "onkeydown", this, "onKeyDown"),
+ dojo.connect(dojo.doc, "onkeyup", this, "onKeyUp"),
+ // cancel text selection and text dragging
+ dojo.connect(dojo.doc, "ondragstart", dojo.stopEvent),
+ dojo.connect(dojo.body(), "onselectstart", dojo.stopEvent)
+ ];
+ var c = "dojoDnd" + (copy ? "Copy" : "Move");
+ dojo.addClass(dojo.body(), c);
+ },
+ canDrop: function(flag){
+ // summary:
+ // called to notify if the current target can accept items
+ var canDropFlag = Boolean(this.target && flag);
+ if(this.canDropFlag != canDropFlag){
+ this.canDropFlag = canDropFlag;
+ this.avatar.update();
+ }
+ },
+ stopDrag: function(){
+ // summary:
+ // stop the DnD in progress
+ dojo.removeClass(dojo.body(), ["dojoDndCopy", "dojoDndMove"]);
+ dojo.forEach(this.events, dojo.disconnect);
+ this.events = [];
+ this.avatar.destroy();
+ this.avatar = null;
+ this.source = this.target = null;
+ this.nodes = [];
+ },
+ makeAvatar: function(){
+ // summary:
+ // makes the avatar; it is separate to be overwritten dynamically, if needed
+ return new dojo.dnd.Avatar(this);
+ },
+ updateAvatar: function(){
+ // summary:
+ // updates the avatar; it is separate to be overwritten dynamically, if needed
+ this.avatar.update();
+ },
+
+ // mouse event processors
+ onMouseMove: function(e){
+ // summary:
+ // event processor for onmousemove
+ // e: Event
+ // mouse event
+ var a = this.avatar;
+ if(a){
+ dojo.dnd.autoScrollNodes(e);
+ //dojo.dnd.autoScroll(e);
+ var s = a.node.style;
+ s.left = (e.pageX + this.OFFSET_X) + "px";
+ s.top = (e.pageY + this.OFFSET_Y) + "px";
+ var copy = Boolean(this.source.copyState(dojo.isCopyKey(e)));
+ if(this.copy != copy){
+ this._setCopyStatus(copy);
+ }
+ }
+ },
+ onMouseUp: function(e){
+ // summary:
+ // event processor for onmouseup
+ // e: Event
+ // mouse event
+ if(this.avatar){
+ if(this.target && this.canDropFlag){
+ var copy = Boolean(this.source.copyState(dojo.isCopyKey(e))),
+ params = [this.source, this.nodes, copy, this.target, e];
+ dojo.publish("/dnd/drop/before", params);
+ dojo.publish("/dnd/drop", params);
+ }else{
+ dojo.publish("/dnd/cancel");
+ }
+ this.stopDrag();
+ }
+ },
+
+ // keyboard event processors
+ onKeyDown: function(e){
+ // summary:
+ // event processor for onkeydown:
+ // watching for CTRL for copy/move status, watching for ESCAPE to cancel the drag
+ // e: Event
+ // keyboard event
+ if(this.avatar){
+ switch(e.keyCode){
+ case dojo.keys.CTRL:
+ var copy = Boolean(this.source.copyState(true));
+ if(this.copy != copy){
+ this._setCopyStatus(copy);
+ }
+ break;
+ case dojo.keys.ESCAPE:
+ dojo.publish("/dnd/cancel");
+ this.stopDrag();
+ break;
+ }
+ }
+ },
+ onKeyUp: function(e){
+ // summary:
+ // event processor for onkeyup, watching for CTRL for copy/move status
+ // e: Event
+ // keyboard event
+ if(this.avatar && e.keyCode == dojo.keys.CTRL){
+ var copy = Boolean(this.source.copyState(false));
+ if(this.copy != copy){
+ this._setCopyStatus(copy);
+ }
+ }
+ },
+
+ // utilities
+ _setCopyStatus: function(copy){
+ // summary:
+ // changes the copy status
+ // copy: Boolean
+ // the copy status
+ this.copy = copy;
+ this.source._markDndStatus(this.copy);
+ this.updateAvatar();
+ dojo.replaceClass(dojo.body(),
+ "dojoDnd" + (this.copy ? "Copy" : "Move"),
+ "dojoDnd" + (this.copy ? "Move" : "Copy"));
+ }
+});
+
+// dojo.dnd._manager:
+// The manager singleton variable. Can be overwritten if needed.
+dojo.dnd._manager = null;
+
+Manager.manager = dojo.dnd.manager = function(){
+ // summary:
+ // Returns the current DnD manager. Creates one if it is not created yet.
+ if(!dojo.dnd._manager){
+ dojo.dnd._manager = new dojo.dnd.Manager();
+ }
+ return dojo.dnd._manager; // Object
+};
+
+return Manager;
+});
+
+},
+'dojox/grid/_RowSelector':function(){
+define("dojox/grid/_RowSelector", [
+ "dojo/_base/declare",
+ "./_View"
+], function(declare, _View){
+
+return declare('dojox.grid._RowSelector', _View, {
+ // summary:
+ // Custom grid view. If used in a grid structure, provides a small selectable region for grid rows.
+ defaultWidth: "2em",
+ noscroll: true,
+ padBorderWidth: 2,
+ buildRendering: function(){
+ this.inherited('buildRendering', arguments);
+ this.scrollboxNode.style.overflow = "hidden";
+ this.headerNode.style.visibility = "hidden";
+ },
+ getWidth: function(){
+ return this.viewWidth || this.defaultWidth;
+ },
+ buildRowContent: function(inRowIndex, inRowNode){
+ var w = this.contentWidth || 0;
+ inRowNode.innerHTML = '<table class="dojoxGridRowbarTable" style="width:' + w + 'px;height:1px;" border="0" cellspacing="0" cellpadding="0" role="presentation"><tr><td class="dojoxGridRowbarInner">&nbsp;</td></tr></table>';
+ },
+ renderHeader: function(){
+ },
+ updateRow: function(){
+ },
+ resize: function(){
+ this.adaptHeight();
+ },
+ adaptWidth: function(){
+ // Only calculate this here - rather than every call to buildRowContent
+ if(!("contentWidth" in this) && this.contentNode){
+ this.contentWidth = this.contentNode.offsetWidth - this.padBorderWidth;
+ }
+ },
+ // styling
+ doStyleRowNode: function(inRowIndex, inRowNode){
+ var n = [ "dojoxGridRowbar dojoxGridNonNormalizedCell" ];
+ if(this.grid.rows.isOver(inRowIndex)){
+ n.push("dojoxGridRowbarOver");
+ }
+ if(this.grid.selection.isSelected(inRowIndex)){
+ n.push("dojoxGridRowbarSelected");
+ }
+ inRowNode.className = n.join(" ");
+ },
+ // event handlers
+ domouseover: function(e){
+ this.grid.onMouseOverRow(e);
+ },
+ domouseout: function(e){
+ if(!this.isIntraRowEvent(e)){
+ this.grid.onMouseOutRow(e);
+ }
+ }
+});
+});
+},
+'dojox/grid/_Layout':function(){
+define("dojox/grid/_Layout", [
+ "dojo/_base/kernel",
+ "../main",
+ "dojo/_base/declare",
+ "dojo/_base/array",
+ "dojo/_base/lang",
+ "dojo/dom-geometry",
+ "./cells",
+ "./_RowSelector"
+], function(dojo, dojox, declare, array, lang, domGeometry){
+
+return declare("dojox.grid._Layout", null, {
+ // summary:
+ // Controls grid cell layout. Owned by grid and used internally.
+ constructor: function(inGrid){
+ this.grid = inGrid;
+ },
+ // flat array of grid cells
+ cells: [],
+ // structured array of grid cells
+ structure: null,
+ // default cell width
+ defaultWidth: '6em',
+
+ // methods
+ moveColumn: function(sourceViewIndex, destViewIndex, cellIndex, targetIndex, before){
+ var source_cells = this.structure[sourceViewIndex].cells[0];
+ var dest_cells = this.structure[destViewIndex].cells[0];
+
+ var cell = null;
+ var cell_ri = 0;
+ var target_ri = 0;
+
+ for(var i=0, c; c=source_cells[i]; i++){
+ if(c.index == cellIndex){
+ cell_ri = i;
+ break;
+ }
+ }
+ cell = source_cells.splice(cell_ri, 1)[0];
+ cell.view = this.grid.views.views[destViewIndex];
+
+ for(i=0, c=null; c=dest_cells[i]; i++){
+ if(c.index == targetIndex){
+ target_ri = i;
+ break;
+ }
+ }
+ if(!before){
+ target_ri += 1;
+ }
+ dest_cells.splice(target_ri, 0, cell);
+
+ var sortedCell = this.grid.getCell(this.grid.getSortIndex());
+ if(sortedCell){
+ sortedCell._currentlySorted = this.grid.getSortAsc();
+ }
+
+ this.cells = [];
+ cellIndex = 0;
+ var v;
+ for(i=0; v=this.structure[i]; i++){
+ for(var j=0, cs; cs=v.cells[j]; j++){
+ for(var k=0; c=cs[k]; k++){
+ c.index = cellIndex;
+ this.cells.push(c);
+ if("_currentlySorted" in c){
+ var si = cellIndex + 1;
+ si *= c._currentlySorted ? 1 : -1;
+ this.grid.sortInfo = si;
+ delete c._currentlySorted;
+ }
+ cellIndex++;
+ }
+ }
+ }
+
+ //Fix #9481 - reset idx in cell markup
+ array.forEach(this.cells, function(c){
+ var marks = c.markup[2].split(" ");
+ var oldIdx = parseInt(marks[1].substring(5));//get old "idx"
+ if(oldIdx != c.index){
+ marks[1] = "idx=\"" + c.index + "\"";
+ c.markup[2] = marks.join(" ");
+ }
+ });
+
+ this.grid.setupHeaderMenu();
+ //this.grid.renderOnIdle();
+ },
+
+ setColumnVisibility: function(columnIndex, visible){
+ var cell = this.cells[columnIndex];
+ if(cell.hidden == visible){
+ cell.hidden = !visible;
+ var v = cell.view, w = v.viewWidth;
+ if(w && w != "auto"){
+ v._togglingColumn = domGeometry.getMarginBox(cell.getHeaderNode()).w || 0;
+ }
+ v.update();
+ return true;
+ }else{
+ return false;
+ }
+ },
+
+ addCellDef: function(inRowIndex, inCellIndex, inDef){
+ var self = this;
+ var getCellWidth = function(inDef){
+ var w = 0;
+ if(inDef.colSpan > 1){
+ w = 0;
+ }else{
+ w = inDef.width || self._defaultCellProps.width || self.defaultWidth;
+
+ if(!isNaN(w)){
+ w = w + "em";
+ }
+ }
+ return w;
+ };
+
+ var props = {
+ grid: this.grid,
+ subrow: inRowIndex,
+ layoutIndex: inCellIndex,
+ index: this.cells.length
+ };
+
+ if(inDef && inDef instanceof dojox.grid.cells._Base){
+ var new_cell = lang.clone(inDef);
+ props.unitWidth = getCellWidth(new_cell._props);
+ new_cell = lang.mixin(new_cell, this._defaultCellProps, inDef._props, props);
+ return new_cell;
+ }
+
+ var cell_type = inDef.type || inDef.cellType || this._defaultCellProps.type || this._defaultCellProps.cellType || dojox.grid.cells.Cell;
+ if(lang.isString(cell_type)){
+ cell_type = lang.getObject(cell_type);
+ }
+
+ props.unitWidth = getCellWidth(inDef);
+ return new cell_type(lang.mixin({}, this._defaultCellProps, inDef, props));
+ },
+
+ addRowDef: function(inRowIndex, inDef){
+ var result = [];
+ var relSum = 0, pctSum = 0, doRel = true;
+ for(var i=0, def, cell; (def=inDef[i]); i++){
+ cell = this.addCellDef(inRowIndex, i, def);
+ result.push(cell);
+ this.cells.push(cell);
+ // Check and calculate the sum of all relative widths
+ if(doRel && cell.relWidth){
+ relSum += cell.relWidth;
+ }else if(cell.width){
+ var w = cell.width;
+ if(typeof w == "string" && w.slice(-1) == "%"){
+ pctSum += window.parseInt(w, 10);
+ }else if(w == "auto"){
+ // relative widths doesn't play nice with auto - since we
+ // don't have a way of knowing how much space the auto is
+ // supposed to take up.
+ doRel = false;
+ }
+ }
+ }
+ if(relSum && doRel){
+ // We have some kind of relWidths specified - so change them to %
+ array.forEach(result, function(cell){
+ if(cell.relWidth){
+ cell.width = cell.unitWidth = ((cell.relWidth / relSum) * (100 - pctSum)) + "%";
+ }
+ });
+ }
+ return result;
+
+ },
+
+ addRowsDef: function(inDef){
+ var result = [];
+ if(lang.isArray(inDef)){
+ if(lang.isArray(inDef[0])){
+ for(var i=0, row; inDef && (row=inDef[i]); i++){
+ result.push(this.addRowDef(i, row));
+ }
+ }else{
+ result.push(this.addRowDef(0, inDef));
+ }
+ }
+ return result;
+ },
+
+ addViewDef: function(inDef){
+ this._defaultCellProps = inDef.defaultCell || {};
+ if(inDef.width && inDef.width == "auto"){
+ delete inDef.width;
+ }
+ return lang.mixin({}, inDef, {cells: this.addRowsDef(inDef.rows || inDef.cells)});
+ },
+
+ setStructure: function(inStructure){
+ this.fieldIndex = 0;
+ this.cells = [];
+ var s = this.structure = [];
+
+ if(this.grid.rowSelector){
+ var sel = { type: dojox._scopeName + ".grid._RowSelector" };
+
+ if(lang.isString(this.grid.rowSelector)){
+ var width = this.grid.rowSelector;
+
+ if(width == "false"){
+ sel = null;
+ }else if(width != "true"){
+ sel['width'] = width;
+ }
+ }else{
+ if(!this.grid.rowSelector){
+ sel = null;
+ }
+ }
+
+ if(sel){
+ s.push(this.addViewDef(sel));
+ }
+ }
+
+ var isCell = function(def){
+ return ("name" in def || "field" in def || "get" in def);
+ };
+
+ var isRowDef = function(def){
+ if(lang.isArray(def)){
+ if(lang.isArray(def[0]) || isCell(def[0])){
+ return true;
+ }
+ }
+ return false;
+ };
+
+ var isView = function(def){
+ return (def !== null && lang.isObject(def) &&
+ ("cells" in def || "rows" in def || ("type" in def && !isCell(def))));
+ };
+
+ if(lang.isArray(inStructure)){
+ var hasViews = false;
+ for(var i=0, st; (st=inStructure[i]); i++){
+ if(isView(st)){
+ hasViews = true;
+ break;
+ }
+ }
+ if(!hasViews){
+ s.push(this.addViewDef({ cells: inStructure }));
+ }else{
+ for(i=0; (st=inStructure[i]); i++){
+ if(isRowDef(st)){
+ s.push(this.addViewDef({ cells: st }));
+ }else if(isView(st)){
+ s.push(this.addViewDef(st));
+ }
+ }
+ }
+ }else if(isView(inStructure)){
+ // it's a view object
+ s.push(this.addViewDef(inStructure));
+ }
+
+ this.cellCount = this.cells.length;
+ this.grid.setupHeaderMenu();
+ }
+});
+});
+},
+'dojox/grid/_Grid':function(){
+require({cache:{
+'url:dojox/grid/resources/_Grid.html':"<div hidefocus=\"hidefocus\" role=\"grid\" dojoAttachEvent=\"onmouseout:_mouseOut\">\n\t<div class=\"dojoxGridMasterHeader\" dojoAttachPoint=\"viewsHeaderNode\" role=\"presentation\"></div>\n\t<div class=\"dojoxGridMasterView\" dojoAttachPoint=\"viewsNode\" role=\"presentation\"></div>\n\t<div class=\"dojoxGridMasterMessages\" style=\"display: none;\" dojoAttachPoint=\"messagesNode\"></div>\n\t<span dojoAttachPoint=\"lastFocusNode\" tabindex=\"0\"></span>\n</div>\n"}});
+define("dojox/grid/_Grid", [
+ "dojo/_base/kernel",
+ "../main",
+ "dojo/_base/declare",
+ "./_Events",
+ "./_Scroller",
+ "./_Layout",
+ "./_View",
+ "./_ViewManager",
+ "./_RowManager",
+ "./_FocusManager",
+ "./_EditManager",
+ "./Selection",
+ "./_RowSelector",
+ "./util",
+ "dijit/_Widget",
+ "dijit/_TemplatedMixin",
+ "dijit/CheckedMenuItem",
+ "dojo/text!./resources/_Grid.html",
+ "dojo/string",
+ "dojo/_base/array",
+ "dojo/_base/lang",
+ "dojo/_base/sniff",
+ "dojox/html/metrics",
+ "dojo/_base/html",
+ "dojo/query",
+ "dojo/dnd/common",
+ "dojo/i18n!dijit/nls/loading"
+], function(dojo, dojox, declare, _Events, _Scroller, _Layout, _View, _ViewManager,
+ _RowManager, _FocusManager, _EditManager, Selection, _RowSelector, util, _Widget,
+ _TemplatedMixin, CheckedMenuItem, template, string, array, lang, has, metrics, html, query){
+
+ // NOTE: this is for backwards compatibility with Dojo 1.3
+ if(!dojo.isCopyKey){
+ dojo.isCopyKey = dojo.dnd.getCopyKeyState;
+ }
+ /*=====
+ dojox.grid.__CellDef = function(){
+ // name: String?
+ // The text to use in the header of the grid for this cell.
+ // get: Function?
+ // function(rowIndex){} rowIndex is of type Integer. This
+ // function will be called when a cell requests data. Returns the
+ // unformatted data for the cell.
+ // value: String?
+ // If "get" is not specified, this is used as the data for the cell.
+ // defaultValue: String?
+ // If "get" and "value" aren't specified or if "get" returns an undefined
+ // value, this is used as the data for the cell. "formatter" is not run
+ // on this if "get" returns an undefined value.
+ // formatter: Function?
+ // function(data, rowIndex){} data is of type anything, rowIndex
+ // is of type Integer. This function will be called after the cell
+ // has its data but before it passes it back to the grid to render.
+ // Returns the formatted version of the cell's data.
+ // type: dojox.grid.cells._Base|Function?
+ // TODO
+ // editable: Boolean?
+ // Whether this cell should be editable or not.
+ // hidden: Boolean?
+ // If true, the cell will not be displayed.
+ // noresize: Boolean?
+ // If true, the cell will not be able to be resized.
+ // width: Integer|String?
+ // A CSS size. If it's an Integer, the width will be in em's.
+ // colSpan: Integer?
+ // How many columns to span this cell. Will not work in the first
+ // sub-row of cells.
+ // rowSpan: Integer?
+ // How many sub-rows to span this cell.
+ // styles: String?
+ // A string of styles to apply to both the header cell and main
+ // grid cells. Must end in a ';'.
+ // headerStyles: String?
+ // A string of styles to apply to just the header cell. Must end
+ // in a ';'
+ // cellStyles: String?
+ // A string of styles to apply to just the main grid cells. Must
+ // end in a ';'
+ // classes: String?
+ // A space separated list of classes to apply to both the header
+ // cell and the main grid cells.
+ // headerClasses: String?
+ // A space separated list of classes to apply to just the header
+ // cell.
+ // cellClasses: String?
+ // A space separated list of classes to apply to just the main
+ // grid cells.
+ // attrs: String?
+ // A space separated string of attribute='value' pairs to add to
+ // the header cell element and main grid cell elements.
+ this.name = name;
+ this.value = value;
+ this.get = get;
+ this.formatter = formatter;
+ this.type = type;
+ this.editable = editable;
+ this.hidden = hidden;
+ this.width = width;
+ this.colSpan = colSpan;
+ this.rowSpan = rowSpan;
+ this.styles = styles;
+ this.headerStyles = headerStyles;
+ this.cellStyles = cellStyles;
+ this.classes = classes;
+ this.headerClasses = headerClasses;
+ this.cellClasses = cellClasses;
+ this.attrs = attrs;
+ }
+ =====*/
+
+ /*=====
+ dojox.grid.__ViewDef = function(){
+ // noscroll: Boolean?
+ // If true, no scrollbars will be rendered without scrollbars.
+ // width: Integer|String?
+ // A CSS size. If it's an Integer, the width will be in em's. If
+ // "noscroll" is true, this value is ignored.
+ // cells: dojox.grid.__CellDef[]|Array[dojox.grid.__CellDef[]]?
+ // The structure of the cells within this grid.
+ // type: String?
+ // A string containing the constructor of a subclass of
+ // dojox.grid._View. If this is not specified, dojox.grid._View
+ // is used.
+ // defaultCell: dojox.grid.__CellDef?
+ // A cell definition with default values for all cells in this view. If
+ // a property is defined in a cell definition in the "cells" array and
+ // this property, the cell definition's property will override this
+ // property's property.
+ // onBeforeRow: Function?
+ // function(rowIndex, cells){} rowIndex is of type Integer, cells
+ // is of type Array[dojox.grid.__CellDef[]]. This function is called
+ // before each row of data is rendered. Before the header is
+ // rendered, rowIndex will be -1. "cells" is a reference to the
+ // internal structure of this view's cells so any changes you make to
+ // it will persist between calls.
+ // onAfterRow: Function?
+ // function(rowIndex, cells, rowNode){} rowIndex is of type Integer, cells
+ // is of type Array[dojox.grid.__CellDef[]], rowNode is of type DOMNode.
+ // This function is called after each row of data is rendered. After the
+ // header is rendered, rowIndex will be -1. "cells" is a reference to the
+ // internal structure of this view's cells so any changes you make to
+ // it will persist between calls.
+ this.noscroll = noscroll;
+ this.width = width;
+ this.cells = cells;
+ this.type = type;
+ this.defaultCell = defaultCell;
+ this.onBeforeRow = onBeforeRow;
+ this.onAfterRow = onAfterRow;
+ }
+ =====*/
+
+ var _Grid = declare('dojox.grid._Grid',
+ [ _Widget, _TemplatedMixin, _Events ],
+ {
+ // summary:
+ // A grid widget with virtual scrolling, cell editing, complex rows,
+ // sorting, fixed columns, sizeable columns, etc.
+ //
+ // description:
+ // _Grid provides the full set of grid features without any
+ // direct connection to a data store.
+ //
+ // The grid exposes a get function for the grid, or optionally
+ // individual columns, to populate cell contents.
+ //
+ // The grid is rendered based on its structure, an object describing
+ // column and cell layout.
+ //
+ // example:
+ // A quick sample:
+ //
+ // define a get function
+ // | function get(inRowIndex){ // called in cell context
+ // | return [this.index, inRowIndex].join(', ');
+ // | }
+ //
+ // define the grid structure:
+ // | var structure = [ // array of view objects
+ // | { cells: [// array of rows, a row is an array of cells
+ // | [
+ // | { name: "Alpha", width: 6 },
+ // | { name: "Beta" },
+ // | { name: "Gamma", get: get }]
+ // | ]}
+ // | ];
+ //
+ // | <div id="grid"
+ // | rowCount="100" get="get"
+ // | structure="structure"
+ // | dojoType="dojox.grid._Grid"></div>
+
+ templateString: template,
+
+ // classTag: String
+ // CSS class applied to the grid's domNode
+ classTag: 'dojoxGrid',
+
+ // settings
+ // rowCount: Integer
+ // Number of rows to display.
+ rowCount: 5,
+
+ // keepRows: Integer
+ // Number of rows to keep in the rendering cache.
+ keepRows: 75,
+
+ // rowsPerPage: Integer
+ // Number of rows to render at a time.
+ rowsPerPage: 25,
+
+ // autoWidth: Boolean
+ // If autoWidth is true, grid width is automatically set to fit the data.
+ autoWidth: false,
+
+ // initialWidth: String
+ // A css string to use to set our initial width (only used if autoWidth
+ // is true). The first rendering of the grid will be this width, any
+ // resizing of columns, etc will result in the grid switching to
+ // autoWidth mode. Note, this width will override any styling in a
+ // stylesheet or directly on the node.
+ initialWidth: "",
+
+ // autoHeight: Boolean|Integer
+ // If autoHeight is true, grid height is automatically set to fit the data.
+ // If it is an integer, the height will be automatically set to fit the data
+ // if there are fewer than that many rows - and the height will be set to show
+ // that many rows if there are more
+ autoHeight: '',
+
+ // rowHeight: Integer
+ // If rowHeight is set to a positive number, it will define the height of the rows
+ // in pixels. This can provide a significant performance advantage, since it
+ // eliminates the need to measure row sizes during rendering, which is one
+ // the primary bottlenecks in the DataGrid's performance.
+ rowHeight: 0,
+
+ // autoRender: Boolean
+ // If autoRender is true, grid will render itself after initialization.
+ autoRender: true,
+
+ // defaultHeight: String
+ // default height of the grid, measured in any valid css unit.
+ defaultHeight: '15em',
+
+ // height: String
+ // explicit height of the grid, measured in any valid css unit. This will be populated (and overridden)
+ // if the height: css attribute exists on the source node.
+ height: '',
+
+ // structure: dojox.grid.__ViewDef|dojox.grid.__ViewDef[]|dojox.grid.__CellDef[]|Array[dojox.grid.__CellDef[]]
+ // View layout defintion.
+ structure: null,
+
+ // elasticView: Integer
+ // Override defaults and make the indexed grid view elastic, thus filling available horizontal space.
+ elasticView: -1,
+
+ // singleClickEdit: boolean
+ // Single-click starts editing. Default is double-click
+ singleClickEdit: false,
+
+ // selectionMode: String
+ // Set the selection mode of grid's Selection. Value must be 'single', 'multiple',
+ // or 'extended'. Default is 'extended'.
+ selectionMode: 'extended',
+
+ // rowSelector: Boolean|String
+ // If set to true, will add a row selector view to this grid. If set to a CSS width, will add
+ // a row selector of that width to this grid.
+ rowSelector: '',
+
+ // columnReordering: Boolean
+ // If set to true, will add drag and drop reordering to views with one row of columns.
+ columnReordering: false,
+
+ // headerMenu: dijit.Menu
+ // If set to a dijit.Menu, will use this as a context menu for the grid headers.
+ headerMenu: null,
+
+ // placeholderLabel: String
+ // Label of placeholders to search for in the header menu to replace with column toggling
+ // menu items.
+ placeholderLabel: "GridColumns",
+
+ // selectable: Boolean
+ // Set to true if you want to be able to select the text within the grid.
+ selectable: false,
+
+ // Used to store the last two clicks, to ensure double-clicking occurs based on the intended row
+ _click: null,
+
+ // loadingMessage: String
+ // Message that shows while the grid is loading
+ loadingMessage: "<span class='dojoxGridLoading'>${loadingState}</span>",
+
+ // errorMessage: String
+ // Message that shows when the grid encounters an error loading
+ errorMessage: "<span class='dojoxGridError'>${errorState}</span>",
+
+ // noDataMessage: String
+ // Message that shows if the grid has no data - wrap it in a
+ // span with class 'dojoxGridNoData' if you want it to be
+ // styled similar to the loading and error messages
+ noDataMessage: "",
+
+ // escapeHTMLInData: Boolean
+ // This will escape HTML brackets from the data to prevent HTML from
+ // user-inputted data being rendered with may contain JavaScript and result in
+ // XSS attacks. This is true by default, and it is recommended that it remain
+ // true. Setting this to false will allow data to be displayed in the grid without
+ // filtering, and should be only used if it is known that the data won't contain
+ // malicious scripts. If HTML is needed in grid cells, it is recommended that
+ // you use the formatter function to generate the HTML (the output of
+ // formatter functions is not filtered, even with escapeHTMLInData set to true).
+ escapeHTMLInData: true,
+
+ // formatterScope: Object
+ // An object to execute format functions within. If not set, the
+ // format functions will execute within the scope of the cell that
+ // has a format function.
+ formatterScope: null,
+
+ // editable: boolean
+ // indicates if the grid contains editable cells, default is false
+ // set to true if editable cell encountered during rendering
+ editable: false,
+
+ // private
+ sortInfo: 0,
+ themeable: true,
+ _placeholders: null,
+
+ // _layoutClass: Object
+ // The class to use for our layout - can be overridden by grid subclasses
+ _layoutClass: _Layout,
+
+ // initialization
+ buildRendering: function(){
+ this.inherited(arguments);
+ if(!this.domNode.getAttribute('tabIndex')){
+ this.domNode.tabIndex = "0";
+ }
+ this.createScroller();
+ this.createLayout();
+ this.createViews();
+ this.createManagers();
+
+ this.createSelection();
+
+ this.connect(this.selection, "onSelected", "onSelected");
+ this.connect(this.selection, "onDeselected", "onDeselected");
+ this.connect(this.selection, "onChanged", "onSelectionChanged");
+
+ metrics.initOnFontResize();
+ this.connect(metrics, "onFontResize", "textSizeChanged");
+ util.funnelEvents(this.domNode, this, 'doKeyEvent', util.keyEvents);
+ if (this.selectionMode != "none") {
+ this.domNode.setAttribute("aria-multiselectable", this.selectionMode == "single" ? "false" : "true");
+ }
+
+ html.addClass(this.domNode, this.classTag);
+ if(!this.isLeftToRight()){
+ html.addClass(this.domNode, this.classTag+"Rtl");
+ }
+ },
+
+ postMixInProperties: function(){
+ this.inherited(arguments);
+ var messages = dojo.i18n.getLocalization("dijit", "loading", this.lang);
+ this.loadingMessage = string.substitute(this.loadingMessage, messages);
+ this.errorMessage = string.substitute(this.errorMessage, messages);
+ if(this.srcNodeRef && this.srcNodeRef.style.height){
+ this.height = this.srcNodeRef.style.height;
+ }
+ // Call this to update our autoheight to start out
+ this._setAutoHeightAttr(this.autoHeight, true);
+ this.lastScrollTop = this.scrollTop = 0;
+ },
+
+ postCreate: function(){
+ this._placeholders = [];
+ this._setHeaderMenuAttr(this.headerMenu);
+ this._setStructureAttr(this.structure);
+ this._click = [];
+ this.inherited(arguments);
+ if(this.domNode && this.autoWidth && this.initialWidth){
+ this.domNode.style.width = this.initialWidth;
+ }
+ if (this.domNode && !this.editable){
+ // default value for aria-readonly is false, set to true if grid is not editable
+ html.attr(this.domNode,"aria-readonly", "true");
+ }
+ },
+
+ destroy: function(){
+ this.domNode.onReveal = null;
+ this.domNode.onSizeChange = null;
+
+ // Fixes IE domNode leak
+ delete this._click;
+
+ if(this.scroller){
+ this.scroller.destroy();
+ delete this.scroller;
+ }
+ this.edit.destroy();
+ delete this.edit;
+ this.views.destroyViews();
+ if(this.focus){
+ this.focus.destroy();
+ delete this.focus;
+ }
+ if(this.headerMenu&&this._placeholders.length){
+ array.forEach(this._placeholders, function(p){ p.unReplace(true); });
+ this.headerMenu.unBindDomNode(this.viewsHeaderNode);
+ }
+ this.inherited(arguments);
+ },
+
+ _setAutoHeightAttr: function(ah, skipRender){
+ // Calculate our autoheight - turn it into a boolean or an integer
+ if(typeof ah == "string"){
+ if(!ah || ah == "false"){
+ ah = false;
+ }else if (ah == "true"){
+ ah = true;
+ }else{
+ ah = window.parseInt(ah, 10);
+ }
+ }
+ if(typeof ah == "number"){
+ if(isNaN(ah)){
+ ah = false;
+ }
+ // Autoheight must be at least 1, if it's a number. If it's
+ // less than 0, we'll take that to mean "all" rows (same as
+ // autoHeight=true - if it is equal to zero, we'll take that
+ // to mean autoHeight=false
+ if(ah < 0){
+ ah = true;
+ }else if (ah === 0){
+ ah = false;
+ }
+ }
+ this.autoHeight = ah;
+ if(typeof ah == "boolean"){
+ this._autoHeight = ah;
+ }else if(typeof ah == "number"){
+ this._autoHeight = (ah >= this.get('rowCount'));
+ }else{
+ this._autoHeight = false;
+ }
+ if(this._started && !skipRender){
+ this.render();
+ }
+ },
+
+ _getRowCountAttr: function(){
+ return this.updating && this.invalidated && this.invalidated.rowCount != undefined ?
+ this.invalidated.rowCount : this.rowCount;
+ },
+
+ textSizeChanged: function(){
+ this.render();
+ },
+
+ sizeChange: function(){
+ this.update();
+ },
+
+ createManagers: function(){
+ // summary:
+ // create grid managers for various tasks including rows, focus, selection, editing
+
+ // row manager
+ this.rows = new _RowManager(this);
+ // focus manager
+ this.focus = new _FocusManager(this);
+ // edit manager
+ this.edit = new _EditManager(this);
+ },
+
+ createSelection: function(){
+ // summary: Creates a new Grid selection manager.
+
+ // selection manager
+ this.selection = new Selection(this);
+ },
+
+ createScroller: function(){
+ // summary: Creates a new virtual scroller
+ this.scroller = new _Scroller();
+ this.scroller.grid = this;
+ this.scroller.renderRow = lang.hitch(this, "renderRow");
+ this.scroller.removeRow = lang.hitch(this, "rowRemoved");
+ },
+
+ createLayout: function(){
+ // summary: Creates a new Grid layout
+ this.layout = new this._layoutClass(this);
+ this.connect(this.layout, "moveColumn", "onMoveColumn");
+ },
+
+ onMoveColumn: function(){
+ this.render();
+ },
+
+ onResizeColumn: function(/*int*/ cellIdx){
+ // Called when a column is resized.
+ },
+
+ // views
+ createViews: function(){
+ this.views = new _ViewManager(this);
+ this.views.createView = lang.hitch(this, "createView");
+ },
+
+ createView: function(inClass, idx){
+ var c = lang.getObject(inClass);
+ var view = new c({ grid: this, index: idx });
+ this.viewsNode.appendChild(view.domNode);
+ this.viewsHeaderNode.appendChild(view.headerNode);
+ this.views.addView(view);
+ html.attr(this.domNode, "align", this.isLeftToRight() ? 'left' : 'right');
+ return view;
+ },
+
+ buildViews: function(){
+ for(var i=0, vs; (vs=this.layout.structure[i]); i++){
+ this.createView(vs.type || dojox._scopeName + ".grid._View", i).setStructure(vs);
+ }
+ this.scroller.setContentNodes(this.views.getContentNodes());
+ },
+
+ _setStructureAttr: function(structure){
+ var s = structure;
+ if(s && lang.isString(s)){
+ dojo.deprecated("dojox.grid._Grid.set('structure', 'objVar')", "use dojox.grid._Grid.set('structure', objVar) instead", "2.0");
+ s=lang.getObject(s);
+ }
+ this.structure = s;
+ if(!s){
+ if(this.layout.structure){
+ s = this.layout.structure;
+ }else{
+ return;
+ }
+ }
+ this.views.destroyViews();
+ this.focus.focusView = null;
+ if(s !== this.layout.structure){
+ this.layout.setStructure(s);
+ }
+ this._structureChanged();
+ },
+
+ setStructure: function(/* dojox.grid.__ViewDef|dojox.grid.__ViewDef[]|dojox.grid.__CellDef[]|Array[dojox.grid.__CellDef[]] */ inStructure){
+ // summary:
+ // Install a new structure and rebuild the grid.
+ dojo.deprecated("dojox.grid._Grid.setStructure(obj)", "use dojox.grid._Grid.set('structure', obj) instead.", "2.0");
+ this._setStructureAttr(inStructure);
+ },
+
+ getColumnTogglingItems: function(){
+ // Summary: returns an array of dijit.CheckedMenuItem widgets that can be
+ // added to a menu for toggling columns on and off.
+ var items, checkedItems = [];
+ items = array.map(this.layout.cells, function(cell){
+ if(!cell.menuItems){ cell.menuItems = []; }
+
+ var self = this;
+ var item = new CheckedMenuItem({
+ label: cell.name,
+ checked: !cell.hidden,
+ _gridCell: cell,
+ onChange: function(checked){
+ if(self.layout.setColumnVisibility(this._gridCell.index, checked)){
+ var items = this._gridCell.menuItems;
+ if(items.length > 1){
+ array.forEach(items, function(item){
+ if(item !== this){
+ item.setAttribute("checked", checked);
+ }
+ }, this);
+ }
+ checked = array.filter(self.layout.cells, function(c){
+ if(c.menuItems.length > 1){
+ array.forEach(c.menuItems, "item.set('disabled', false);");
+ }else{
+ c.menuItems[0].set('disabled', false);
+ }
+ return !c.hidden;
+ });
+ if(checked.length == 1){
+ array.forEach(checked[0].menuItems, "item.set('disabled', true);");
+ }
+ }
+ },
+ destroy: function(){
+ var index = array.indexOf(this._gridCell.menuItems, this);
+ this._gridCell.menuItems.splice(index, 1);
+ delete this._gridCell;
+ CheckedMenuItem.prototype.destroy.apply(this, arguments);
+ }
+ });
+ cell.menuItems.push(item);
+ if(!cell.hidden) {
+ checkedItems.push(item);
+ }
+ return item;
+ }, this); // dijit.CheckedMenuItem[]
+ if(checkedItems.length == 1) {
+ checkedItems[0].set('disabled', true);
+ }
+ return items;
+ },
+
+ _setHeaderMenuAttr: function(menu){
+ if(this._placeholders && this._placeholders.length){
+ array.forEach(this._placeholders, function(p){
+ p.unReplace(true);
+ });
+ this._placeholders = [];
+ }
+ if(this.headerMenu){
+ this.headerMenu.unBindDomNode(this.viewsHeaderNode);
+ }
+ this.headerMenu = menu;
+ if(!menu){ return; }
+
+ this.headerMenu.bindDomNode(this.viewsHeaderNode);
+ if(this.headerMenu.getPlaceholders){
+ this._placeholders = this.headerMenu.getPlaceholders(this.placeholderLabel);
+ }
+ },
+
+ setHeaderMenu: function(/* dijit.Menu */ menu){
+ dojo.deprecated("dojox.grid._Grid.setHeaderMenu(obj)", "use dojox.grid._Grid.set('headerMenu', obj) instead.", "2.0");
+ this._setHeaderMenuAttr(menu);
+ },
+
+ setupHeaderMenu: function(){
+ if(this._placeholders && this._placeholders.length){
+ array.forEach(this._placeholders, function(p){
+ if(p._replaced){
+ p.unReplace(true);
+ }
+ p.replace(this.getColumnTogglingItems());
+ }, this);
+ }
+ },
+
+ _fetch: function(start){
+ this.setScrollTop(0);
+ },
+
+ getItem: function(inRowIndex){
+ return null;
+ },
+
+ showMessage: function(message){
+ if(message){
+ this.messagesNode.innerHTML = message;
+ this.messagesNode.style.display = "";
+ }else{
+ this.messagesNode.innerHTML = "";
+ this.messagesNode.style.display = "none";
+ }
+ },
+
+ _structureChanged: function() {
+ this.buildViews();
+ if(this.autoRender && this._started){
+ this.render();
+ }
+ },
+
+ hasLayout: function() {
+ return this.layout.cells.length;
+ },
+
+ // sizing
+ resize: function(changeSize, resultSize){
+ // summary:
+ // Update the grid's rendering dimensions and resize it
+
+ // Calling sizeChange calls update() which calls _resize...so let's
+ // save our input values, if any, and use them there when it gets
+ // called. This saves us an extra call to _resize(), which can
+ // get kind of heavy.
+
+ // fixes #11101, should ignore resize when in autoheight mode(IE) to avoid a deadlock
+ // e.g when an autoheight editable grid put in dijit.form.Form or other similar containers,
+ // grid switch to editing mode --> grid height change --> From height change
+ // ---> Form call grid.resize() ---> grid height change --> deaklock
+ if(dojo.isIE && !changeSize && !resultSize && this._autoHeight){
+ return;
+ }
+ this._pendingChangeSize = changeSize;
+ this._pendingResultSize = resultSize;
+ this.sizeChange();
+ },
+
+ _getPadBorder: function() {
+ this._padBorder = this._padBorder || html._getPadBorderExtents(this.domNode);
+ return this._padBorder;
+ },
+
+ _getHeaderHeight: function(){
+ var vns = this.viewsHeaderNode.style, t = vns.display == "none" ? 0 : this.views.measureHeader();
+ vns.height = t + 'px';
+ // header heights are reset during measuring so must be normalized after measuring.
+ this.views.normalizeHeaderNodeHeight();
+ return t;
+ },
+
+ _resize: function(changeSize, resultSize){
+ // Restore our pending values, if any
+ changeSize = changeSize || this._pendingChangeSize;
+ resultSize = resultSize || this._pendingResultSize;
+ delete this._pendingChangeSize;
+ delete this._pendingResultSize;
+ // if we have set up everything except the DOM, we cannot resize
+ if(!this.domNode){ return; }
+ var pn = this.domNode.parentNode;
+ if(!pn || pn.nodeType != 1 || !this.hasLayout() || pn.style.visibility == "hidden" || pn.style.display == "none"){
+ return;
+ }
+ // useful measurement
+ var padBorder = this._getPadBorder();
+ var hh = undefined;
+ var h;
+ // grid height
+ if(this._autoHeight){
+ this.domNode.style.height = 'auto';
+ }else if(typeof this.autoHeight == "number"){
+ h = hh = this._getHeaderHeight();
+ h += (this.scroller.averageRowHeight * this.autoHeight);
+ this.domNode.style.height = h + "px";
+ }else if(this.domNode.clientHeight <= padBorder.h){
+ if(pn == document.body){
+ this.domNode.style.height = this.defaultHeight;
+ }else if(this.height){
+ this.domNode.style.height = this.height;
+ }else{
+ this.fitTo = "parent";
+ }
+ }
+ // if we are given dimensions, size the grid's domNode to those dimensions
+ if(resultSize){
+ changeSize = resultSize;
+ }
+ if(!this._autoHeight && changeSize){
+ html.marginBox(this.domNode, changeSize);
+ this.height = this.domNode.style.height;
+ delete this.fitTo;
+ }else if(this.fitTo == "parent"){
+ h = this._parentContentBoxHeight = this._parentContentBoxHeight || html._getContentBox(pn).h;
+ this.domNode.style.height = Math.max(0, h) + "px";
+ }
+
+ var hasFlex = array.some(this.views.views, function(v){ return v.flexCells; });
+
+ if(!this._autoHeight && (h || html._getContentBox(this.domNode).h) === 0){
+ // We need to hide the header, since the Grid is essentially hidden.
+ this.viewsHeaderNode.style.display = "none";
+ }else{
+ // Otherwise, show the header and give it an appropriate height.
+ this.viewsHeaderNode.style.display = "block";
+ if(!hasFlex && hh === undefined){
+ hh = this._getHeaderHeight();
+ }
+ }
+ if(hasFlex){
+ hh = undefined;
+ }
+
+ // NOTE: it is essential that width be applied before height
+ // Header height can only be calculated properly after view widths have been set.
+ // This is because flex column width is naturally 0 in Firefox.
+ // Therefore prior to width sizing flex columns with spaces are maximally wrapped
+ // and calculated to be too tall.
+ this.adaptWidth();
+ this.adaptHeight(hh);
+
+ this.postresize();
+ },
+
+ adaptWidth: function() {
+ // private: sets width and position for views and update grid width if necessary
+ var doAutoWidth = (!this.initialWidth && this.autoWidth);
+ var w = doAutoWidth ? 0 : this.domNode.clientWidth || (this.domNode.offsetWidth - this._getPadBorder().w),
+ vw = this.views.arrange(1, w);
+ this.views.onEach("adaptWidth");
+ if(doAutoWidth){
+ this.domNode.style.width = vw + "px";
+ }
+ },
+
+ adaptHeight: function(inHeaderHeight){
+ // private: measures and normalizes header height, then sets view heights, and then updates scroller
+ // content extent
+ var t = inHeaderHeight === undefined ? this._getHeaderHeight() : inHeaderHeight;
+ var h = (this._autoHeight ? -1 : Math.max(this.domNode.clientHeight - t, 0) || 0);
+ this.views.onEach('setSize', [0, h]);
+ this.views.onEach('adaptHeight');
+ if(!this._autoHeight){
+ var numScroll = 0, numNoScroll = 0;
+ var noScrolls = array.filter(this.views.views, function(v){
+ var has = v.hasHScrollbar();
+ if(has){ numScroll++; }else{ numNoScroll++; }
+ return (!has);
+ });
+ if(numScroll > 0 && numNoScroll > 0){
+ array.forEach(noScrolls, function(v){
+ v.adaptHeight(true);
+ });
+ }
+ }
+ if(this.autoHeight === true || h != -1 || (typeof this.autoHeight == "number" && this.autoHeight >= this.get('rowCount'))){
+ this.scroller.windowHeight = h;
+ }else{
+ this.scroller.windowHeight = Math.max(this.domNode.clientHeight - t, 0);
+ }
+ },
+
+ // startup
+ startup: function(){
+ if(this._started){return;}
+ this.inherited(arguments);
+ if(this.autoRender){
+ this.render();
+ }
+ },
+
+ // render
+ render: function(){
+ // summary:
+ // Render the grid, headers, and views. Edit and scrolling states are reset. To retain edit and
+ // scrolling states, see Update.
+
+ if(!this.domNode){return;}
+ if(!this._started){return;}
+
+ if(!this.hasLayout()) {
+ this.scroller.init(0, this.keepRows, this.rowsPerPage);
+ return;
+ }
+ //
+ this.update = this.defaultUpdate;
+ this._render();
+ },
+
+ _render: function(){
+ this.scroller.init(this.get('rowCount'), this.keepRows, this.rowsPerPage);
+ this.prerender();
+ this.setScrollTop(0);
+ this.postrender();
+ },
+
+ prerender: function(){
+ // if autoHeight, make sure scroller knows not to virtualize; everything must be rendered.
+ this.keepRows = this._autoHeight ? 0 : this.keepRows;
+ this.scroller.setKeepInfo(this.keepRows);
+ this.views.render();
+ this._resize();
+ },
+
+ postrender: function(){
+ this.postresize();
+ this.focus.initFocusView();
+ // make rows unselectable
+ html.setSelectable(this.domNode, this.selectable);
+ },
+
+ postresize: function(){
+ // views are position absolute, so they do not inflate the parent
+ if(this._autoHeight){
+ var size = Math.max(this.views.measureContent()) + 'px';
+
+ this.viewsNode.style.height = size;
+ }
+ },
+
+ renderRow: function(inRowIndex, inNodes){
+ // summary: private, used internally to render rows
+ this.views.renderRow(inRowIndex, inNodes, this._skipRowRenormalize);
+ },
+
+ rowRemoved: function(inRowIndex){
+ // summary: private, used internally to remove rows
+ this.views.rowRemoved(inRowIndex);
+ },
+
+ invalidated: null,
+
+ updating: false,
+
+ beginUpdate: function(){
+ // summary:
+ // Use to make multiple changes to rows while queueing row updating.
+ // NOTE: not currently supporting nested begin/endUpdate calls
+ this.invalidated = [];
+ this.updating = true;
+ },
+
+ endUpdate: function(){
+ // summary:
+ // Use after calling beginUpdate to render any changes made to rows.
+ this.updating = false;
+ var i = this.invalidated, r;
+ if(i.all){
+ this.update();
+ }else if(i.rowCount != undefined){
+ this.updateRowCount(i.rowCount);
+ }else{
+ for(r in i){
+ this.updateRow(Number(r));
+ }
+ }
+ this.invalidated = [];
+ },
+
+ // update
+ defaultUpdate: function(){
+ // note: initial update calls render and subsequently this function.
+ if(!this.domNode){return;}
+ if(this.updating){
+ this.invalidated.all = true;
+ return;
+ }
+ //this.edit.saveState(inRowIndex);
+ this.lastScrollTop = this.scrollTop;
+ this.prerender();
+ this.scroller.invalidateNodes();
+ this.setScrollTop(this.lastScrollTop);
+ this.postrender();
+ //this.edit.restoreState(inRowIndex);
+ },
+
+ update: function(){
+ // summary:
+ // Update the grid, retaining edit and scrolling states.
+ this.render();
+ },
+
+ updateRow: function(inRowIndex){
+ // summary:
+ // Render a single row.
+ // inRowIndex: Integer
+ // Index of the row to render
+ inRowIndex = Number(inRowIndex);
+ if(this.updating){
+ this.invalidated[inRowIndex]=true;
+ }else{
+ this.views.updateRow(inRowIndex);
+ this.scroller.rowHeightChanged(inRowIndex);
+ }
+ },
+
+ updateRows: function(startIndex, howMany){
+ // summary:
+ // Render consecutive rows at once.
+ // startIndex: Integer
+ // Index of the starting row to render
+ // howMany: Integer
+ // How many rows to update.
+ startIndex = Number(startIndex);
+ howMany = Number(howMany);
+ var i;
+ if(this.updating){
+ for(i=0; i<howMany; i++){
+ this.invalidated[i+startIndex]=true;
+ }
+ }else{
+ for(i=0; i<howMany; i++){
+ this.views.updateRow(i+startIndex, this._skipRowRenormalize);
+ }
+ this.scroller.rowHeightChanged(startIndex);
+ }
+ },
+
+ updateRowCount: function(inRowCount){
+ //summary:
+ // Change the number of rows.
+ // inRowCount: int
+ // Number of rows in the grid.
+ if(this.updating){
+ this.invalidated.rowCount = inRowCount;
+ }else{
+ this.rowCount = inRowCount;
+ this._setAutoHeightAttr(this.autoHeight, true);
+ if(this.layout.cells.length){
+ this.scroller.updateRowCount(inRowCount);
+ }
+ this._resize();
+ if(this.layout.cells.length){
+ this.setScrollTop(this.scrollTop);
+ }
+ }
+ },
+
+ updateRowStyles: function(inRowIndex){
+ // summary:
+ // Update the styles for a row after it's state has changed.
+ this.views.updateRowStyles(inRowIndex);
+ },
+ getRowNode: function(inRowIndex){
+ // summary:
+ // find the rowNode that is not a rowSelector
+ if (this.focus.focusView && !(this.focus.focusView instanceof _RowSelector)){
+ return this.focus.focusView.rowNodes[inRowIndex];
+ }else{ // search through views
+ for (var i = 0, cView; (cView = this.views.views[i]); i++) {
+ if (!(cView instanceof _RowSelector)) {
+ return cView.rowNodes[inRowIndex];
+ }
+ }
+ }
+ return null;
+ },
+ rowHeightChanged: function(inRowIndex){
+ // summary:
+ // Update grid when the height of a row has changed. Row height is handled automatically as rows
+ // are rendered. Use this function only to update a row's height outside the normal rendering process.
+ // inRowIndex: Integer
+ // index of the row that has changed height
+
+ this.views.renormalizeRow(inRowIndex);
+ this.scroller.rowHeightChanged(inRowIndex);
+ },
+
+ // fastScroll: Boolean
+ // flag modifies vertical scrolling behavior. Defaults to true but set to false for slower
+ // scroll performance but more immediate scrolling feedback
+ fastScroll: true,
+
+ delayScroll: false,
+
+ // scrollRedrawThreshold: int
+ // pixel distance a user must scroll vertically to trigger grid scrolling.
+ scrollRedrawThreshold: (has("ie") ? 100 : 50),
+
+ // scroll methods
+ scrollTo: function(inTop){
+ // summary:
+ // Vertically scroll the grid to a given pixel position
+ // inTop: Integer
+ // vertical position of the grid in pixels
+ if(!this.fastScroll){
+ this.setScrollTop(inTop);
+ return;
+ }
+ var delta = Math.abs(this.lastScrollTop - inTop);
+ this.lastScrollTop = inTop;
+ if(delta > this.scrollRedrawThreshold || this.delayScroll){
+ this.delayScroll = true;
+ this.scrollTop = inTop;
+ this.views.setScrollTop(inTop);
+ if(this._pendingScroll){
+ window.clearTimeout(this._pendingScroll);
+ }
+ var _this = this;
+ this._pendingScroll = window.setTimeout(function(){
+ delete _this._pendingScroll;
+ _this.finishScrollJob();
+ }, 200);
+ }else{
+ this.setScrollTop(inTop);
+ }
+ },
+
+ finishScrollJob: function(){
+ this.delayScroll = false;
+ this.setScrollTop(this.scrollTop);
+ },
+
+ setScrollTop: function(inTop){
+ this.scroller.scroll(this.views.setScrollTop(inTop));
+ },
+
+ scrollToRow: function(inRowIndex){
+ // summary:
+ // Scroll the grid to a specific row.
+ // inRowIndex: Integer
+ // grid row index
+ this.setScrollTop(this.scroller.findScrollTop(inRowIndex) + 1);
+ },
+
+ // styling (private, used internally to style individual parts of a row)
+ styleRowNode: function(inRowIndex, inRowNode){
+ if(inRowNode){
+ this.rows.styleRowNode(inRowIndex, inRowNode);
+ }
+ },
+
+ // called when the mouse leaves the grid so we can deselect all hover rows
+ _mouseOut: function(e){
+ this.rows.setOverRow(-2);
+ },
+
+ // cells
+ getCell: function(inIndex){
+ // summary:
+ // Retrieves the cell object for a given grid column.
+ // inIndex: Integer
+ // Grid column index of cell to retrieve
+ // returns:
+ // a grid cell
+ return this.layout.cells[inIndex];
+ },
+
+ setCellWidth: function(inIndex, inUnitWidth){
+ this.getCell(inIndex).unitWidth = inUnitWidth;
+ },
+
+ getCellName: function(inCell){
+ // summary: Returns the cell name of a passed cell
+ return "Cell " + inCell.index; // String
+ },
+
+ // sorting
+ canSort: function(inSortInfo){
+ // summary:
+ // Determines if the grid can be sorted
+ // inSortInfo: Integer
+ // Sort information, 1-based index of column on which to sort, positive for an ascending sort
+ // and negative for a descending sort
+ // returns: Boolean
+ // True if grid can be sorted on the given column in the given direction
+ },
+
+ sort: function(){
+ },
+
+ getSortAsc: function(inSortInfo){
+ // summary:
+ // Returns true if grid is sorted in an ascending direction.
+ inSortInfo = inSortInfo == undefined ? this.sortInfo : inSortInfo;
+ return Boolean(inSortInfo > 0); // Boolean
+ },
+
+ getSortIndex: function(inSortInfo){
+ // summary:
+ // Returns the index of the column on which the grid is sorted
+ inSortInfo = inSortInfo == undefined ? this.sortInfo : inSortInfo;
+ return Math.abs(inSortInfo) - 1; // Integer
+ },
+
+ setSortIndex: function(inIndex, inAsc){
+ // summary:
+ // Sort the grid on a column in a specified direction
+ // inIndex: Integer
+ // Column index on which to sort.
+ // inAsc: Boolean
+ // If true, sort the grid in ascending order, otherwise in descending order
+ var si = inIndex +1;
+ if(inAsc != undefined){
+ si *= (inAsc ? 1 : -1);
+ } else if(this.getSortIndex() == inIndex){
+ si = -this.sortInfo;
+ }
+ this.setSortInfo(si);
+ },
+
+ setSortInfo: function(inSortInfo){
+ if(this.canSort(inSortInfo)){
+ this.sortInfo = inSortInfo;
+ this.sort();
+ this.update();
+ }
+ },
+
+ // DOM event handler
+ doKeyEvent: function(e){
+ e.dispatch = 'do' + e.type;
+ this.onKeyEvent(e);
+ },
+
+ // event dispatch
+ //: protected
+ _dispatch: function(m, e){
+ if(m in this){
+ return this[m](e);
+ }
+ return false;
+ },
+
+ dispatchKeyEvent: function(e){
+ this._dispatch(e.dispatch, e);
+ },
+
+ dispatchContentEvent: function(e){
+ this.edit.dispatchEvent(e) || e.sourceView.dispatchContentEvent(e) || this._dispatch(e.dispatch, e);
+ },
+
+ dispatchHeaderEvent: function(e){
+ e.sourceView.dispatchHeaderEvent(e) || this._dispatch('doheader' + e.type, e);
+ },
+
+ dokeydown: function(e){
+ this.onKeyDown(e);
+ },
+
+ doclick: function(e){
+ if(e.cellNode){
+ this.onCellClick(e);
+ }else{
+ this.onRowClick(e);
+ }
+ },
+
+ dodblclick: function(e){
+ if(e.cellNode){
+ this.onCellDblClick(e);
+ }else{
+ this.onRowDblClick(e);
+ }
+ },
+
+ docontextmenu: function(e){
+ if(e.cellNode){
+ this.onCellContextMenu(e);
+ }else{
+ this.onRowContextMenu(e);
+ }
+ },
+
+ doheaderclick: function(e){
+ if(e.cellNode){
+ this.onHeaderCellClick(e);
+ }else{
+ this.onHeaderClick(e);
+ }
+ },
+
+ doheaderdblclick: function(e){
+ if(e.cellNode){
+ this.onHeaderCellDblClick(e);
+ }else{
+ this.onHeaderDblClick(e);
+ }
+ },
+
+ doheadercontextmenu: function(e){
+ if(e.cellNode){
+ this.onHeaderCellContextMenu(e);
+ }else{
+ this.onHeaderContextMenu(e);
+ }
+ },
+
+ // override to modify editing process
+ doStartEdit: function(inCell, inRowIndex){
+ this.onStartEdit(inCell, inRowIndex);
+ },
+
+ doApplyCellEdit: function(inValue, inRowIndex, inFieldIndex){
+ this.onApplyCellEdit(inValue, inRowIndex, inFieldIndex);
+ },
+
+ doCancelEdit: function(inRowIndex){
+ this.onCancelEdit(inRowIndex);
+ },
+
+ doApplyEdit: function(inRowIndex){
+ this.onApplyEdit(inRowIndex);
+ },
+
+ // row editing
+ addRow: function(){
+ // summary:
+ // Add a row to the grid.
+ this.updateRowCount(this.get('rowCount')+1);
+ },
+
+ removeSelectedRows: function(){
+ // summary:
+ // Remove the selected rows from the grid.
+ if(this.allItemsSelected){
+ this.updateRowCount(0);
+ }else{
+ this.updateRowCount(Math.max(0, this.get('rowCount') - this.selection.getSelected().length));
+ }
+ this.selection.clear();
+ }
+
+ });
+
+ _Grid.markupFactory = function(props, node, ctor, cellFunc){
+ var widthFromAttr = function(n){
+ var w = html.attr(n, "width")||"auto";
+ if((w != "auto")&&(w.slice(-2) != "em")&&(w.slice(-1) != "%")){
+ w = parseInt(w, 10)+"px";
+ }
+ return w;
+ };
+ // if(!props.store){ console.debug("no store!"); }
+ // if a structure isn't referenced, do we have enough
+ // data to try to build one automatically?
+ if( !props.structure &&
+ node.nodeName.toLowerCase() == "table"){
+
+ // try to discover a structure
+ props.structure = query("> colgroup", node).map(function(cg){
+ var sv = html.attr(cg, "span");
+ var v = {
+ noscroll: (html.attr(cg, "noscroll") == "true") ? true : false,
+ __span: (!!sv ? parseInt(sv, 10) : 1),
+ cells: []
+ };
+ if(html.hasAttr(cg, "width")){
+ v.width = widthFromAttr(cg);
+ }
+ return v; // for vendetta
+ });
+ if(!props.structure.length){
+ props.structure.push({
+ __span: Infinity,
+ cells: [] // catch-all view
+ });
+ }
+ // check to see if we're gonna have more than one view
+
+ // for each tr in our th, create a row of cells
+ query("thead > tr", node).forEach(function(tr, tr_idx){
+ var cellCount = 0;
+ var viewIdx = 0;
+ var lastViewIdx;
+ var cView = null;
+ query("> th", tr).map(function(th){
+ // what view will this cell go into?
+
+ // NOTE:
+ // to prevent extraneous iteration, we start counters over
+ // for each row, incrementing over the surface area of the
+ // structure that colgroup processing generates and
+ // creating cell objects for each <th> to place into those
+ // cell groups. There's a lot of state-keepking logic
+ // here, but it is what it has to be.
+ if(!cView){ // current view book keeping
+ lastViewIdx = 0;
+ cView = props.structure[0];
+ }else if(cellCount >= (lastViewIdx+cView.__span)){
+ viewIdx++;
+ // move to allocating things into the next view
+ lastViewIdx += cView.__span;
+ var lastView = cView;
+ cView = props.structure[viewIdx];
+ }
+
+ // actually define the cell from what markup hands us
+ var cell = {
+ name: lang.trim(html.attr(th, "name")||th.innerHTML),
+ colSpan: parseInt(html.attr(th, "colspan")||1, 10),
+ type: lang.trim(html.attr(th, "cellType")||""),
+ id: lang.trim(html.attr(th,"id")||"")
+ };
+ cellCount += cell.colSpan;
+ var rowSpan = html.attr(th, "rowspan");
+ if(rowSpan){
+ cell.rowSpan = rowSpan;
+ }
+ if(html.hasAttr(th, "width")){
+ cell.width = widthFromAttr(th);
+ }
+ if(html.hasAttr(th, "relWidth")){
+ cell.relWidth = window.parseInt(html.attr(th, "relWidth"), 10);
+ }
+ if(html.hasAttr(th, "hidden")){
+ cell.hidden = (html.attr(th, "hidden") == "true" || html.attr(th, "hidden") === true/*always boolean true in Chrome*/);
+ }
+
+ if(cellFunc){
+ cellFunc(th, cell);
+ }
+
+ cell.type = cell.type ? lang.getObject(cell.type) : dojox.grid.cells.Cell;
+
+ if(cell.type && cell.type.markupFactory){
+ cell.type.markupFactory(th, cell);
+ }
+
+ if(!cView.cells[tr_idx]){
+ cView.cells[tr_idx] = [];
+ }
+ cView.cells[tr_idx].push(cell);
+ });
+ });
+ }
+
+ return new ctor(props, node);
+ };
+
+ return _Grid;
+
+});
+},
+'dijit/nls/loading':function(){
+define("dijit/nls/loading", { root:
+//begin v1.x content
+({
+ loadingState: "Loading...",
+ errorState: "Sorry, an error occurred"
+})
+//end v1.x content
+,
+"zh": true,
+"zh-tw": true,
+"tr": true,
+"th": true,
+"sv": true,
+"sl": true,
+"sk": true,
+"ru": true,
+"ro": true,
+"pt": true,
+"pt-pt": true,
+"pl": true,
+"nl": true,
+"nb": true,
+"ko": true,
+"kk": true,
+"ja": true,
+"it": true,
+"hu": true,
+"hr": true,
+"he": true,
+"fr": true,
+"fi": true,
+"es": true,
+"el": true,
+"de": true,
+"da": true,
+"cs": true,
+"ca": true,
+"az": true,
+"ar": true
+});
+
+},
+'dojox/main':function(){
+define("dojox/main", ["dojo/_base/kernel"], function(dojo) {
+ // module:
+ // dojox/main
+ // summary:
+ // The dojox package main module; dojox package is somewhat unusual in that the main module currently just provides an empty object.
+
+ return dojo.dojox;
+});
+},
+'dojo/dnd/Mover':function(){
+define(["../main", "../Evented", "../touch", "./common", "./autoscroll"], function(dojo, Evented, touch) {
+ // module:
+ // dojo/dnd/Mover
+ // summary:
+ // TODOC
+
+
+dojo.declare("dojo.dnd.Mover", [Evented], {
+ constructor: function(node, e, host){
+ // summary:
+ // an object which makes a node follow the mouse, or touch-drag on touch devices.
+ // Used as a default mover, and as a base class for custom movers.
+ // node: Node
+ // a node (or node's id) to be moved
+ // e: Event
+ // a mouse event, which started the move;
+ // only pageX and pageY properties are used
+ // host: Object?
+ // object which implements the functionality of the move,
+ // and defines proper events (onMoveStart and onMoveStop)
+ this.node = dojo.byId(node);
+ this.marginBox = {l: e.pageX, t: e.pageY};
+ this.mouseButton = e.button;
+ var h = (this.host = host), d = node.ownerDocument;
+ this.events = [
+ // At the start of a drag, onFirstMove is called, and then the following two
+ // connects are disconnected
+ dojo.connect(d, touch.move, this, "onFirstMove"),
+
+ // These are called continually during the drag
+ dojo.connect(d, touch.move, this, "onMouseMove"),
+
+ // And these are called at the end of the drag
+ dojo.connect(d, touch.release, this, "onMouseUp"),
+
+ // cancel text selection and text dragging
+ dojo.connect(d, "ondragstart", dojo.stopEvent),
+ dojo.connect(d.body, "onselectstart", dojo.stopEvent)
+ ];
+ // notify that the move has started
+ if(h && h.onMoveStart){
+ h.onMoveStart(this);
+ }
+ },
+ // mouse event processors
+ onMouseMove: function(e){
+ // summary:
+ // event processor for onmousemove/ontouchmove
+ // e: Event
+ // mouse/touch event
+ dojo.dnd.autoScroll(e);
+ var m = this.marginBox;
+ this.host.onMove(this, {l: m.l + e.pageX, t: m.t + e.pageY}, e);
+ dojo.stopEvent(e);
+ },
+ onMouseUp: function(e){
+ if(dojo.isWebKit && dojo.isMac && this.mouseButton == 2 ?
+ e.button == 0 : this.mouseButton == e.button){ // TODO Should condition be met for touch devices, too?
+ this.destroy();
+ }
+ dojo.stopEvent(e);
+ },
+ // utilities
+ onFirstMove: function(e){
+ // summary:
+ // makes the node absolute; it is meant to be called only once.
+ // relative and absolutely positioned nodes are assumed to use pixel units
+ var s = this.node.style, l, t, h = this.host;
+ switch(s.position){
+ case "relative":
+ case "absolute":
+ // assume that left and top values are in pixels already
+ l = Math.round(parseFloat(s.left)) || 0;
+ t = Math.round(parseFloat(s.top)) || 0;
+ break;
+ default:
+ s.position = "absolute"; // enforcing the absolute mode
+ var m = dojo.marginBox(this.node);
+ // event.pageX/pageY (which we used to generate the initial
+ // margin box) includes padding and margin set on the body.
+ // However, setting the node's position to absolute and then
+ // doing dojo.marginBox on it *doesn't* take that additional
+ // space into account - so we need to subtract the combined
+ // padding and margin. We use getComputedStyle and
+ // _getMarginBox/_getContentBox to avoid the extra lookup of
+ // the computed style.
+ var b = dojo.doc.body;
+ var bs = dojo.getComputedStyle(b);
+ var bm = dojo._getMarginBox(b, bs);
+ var bc = dojo._getContentBox(b, bs);
+ l = m.l - (bc.l - bm.l);
+ t = m.t - (bc.t - bm.t);
+ break;
+ }
+ this.marginBox.l = l - this.marginBox.l;
+ this.marginBox.t = t - this.marginBox.t;
+ if(h && h.onFirstMove){
+ h.onFirstMove(this, e);
+ }
+
+ // Disconnect onmousemove and ontouchmove events that call this function
+ dojo.disconnect(this.events.shift());
+ },
+ destroy: function(){
+ // summary:
+ // stops the move, deletes all references, so the object can be garbage-collected
+ dojo.forEach(this.events, dojo.disconnect);
+ // undo global settings
+ var h = this.host;
+ if(h && h.onMoveStop){
+ h.onMoveStop(this);
+ }
+ // destroy objects
+ this.events = this.node = this.host = null;
+ }
+});
+
+return dojo.dnd.Mover;
+});
+
+},
+'dojo/Stateful':function(){
+define(["./_base/kernel", "./_base/declare", "./_base/lang", "./_base/array"], function(dojo, declare, lang, array) {
+ // module:
+ // dojo/Stateful
+ // summary:
+ // TODOC
+
+return dojo.declare("dojo.Stateful", null, {
+ // summary:
+ // Base class for objects that provide named properties with optional getter/setter
+ // control and the ability to watch for property changes
+ // example:
+ // | var obj = new dojo.Stateful();
+ // | obj.watch("foo", function(){
+ // | console.log("foo changed to " + this.get("foo"));
+ // | });
+ // | obj.set("foo","bar");
+ postscript: function(mixin){
+ if(mixin){
+ lang.mixin(this, mixin);
+ }
+ },
+
+ get: function(/*String*/name){
+ // summary:
+ // Get a property on a Stateful instance.
+ // name:
+ // The property to get.
+ // returns:
+ // The property value on this Stateful instance.
+ // description:
+ // Get a named property on a Stateful object. The property may
+ // potentially be retrieved via a getter method in subclasses. In the base class
+ // this just retrieves the object's property.
+ // For example:
+ // | stateful = new dojo.Stateful({foo: 3});
+ // | stateful.get("foo") // returns 3
+ // | stateful.foo // returns 3
+
+ return this[name]; //Any
+ },
+ set: function(/*String*/name, /*Object*/value){
+ // summary:
+ // Set a property on a Stateful instance
+ // name:
+ // The property to set.
+ // value:
+ // The value to set in the property.
+ // returns:
+ // The function returns this dojo.Stateful instance.
+ // description:
+ // Sets named properties on a stateful object and notifies any watchers of
+ // the property. A programmatic setter may be defined in subclasses.
+ // For example:
+ // | stateful = new dojo.Stateful();
+ // | stateful.watch(function(name, oldValue, value){
+ // | // this will be called on the set below
+ // | }
+ // | stateful.set(foo, 5);
+ //
+ // set() may also be called with a hash of name/value pairs, ex:
+ // | myObj.set({
+ // | foo: "Howdy",
+ // | bar: 3
+ // | })
+ // This is equivalent to calling set(foo, "Howdy") and set(bar, 3)
+ if(typeof name === "object"){
+ for(var x in name){
+ this.set(x, name[x]);
+ }
+ return this;
+ }
+ var oldValue = this[name];
+ this[name] = value;
+ if(this._watchCallbacks){
+ this._watchCallbacks(name, oldValue, value);
+ }
+ return this; //dojo.Stateful
+ },
+ watch: function(/*String?*/name, /*Function*/callback){
+ // summary:
+ // Watches a property for changes
+ // name:
+ // Indicates the property to watch. This is optional (the callback may be the
+ // only parameter), and if omitted, all the properties will be watched
+ // returns:
+ // An object handle for the watch. The unwatch method of this object
+ // can be used to discontinue watching this property:
+ // | var watchHandle = obj.watch("foo", callback);
+ // | watchHandle.unwatch(); // callback won't be called now
+ // callback:
+ // The function to execute when the property changes. This will be called after
+ // the property has been changed. The callback will be called with the |this|
+ // set to the instance, the first argument as the name of the property, the
+ // second argument as the old value and the third argument as the new value.
+
+ var callbacks = this._watchCallbacks;
+ if(!callbacks){
+ var self = this;
+ callbacks = this._watchCallbacks = function(name, oldValue, value, ignoreCatchall){
+ var notify = function(propertyCallbacks){
+ if(propertyCallbacks){
+ propertyCallbacks = propertyCallbacks.slice();
+ for(var i = 0, l = propertyCallbacks.length; i < l; i++){
+ try{
+ propertyCallbacks[i].call(self, name, oldValue, value);
+ }catch(e){
+ console.error(e);
+ }
+ }
+ }
+ };
+ notify(callbacks['_' + name]);
+ if(!ignoreCatchall){
+ notify(callbacks["*"]); // the catch-all
+ }
+ }; // we use a function instead of an object so it will be ignored by JSON conversion
+ }
+ if(!callback && typeof name === "function"){
+ callback = name;
+ name = "*";
+ }else{
+ // prepend with dash to prevent name conflicts with function (like "name" property)
+ name = '_' + name;
+ }
+ var propertyCallbacks = callbacks[name];
+ if(typeof propertyCallbacks !== "object"){
+ propertyCallbacks = callbacks[name] = [];
+ }
+ propertyCallbacks.push(callback);
+ return {
+ unwatch: function(){
+ propertyCallbacks.splice(array.indexOf(propertyCallbacks, callback), 1);
+ }
+ }; //Object
+ }
+
+});
+
+});
+
+},
+'dojo/touch':function(){
+define(["./_base/kernel", "./on", "./has", "./mouse"], function(dojo, on, has, mouse){
+// module:
+// dojo/touch
+
+/*=====
+ dojo.touch = {
+ // summary:
+ // This module provides unified touch event handlers by exporting
+ // press, move, release and cancel which can also run well on desktop.
+ // Based on http://dvcs.w3.org/hg/webevents/raw-file/tip/touchevents.html
+ //
+ // example:
+ // 1. Used with dojo.connect()
+ // | dojo.connect(node, dojo.touch.press, function(e){});
+ // | dojo.connect(node, dojo.touch.move, function(e){});
+ // | dojo.connect(node, dojo.touch.release, function(e){});
+ // | dojo.connect(node, dojo.touch.cancel, function(e){});
+ //
+ // 2. Used with dojo.on
+ // | define(["dojo/on", "dojo/touch"], function(on, touch){
+ // | on(node, touch.press, function(e){});
+ // | on(node, touch.move, function(e){});
+ // | on(node, touch.release, function(e){});
+ // | on(node, touch.cancel, function(e){});
+ //
+ // 3. Used with dojo.touch.* directly
+ // | dojo.touch.press(node, function(e){});
+ // | dojo.touch.move(node, function(e){});
+ // | dojo.touch.release(node, function(e){});
+ // | dojo.touch.cancel(node, function(e){});
+
+ press: function(node, listener){
+ // summary:
+ // Register a listener to 'touchstart'|'mousedown' for the given node
+ // node: Dom
+ // Target node to listen to
+ // listener: Function
+ // Callback function
+ // returns:
+ // A handle which will be used to remove the listener by handle.remove()
+ },
+ move: function(node, listener){
+ // summary:
+ // Register a listener to 'touchmove'|'mousemove' for the given node
+ // node: Dom
+ // Target node to listen to
+ // listener: Function
+ // Callback function
+ // returns:
+ // A handle which will be used to remove the listener by handle.remove()
+ },
+ release: function(node, listener){
+ // summary:
+ // Register a listener to 'touchend'|'mouseup' for the given node
+ // node: Dom
+ // Target node to listen to
+ // listener: Function
+ // Callback function
+ // returns:
+ // A handle which will be used to remove the listener by handle.remove()
+ },
+ cancel: function(node, listener){
+ // summary:
+ // Register a listener to 'touchcancel'|'mouseleave' for the given node
+ // node: Dom
+ // Target node to listen to
+ // listener: Function
+ // Callback function
+ // returns:
+ // A handle which will be used to remove the listener by handle.remove()
+ }
+ };
+=====*/
+
+ function _handle(/*String - press | move | release | cancel*/type){
+ return function(node, listener){//called by on(), see dojo.on
+ return on(node, type, listener);
+ };
+ }
+ var touch = has("touch");
+ //device neutral events - dojo.touch.press|move|release|cancel
+ dojo.touch = {
+ press: _handle(touch ? "touchstart": "mousedown"),
+ move: _handle(touch ? "touchmove": "mousemove"),
+ release: _handle(touch ? "touchend": "mouseup"),
+ cancel: touch ? _handle("touchcancel") : mouse.leave
+ };
+ return dojo.touch;
+});
+},
+'dojox/grid/Selection':function(){
+define("dojox/grid/Selection", [
+ "dojo/_base/declare",
+ "dojo/_base/array",
+ "dojo/_base/lang",
+ "dojo/dom-attr"
+], function(declare, array, lang, domAttr){
+
+return declare("dojox.grid.Selection", null, {
+ // summary:
+ // Manages row selection for grid. Owned by grid and used internally
+ // for selection. Override to implement custom selection.
+
+ constructor: function(inGrid){
+ this.grid = inGrid;
+ this.selected = [];
+
+ this.setMode(inGrid.selectionMode);
+ },
+
+ mode: 'extended',
+
+ selected: null,
+ updating: 0,
+ selectedIndex: -1,
+
+ setMode: function(mode){
+ if(this.selected.length){
+ this.deselectAll();
+ }
+ if(mode != 'extended' && mode != 'multiple' && mode != 'single' && mode != 'none'){
+ this.mode = 'extended';
+ }else{
+ this.mode = mode;
+ }
+ },
+
+ onCanSelect: function(inIndex){
+ return this.grid.onCanSelect(inIndex);
+ },
+
+ onCanDeselect: function(inIndex){
+ return this.grid.onCanDeselect(inIndex);
+ },
+
+ onSelected: function(inIndex){
+ },
+
+ onDeselected: function(inIndex){
+ },
+
+ //onSetSelected: function(inIndex, inSelect) { };
+ onChanging: function(){
+ },
+
+ onChanged: function(){
+ },
+
+ isSelected: function(inIndex){
+ if(this.mode == 'none'){
+ return false;
+ }
+ return this.selected[inIndex];
+ },
+
+ getFirstSelected: function(){
+ if(!this.selected.length||this.mode == 'none'){ return -1; }
+ for(var i=0, l=this.selected.length; i<l; i++){
+ if(this.selected[i]){
+ return i;
+ }
+ }
+ return -1;
+ },
+
+ getNextSelected: function(inPrev){
+ if(this.mode == 'none'){ return -1; }
+ for(var i=inPrev+1, l=this.selected.length; i<l; i++){
+ if(this.selected[i]){
+ return i;
+ }
+ }
+ return -1;
+ },
+
+ getSelected: function(){
+ var result = [];
+ for(var i=0, l=this.selected.length; i<l; i++){
+ if(this.selected[i]){
+ result.push(i);
+ }
+ }
+ return result;
+ },
+
+ getSelectedCount: function(){
+ var c = 0;
+ for(var i=0; i<this.selected.length; i++){
+ if(this.selected[i]){
+ c++;
+ }
+ }
+ return c;
+ },
+
+ _beginUpdate: function(){
+ if(this.updating === 0){
+ this.onChanging();
+ }
+ this.updating++;
+ },
+
+ _endUpdate: function(){
+ this.updating--;
+ if(this.updating === 0){
+ this.onChanged();
+ }
+ },
+
+ select: function(inIndex){
+ if(this.mode == 'none'){ return; }
+ if(this.mode != 'multiple'){
+ this.deselectAll(inIndex);
+ this.addToSelection(inIndex);
+ }else{
+ this.toggleSelect(inIndex);
+ }
+ },
+
+ addToSelection: function(inIndex){
+ if(this.mode == 'none'){ return; }
+ if(lang.isArray(inIndex)){
+ array.forEach(inIndex, this.addToSelection, this);
+ return;
+ }
+ inIndex = Number(inIndex);
+ if(this.selected[inIndex]){
+ this.selectedIndex = inIndex;
+ }else{
+ if(this.onCanSelect(inIndex) !== false){
+ this.selectedIndex = inIndex;
+ var rowNode = this.grid.getRowNode(inIndex);
+ if(rowNode){
+ domAttr.set(rowNode, "aria-selected", "true");
+ }
+ this._beginUpdate();
+ this.selected[inIndex] = true;
+ //this.grid.onSelected(inIndex);
+ this.onSelected(inIndex);
+ //this.onSetSelected(inIndex, true);
+ this._endUpdate();
+ }
+ }
+ },
+
+ deselect: function(inIndex){
+ if(this.mode == 'none'){ return; }
+ if(lang.isArray(inIndex)){
+ array.forEach(inIndex, this.deselect, this);
+ return;
+ }
+ inIndex = Number(inIndex);
+ if(this.selectedIndex == inIndex){
+ this.selectedIndex = -1;
+ }
+ if(this.selected[inIndex]){
+ if(this.onCanDeselect(inIndex) === false){
+ return;
+ }
+ var rowNode = this.grid.getRowNode(inIndex);
+ if(rowNode){
+ domAttr.set(rowNode, "aria-selected", "false");
+ }
+ this._beginUpdate();
+ delete this.selected[inIndex];
+ //this.grid.onDeselected(inIndex);
+ this.onDeselected(inIndex);
+ //this.onSetSelected(inIndex, false);
+ this._endUpdate();
+ }
+ },
+
+ setSelected: function(inIndex, inSelect){
+ this[(inSelect ? 'addToSelection' : 'deselect')](inIndex);
+ },
+
+ toggleSelect: function(inIndex){
+ if(lang.isArray(inIndex)){
+ array.forEach(inIndex, this.toggleSelect, this);
+ return;
+ }
+ this.setSelected(inIndex, !this.selected[inIndex]);
+ },
+
+ _range: function(inFrom, inTo, func){
+ var s = (inFrom >= 0 ? inFrom : inTo), e = inTo;
+ if(s > e){
+ e = s;
+ s = inTo;
+ }
+ for(var i=s; i<=e; i++){
+ func(i);
+ }
+ },
+
+ selectRange: function(inFrom, inTo){
+ this._range(inFrom, inTo, lang.hitch(this, "addToSelection"));
+ },
+
+ deselectRange: function(inFrom, inTo){
+ this._range(inFrom, inTo, lang.hitch(this, "deselect"));
+ },
+
+ insert: function(inIndex){
+ this.selected.splice(inIndex, 0, false);
+ if(this.selectedIndex >= inIndex){
+ this.selectedIndex++;
+ }
+ },
+
+ remove: function(inIndex){
+ this.selected.splice(inIndex, 1);
+ if(this.selectedIndex >= inIndex){
+ this.selectedIndex--;
+ }
+ },
+
+ deselectAll: function(inExcept){
+ for(var i in this.selected){
+ if((i!=inExcept)&&(this.selected[i]===true)){
+ this.deselect(i);
+ }
+ }
+ },
+
+ clickSelect: function(inIndex, inCtrlKey, inShiftKey){
+ if(this.mode == 'none'){ return; }
+ this._beginUpdate();
+ if(this.mode != 'extended'){
+ this.select(inIndex);
+ }else{
+ var lastSelected = this.selectedIndex;
+ if(!inCtrlKey){
+ this.deselectAll(inIndex);
+ }
+ if(inShiftKey){
+ this.selectRange(lastSelected, inIndex);
+ }else if(inCtrlKey){
+ this.toggleSelect(inIndex);
+ }else{
+ this.addToSelection(inIndex);
+ }
+ }
+ this._endUpdate();
+ },
+
+ clickSelectEvent: function(e){
+ this.clickSelect(e.rowIndex, dojo.isCopyKey(e), e.shiftKey);
+ },
+
+ clear: function(){
+ this._beginUpdate();
+ this.deselectAll();
+ this._endUpdate();
+ }
+});
+});
+},
+'dijit/_CssStateMixin':function(){
+define("dijit/_CssStateMixin", [
+ "dojo/touch",
+ "dojo/_base/array", // array.forEach array.map
+ "dojo/_base/declare", // declare
+ "dojo/dom-class", // domClass.toggle
+ "dojo/_base/lang", // lang.hitch
+ "dojo/_base/window" // win.body
+], function(touch, array, declare, domClass, lang, win){
+
+// module:
+// dijit/_CssStateMixin
+// summary:
+// Mixin for widgets to set CSS classes on the widget DOM nodes depending on hover/mouse press/focus
+// state changes, and also higher-level state changes such becoming disabled or selected.
+
+return declare("dijit._CssStateMixin", [], {
+ // summary:
+ // Mixin for widgets to set CSS classes on the widget DOM nodes depending on hover/mouse press/focus
+ // state changes, and also higher-level state changes such becoming disabled or selected.
+ //
+ // description:
+ // By mixing this class into your widget, and setting the this.baseClass attribute, it will automatically
+ // maintain CSS classes on the widget root node (this.domNode) depending on hover,
+ // active, focus, etc. state. Ex: with a baseClass of dijitButton, it will apply the classes
+ // dijitButtonHovered and dijitButtonActive, as the user moves the mouse over the widget and clicks it.
+ //
+ // It also sets CSS like dijitButtonDisabled based on widget semantic state.
+ //
+ // By setting the cssStateNodes attribute, a widget can also track events on subnodes (like buttons
+ // within the widget).
+
+ // cssStateNodes: [protected] Object
+ // List of sub-nodes within the widget that need CSS classes applied on mouse hover/press and focus
+ //.
+ // Each entry in the hash is a an attachpoint names (like "upArrowButton") mapped to a CSS class names
+ // (like "dijitUpArrowButton"). Example:
+ // | {
+ // | "upArrowButton": "dijitUpArrowButton",
+ // | "downArrowButton": "dijitDownArrowButton"
+ // | }
+ // The above will set the CSS class dijitUpArrowButton to the this.upArrowButton DOMNode when it
+ // is hovered, etc.
+ cssStateNodes: {},
+
+ // hovering: [readonly] Boolean
+ // True if cursor is over this widget
+ hovering: false,
+
+ // active: [readonly] Boolean
+ // True if mouse was pressed while over this widget, and hasn't been released yet
+ active: false,
+
+ _applyAttributes: function(){
+ // This code would typically be in postCreate(), but putting in _applyAttributes() for
+ // performance: so the class changes happen before DOM is inserted into the document.
+ // Change back to postCreate() in 2.0. See #11635.
+
+ this.inherited(arguments);
+
+ // Automatically monitor mouse events (essentially :hover and :active) on this.domNode
+ array.forEach(["onmouseenter", "onmouseleave", touch.press], function(e){
+ this.connect(this.domNode, e, "_cssMouseEvent");
+ }, this);
+
+ // Monitoring changes to disabled, readonly, etc. state, and update CSS class of root node
+ array.forEach(["disabled", "readOnly", "checked", "selected", "focused", "state", "hovering", "active"], function(attr){
+ this.watch(attr, lang.hitch(this, "_setStateClass"));
+ }, this);
+
+ // Events on sub nodes within the widget
+ for(var ap in this.cssStateNodes){
+ this._trackMouseState(this[ap], this.cssStateNodes[ap]);
+ }
+ // Set state initially; there's probably no hover/active/focus state but widget might be
+ // disabled/readonly/checked/selected so we want to set CSS classes for those conditions.
+ this._setStateClass();
+ },
+
+ _cssMouseEvent: function(/*Event*/ event){
+ // summary:
+ // Sets hovering and active properties depending on mouse state,
+ // which triggers _setStateClass() to set appropriate CSS classes for this.domNode.
+
+ if(!this.disabled){
+ switch(event.type){
+ case "mouseenter":
+ case "mouseover": // generated on non-IE browsers even though we connected to mouseenter
+ this._set("hovering", true);
+ this._set("active", this._mouseDown);
+ break;
+
+ case "mouseleave":
+ case "mouseout": // generated on non-IE browsers even though we connected to mouseleave
+ this._set("hovering", false);
+ this._set("active", false);
+ break;
+
+ case "mousedown":
+ case "touchpress":
+ this._set("active", true);
+ this._mouseDown = true;
+ // Set a global event to handle mouseup, so it fires properly
+ // even if the cursor leaves this.domNode before the mouse up event.
+ // Alternately could set active=false on mouseout.
+ var mouseUpConnector = this.connect(win.body(), touch.release, function(){
+ this._mouseDown = false;
+ this._set("active", false);
+ this.disconnect(mouseUpConnector);
+ });
+ break;
+ }
+ }
+ },
+
+ _setStateClass: function(){
+ // summary:
+ // Update the visual state of the widget by setting the css classes on this.domNode
+ // (or this.stateNode if defined) by combining this.baseClass with
+ // various suffixes that represent the current widget state(s).
+ //
+ // description:
+ // In the case where a widget has multiple
+ // states, it sets the class based on all possible
+ // combinations. For example, an invalid form widget that is being hovered
+ // will be "dijitInput dijitInputInvalid dijitInputHover dijitInputInvalidHover".
+ //
+ // The widget may have one or more of the following states, determined
+ // by this.state, this.checked, this.valid, and this.selected:
+ // - Error - ValidationTextBox sets this.state to "Error" if the current input value is invalid
+ // - Incomplete - ValidationTextBox sets this.state to "Incomplete" if the current input value is not finished yet
+ // - Checked - ex: a checkmark or a ToggleButton in a checked state, will have this.checked==true
+ // - Selected - ex: currently selected tab will have this.selected==true
+ //
+ // In addition, it may have one or more of the following states,
+ // based on this.disabled and flags set in _onMouse (this.active, this.hovering) and from focus manager (this.focused):
+ // - Disabled - if the widget is disabled
+ // - Active - if the mouse (or space/enter key?) is being pressed down
+ // - Focused - if the widget has focus
+ // - Hover - if the mouse is over the widget
+
+ // Compute new set of classes
+ var newStateClasses = this.baseClass.split(" ");
+
+ function multiply(modifier){
+ newStateClasses = newStateClasses.concat(array.map(newStateClasses, function(c){ return c+modifier; }), "dijit"+modifier);
+ }
+
+ if(!this.isLeftToRight()){
+ // For RTL mode we need to set an addition class like dijitTextBoxRtl.
+ multiply("Rtl");
+ }
+
+ var checkedState = this.checked == "mixed" ? "Mixed" : (this.checked ? "Checked" : "");
+ if(this.checked){
+ multiply(checkedState);
+ }
+ if(this.state){
+ multiply(this.state);
+ }
+ if(this.selected){
+ multiply("Selected");
+ }
+
+ if(this.disabled){
+ multiply("Disabled");
+ }else if(this.readOnly){
+ multiply("ReadOnly");
+ }else{
+ if(this.active){
+ multiply("Active");
+ }else if(this.hovering){
+ multiply("Hover");
+ }
+ }
+
+ if(this.focused){
+ multiply("Focused");
+ }
+
+ // Remove old state classes and add new ones.
+ // For performance concerns we only write into domNode.className once.
+ var tn = this.stateNode || this.domNode,
+ classHash = {}; // set of all classes (state and otherwise) for node
+
+ array.forEach(tn.className.split(" "), function(c){ classHash[c] = true; });
+
+ if("_stateClasses" in this){
+ array.forEach(this._stateClasses, function(c){ delete classHash[c]; });
+ }
+
+ array.forEach(newStateClasses, function(c){ classHash[c] = true; });
+
+ var newClasses = [];
+ for(var c in classHash){
+ newClasses.push(c);
+ }
+ tn.className = newClasses.join(" ");
+
+ this._stateClasses = newStateClasses;
+ },
+
+ _trackMouseState: function(/*DomNode*/ node, /*String*/ clazz){
+ // summary:
+ // Track mouse/focus events on specified node and set CSS class on that node to indicate
+ // current state. Usually not called directly, but via cssStateNodes attribute.
+ // description:
+ // Given class=foo, will set the following CSS class on the node
+ // - fooActive: if the user is currently pressing down the mouse button while over the node
+ // - fooHover: if the user is hovering the mouse over the node, but not pressing down a button
+ // - fooFocus: if the node is focused
+ //
+ // Note that it won't set any classes if the widget is disabled.
+ // node: DomNode
+ // Should be a sub-node of the widget, not the top node (this.domNode), since the top node
+ // is handled specially and automatically just by mixing in this class.
+ // clazz: String
+ // CSS class name (ex: dijitSliderUpArrow).
+
+ // Current state of node (initially false)
+ // NB: setting specifically to false because domClass.toggle() needs true boolean as third arg
+ var hovering=false, active=false, focused=false;
+
+ var self = this,
+ cn = lang.hitch(this, "connect", node);
+
+ function setClass(){
+ var disabled = ("disabled" in self && self.disabled) || ("readonly" in self && self.readonly);
+ domClass.toggle(node, clazz+"Hover", hovering && !active && !disabled);
+ domClass.toggle(node, clazz+"Active", active && !disabled);
+ domClass.toggle(node, clazz+"Focused", focused && !disabled);
+ }
+
+ // Mouse
+ cn("onmouseenter", function(){
+ hovering = true;
+ setClass();
+ });
+ cn("onmouseleave", function(){
+ hovering = false;
+ active = false;
+ setClass();
+ });
+ cn(touch.press, function(){
+ active = true;
+ setClass();
+ });
+ cn(touch.release, function(){
+ active = false;
+ setClass();
+ });
+
+ // Focus
+ cn("onfocus", function(){
+ focused = true;
+ setClass();
+ });
+ cn("onblur", function(){
+ focused = false;
+ setClass();
+ });
+
+ // Just in case widget is enabled/disabled while it has focus/hover/active state.
+ // Maybe this is overkill.
+ this.watch("disabled", setClass);
+ this.watch("readOnly", setClass);
+ }
+});
+});
+
+},
+'url:dojox/grid/resources/_Grid.html':"<div hidefocus=\"hidefocus\" role=\"grid\" dojoAttachEvent=\"onmouseout:_mouseOut\">\n\t<div class=\"dojoxGridMasterHeader\" dojoAttachPoint=\"viewsHeaderNode\" role=\"presentation\"></div>\n\t<div class=\"dojoxGridMasterView\" dojoAttachPoint=\"viewsNode\" role=\"presentation\"></div>\n\t<div class=\"dojoxGridMasterMessages\" style=\"display: none;\" dojoAttachPoint=\"messagesNode\"></div>\n\t<span dojoAttachPoint=\"lastFocusNode\" tabindex=\"0\"></span>\n</div>\n",
+'dojox/grid/_RowManager':function(){
+define("dojox/grid/_RowManager", [
+ "dojo/_base/declare",
+ "dojo/_base/lang",
+ "dojo/dom-class"
+], function(declare, lang, domClass){
+
+ var setStyleText = function(inNode, inStyleText){
+ if(inNode.style.cssText == undefined){
+ inNode.setAttribute("style", inStyleText);
+ }else{
+ inNode.style.cssText = inStyleText;
+ }
+ };
+
+ return declare("dojox.grid._RowManager", null, {
+ // Stores information about grid rows. Owned by grid and used internally.
+ constructor: function(inGrid){
+ this.grid = inGrid;
+ },
+ linesToEms: 2,
+ overRow: -2,
+ // styles
+ prepareStylingRow: function(inRowIndex, inRowNode){
+ return {
+ index: inRowIndex,
+ node: inRowNode,
+ odd: Boolean(inRowIndex&1),
+ selected: !!this.grid.selection.isSelected(inRowIndex),
+ over: this.isOver(inRowIndex),
+ customStyles: "",
+ customClasses: "dojoxGridRow"
+ };
+ },
+ styleRowNode: function(inRowIndex, inRowNode){
+ var row = this.prepareStylingRow(inRowIndex, inRowNode);
+ this.grid.onStyleRow(row);
+ this.applyStyles(row);
+ },
+ applyStyles: function(inRow){
+ var i = inRow;
+
+ i.node.className = i.customClasses;
+ var h = i.node.style.height;
+ setStyleText(i.node, i.customStyles + ';' + (i.node._style||''));
+ i.node.style.height = h;
+ },
+ updateStyles: function(inRowIndex){
+ this.grid.updateRowStyles(inRowIndex);
+ },
+ // states and events
+ setOverRow: function(inRowIndex){
+ var last = this.overRow;
+ this.overRow = inRowIndex;
+ if((last!=this.overRow)&&(lang.isString(last) || last >= 0)){
+ this.updateStyles(last);
+ }
+ this.updateStyles(this.overRow);
+ },
+ isOver: function(inRowIndex){
+ return (this.overRow == inRowIndex && !domClass.contains(this.grid.domNode, "dojoxGridColumnResizing"));
+ }
+ });
+});
+},
+'dojo/_base/url':function(){
+define(["./kernel"], function(dojo) {
+ // module:
+ // dojo/url
+ // summary:
+ // This module contains dojo._Url
+
+ var
+ ore = new RegExp("^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?$"),
+ ire = new RegExp("^((([^\\[:]+):)?([^@]+)@)?(\\[([^\\]]+)\\]|([^\\[:]*))(:([0-9]+))?$"),
+ _Url = function(){
+ var n = null,
+ _a = arguments,
+ uri = [_a[0]];
+ // resolve uri components relative to each other
+ for(var i = 1; i<_a.length; i++){
+ if(!_a[i]){ continue; }
+
+ // Safari doesn't support this.constructor so we have to be explicit
+ // FIXME: Tracked (and fixed) in Webkit bug 3537.
+ // http://bugs.webkit.org/show_bug.cgi?id=3537
+ var relobj = new _Url(_a[i]+""),
+ uriobj = new _Url(uri[0]+"");
+
+ if(
+ relobj.path == "" &&
+ !relobj.scheme &&
+ !relobj.authority &&
+ !relobj.query
+ ){
+ if(relobj.fragment != n){
+ uriobj.fragment = relobj.fragment;
+ }
+ relobj = uriobj;
+ }else if(!relobj.scheme){
+ relobj.scheme = uriobj.scheme;
+
+ if(!relobj.authority){
+ relobj.authority = uriobj.authority;
+
+ if(relobj.path.charAt(0) != "/"){
+ var path = uriobj.path.substring(0,
+ uriobj.path.lastIndexOf("/") + 1) + relobj.path;
+
+ var segs = path.split("/");
+ for(var j = 0; j < segs.length; j++){
+ if(segs[j] == "."){
+ // flatten "./" references
+ if(j == segs.length - 1){
+ segs[j] = "";
+ }else{
+ segs.splice(j, 1);
+ j--;
+ }
+ }else if(j > 0 && !(j == 1 && segs[0] == "") &&
+ segs[j] == ".." && segs[j-1] != ".."){
+ // flatten "../" references
+ if(j == (segs.length - 1)){
+ segs.splice(j, 1);
+ segs[j - 1] = "";
+ }else{
+ segs.splice(j - 1, 2);
+ j -= 2;
+ }
+ }
+ }
+ relobj.path = segs.join("/");
+ }
+ }
+ }
+
+ uri = [];
+ if(relobj.scheme){
+ uri.push(relobj.scheme, ":");
+ }
+ if(relobj.authority){
+ uri.push("//", relobj.authority);
+ }
+ uri.push(relobj.path);
+ if(relobj.query){
+ uri.push("?", relobj.query);
+ }
+ if(relobj.fragment){
+ uri.push("#", relobj.fragment);
+ }
+ }
+
+ this.uri = uri.join("");
+
+ // break the uri into its main components
+ var r = this.uri.match(ore);
+
+ this.scheme = r[2] || (r[1] ? "" : n);
+ this.authority = r[4] || (r[3] ? "" : n);
+ this.path = r[5]; // can never be undefined
+ this.query = r[7] || (r[6] ? "" : n);
+ this.fragment = r[9] || (r[8] ? "" : n);
+
+ if(this.authority != n){
+ // server based naming authority
+ r = this.authority.match(ire);
+
+ this.user = r[3] || n;
+ this.password = r[4] || n;
+ this.host = r[6] || r[7]; // ipv6 || ipv4
+ this.port = r[9] || n;
+ }
+ };
+ _Url.prototype.toString = function(){ return this.uri; };
+
+ return dojo._Url = _Url;
+});
+
+},
+'dojo/string':function(){
+define(["./_base/kernel", "./_base/lang"], function(dojo, lang) {
+ // module:
+ // dojo/string
+ // summary:
+ // TODOC
+
+lang.getObject("string", true, dojo);
+
+/*=====
+dojo.string = {
+ // summary: String utilities for Dojo
+};
+=====*/
+
+dojo.string.rep = function(/*String*/str, /*Integer*/num){
+ // summary:
+ // Efficiently replicate a string `n` times.
+ // str:
+ // the string to replicate
+ // num:
+ // number of times to replicate the string
+
+ if(num <= 0 || !str){ return ""; }
+
+ var buf = [];
+ for(;;){
+ if(num & 1){
+ buf.push(str);
+ }
+ if(!(num >>= 1)){ break; }
+ str += str;
+ }
+ return buf.join(""); // String
+};
+
+dojo.string.pad = function(/*String*/text, /*Integer*/size, /*String?*/ch, /*Boolean?*/end){
+ // summary:
+ // Pad a string to guarantee that it is at least `size` length by
+ // filling with the character `ch` at either the start or end of the
+ // string. Pads at the start, by default.
+ // text:
+ // the string to pad
+ // size:
+ // length to provide padding
+ // ch:
+ // character to pad, defaults to '0'
+ // end:
+ // adds padding at the end if true, otherwise pads at start
+ // example:
+ // | // Fill the string to length 10 with "+" characters on the right. Yields "Dojo++++++".
+ // | dojo.string.pad("Dojo", 10, "+", true);
+
+ if(!ch){
+ ch = '0';
+ }
+ var out = String(text),
+ pad = dojo.string.rep(ch, Math.ceil((size - out.length) / ch.length));
+ return end ? out + pad : pad + out; // String
+};
+
+dojo.string.substitute = function( /*String*/ template,
+ /*Object|Array*/map,
+ /*Function?*/ transform,
+ /*Object?*/ thisObject){
+ // summary:
+ // Performs parameterized substitutions on a string. Throws an
+ // exception if any parameter is unmatched.
+ // template:
+ // a string with expressions in the form `${key}` to be replaced or
+ // `${key:format}` which specifies a format function. keys are case-sensitive.
+ // map:
+ // hash to search for substitutions
+ // transform:
+ // a function to process all parameters before substitution takes
+ // place, e.g. mylib.encodeXML
+ // thisObject:
+ // where to look for optional format function; default to the global
+ // namespace
+ // example:
+ // Substitutes two expressions in a string from an Array or Object
+ // | // returns "File 'foo.html' is not found in directory '/temp'."
+ // | // by providing substitution data in an Array
+ // | dojo.string.substitute(
+ // | "File '${0}' is not found in directory '${1}'.",
+ // | ["foo.html","/temp"]
+ // | );
+ // |
+ // | // also returns "File 'foo.html' is not found in directory '/temp'."
+ // | // but provides substitution data in an Object structure. Dotted
+ // | // notation may be used to traverse the structure.
+ // | dojo.string.substitute(
+ // | "File '${name}' is not found in directory '${info.dir}'.",
+ // | { name: "foo.html", info: { dir: "/temp" } }
+ // | );
+ // example:
+ // Use a transform function to modify the values:
+ // | // returns "file 'foo.html' is not found in directory '/temp'."
+ // | dojo.string.substitute(
+ // | "${0} is not found in ${1}.",
+ // | ["foo.html","/temp"],
+ // | function(str){
+ // | // try to figure out the type
+ // | var prefix = (str.charAt(0) == "/") ? "directory": "file";
+ // | return prefix + " '" + str + "'";
+ // | }
+ // | );
+ // example:
+ // Use a formatter
+ // | // returns "thinger -- howdy"
+ // | dojo.string.substitute(
+ // | "${0:postfix}", ["thinger"], null, {
+ // | postfix: function(value, key){
+ // | return value + " -- howdy";
+ // | }
+ // | }
+ // | );
+
+ thisObject = thisObject || dojo.global;
+ transform = transform ?
+ lang.hitch(thisObject, transform) : function(v){ return v; };
+
+ return template.replace(/\$\{([^\s\:\}]+)(?:\:([^\s\:\}]+))?\}/g,
+ function(match, key, format){
+ var value = lang.getObject(key, false, map);
+ if(format){
+ value = lang.getObject(format, false, thisObject).call(thisObject, value, key);
+ }
+ return transform(value, key).toString();
+ }); // String
+};
+
+/*=====
+dojo.string.trim = function(str){
+ // summary:
+ // Trims whitespace from both sides of the string
+ // str: String
+ // String to be trimmed
+ // returns: String
+ // Returns the trimmed string
+ // description:
+ // This version of trim() was taken from [Steven Levithan's blog](http://blog.stevenlevithan.com/archives/faster-trim-javascript).
+ // The short yet performant version of this function is dojo.trim(),
+ // which is part of Dojo base. Uses String.prototype.trim instead, if available.
+ return ""; // String
+}
+=====*/
+
+dojo.string.trim = String.prototype.trim ?
+ lang.trim : // aliasing to the native function
+ function(str){
+ str = str.replace(/^\s+/, '');
+ for(var i = str.length - 1; i >= 0; i--){
+ if(/\S/.test(str.charAt(i))){
+ str = str.substring(0, i + 1);
+ break;
+ }
+ }
+ return str;
+ };
+
+return dojo.string;
+});
+
+},
+'dojo/dnd/Avatar':function(){
+define(["../main", "./common"], function(dojo) {
+ // module:
+ // dojo/dnd/Avatar
+ // summary:
+ // TODOC
+
+
+dojo.declare("dojo.dnd.Avatar", null, {
+ // summary:
+ // Object that represents transferred DnD items visually
+ // manager: Object
+ // a DnD manager object
+
+ constructor: function(manager){
+ this.manager = manager;
+ this.construct();
+ },
+
+ // methods
+ construct: function(){
+ // summary:
+ // constructor function;
+ // it is separate so it can be (dynamically) overwritten in case of need
+ this.isA11y = dojo.hasClass(dojo.body(),"dijit_a11y");
+ var a = dojo.create("table", {
+ "class": "dojoDndAvatar",
+ style: {
+ position: "absolute",
+ zIndex: "1999",
+ margin: "0px"
+ }
+ }),
+ source = this.manager.source, node,
+ b = dojo.create("tbody", null, a),
+ tr = dojo.create("tr", null, b),
+ td = dojo.create("td", null, tr),
+ icon = this.isA11y ? dojo.create("span", {
+ id : "a11yIcon",
+ innerHTML : this.manager.copy ? '+' : "<"
+ }, td) : null,
+ span = dojo.create("span", {
+ innerHTML: source.generateText ? this._generateText() : ""
+ }, td),
+ k = Math.min(5, this.manager.nodes.length), i = 0;
+ // we have to set the opacity on IE only after the node is live
+ dojo.attr(tr, {
+ "class": "dojoDndAvatarHeader",
+ style: {opacity: 0.9}
+ });
+ for(; i < k; ++i){
+ if(source.creator){
+ // create an avatar representation of the node
+ node = source._normalizedCreator(source.getItem(this.manager.nodes[i].id).data, "avatar").node;
+ }else{
+ // or just clone the node and hope it works
+ node = this.manager.nodes[i].cloneNode(true);
+ if(node.tagName.toLowerCase() == "tr"){
+ // insert extra table nodes
+ var table = dojo.create("table"),
+ tbody = dojo.create("tbody", null, table);
+ tbody.appendChild(node);
+ node = table;
+ }
+ }
+ node.id = "";
+ tr = dojo.create("tr", null, b);
+ td = dojo.create("td", null, tr);
+ td.appendChild(node);
+ dojo.attr(tr, {
+ "class": "dojoDndAvatarItem",
+ style: {opacity: (9 - i) / 10}
+ });
+ }
+ this.node = a;
+ },
+ destroy: function(){
+ // summary:
+ // destructor for the avatar; called to remove all references so it can be garbage-collected
+ dojo.destroy(this.node);
+ this.node = false;
+ },
+ update: function(){
+ // summary:
+ // updates the avatar to reflect the current DnD state
+ dojo[(this.manager.canDropFlag ? "add" : "remove") + "Class"](this.node, "dojoDndAvatarCanDrop");
+ if (this.isA11y){
+ var icon = dojo.byId("a11yIcon");
+ var text = '+'; // assume canDrop && copy
+ if (this.manager.canDropFlag && !this.manager.copy) {
+ text = '< '; // canDrop && move
+ }else if (!this.manager.canDropFlag && !this.manager.copy) {
+ text = "o"; //!canDrop && move
+ }else if(!this.manager.canDropFlag){
+ text = 'x'; // !canDrop && copy
+ }
+ icon.innerHTML=text;
+ }
+ // replace text
+ dojo.query(("tr.dojoDndAvatarHeader td span" +(this.isA11y ? " span" : "")), this.node).forEach(
+ function(node){
+ node.innerHTML = this._generateText();
+ }, this);
+ },
+ _generateText: function(){
+ // summary: generates a proper text to reflect copying or moving of items
+ return this.manager.nodes.length.toString();
+ }
+});
+
+return dojo.dnd.Avatar;
+});
+
+},
+'dojox/grid/_Scroller':function(){
+define("dojox/grid/_Scroller", [
+ "dijit/registry",
+ "dojo/_base/declare",
+ "dojo/_base/lang",
+ "./util",
+ "dojo/_base/html"
+], function(dijitRegistry, declare, lang, util, html){
+
+ var indexInParent = function(inNode){
+ var i=0, n, p=inNode.parentNode;
+ while((n = p.childNodes[i++])){
+ if(n == inNode){
+ return i - 1;
+ }
+ }
+ return -1;
+ };
+
+ var cleanNode = function(inNode){
+ if(!inNode){
+ return;
+ }
+ dojo.forEach(dijitRegistry.toArray(), function(w){
+ if(w.domNode && html.isDescendant(w.domNode, inNode, true)){
+ w.destroy();
+ }
+ });
+ };
+
+ var getTagName = function(inNodeOrId){
+ var node = html.byId(inNodeOrId);
+ return (node && node.tagName ? node.tagName.toLowerCase() : '');
+ };
+
+ var nodeKids = function(inNode, inTag){
+ var result = [];
+ var i=0, n;
+ while((n = inNode.childNodes[i])){
+ i++;
+ if(getTagName(n) == inTag){
+ result.push(n);
+ }
+ }
+ return result;
+ };
+
+ var divkids = function(inNode){
+ return nodeKids(inNode, 'div');
+ };
+
+ return declare("dojox.grid._Scroller", null, {
+ constructor: function(inContentNodes){
+ this.setContentNodes(inContentNodes);
+ this.pageHeights = [];
+ this.pageNodes = [];
+ this.stack = [];
+ },
+ // specified
+ rowCount: 0, // total number of rows to manage
+ defaultRowHeight: 32, // default height of a row
+ keepRows: 100, // maximum number of rows that should exist at one time
+ contentNode: null, // node to contain pages
+ scrollboxNode: null, // node that controls scrolling
+ // calculated
+ defaultPageHeight: 0, // default height of a page
+ keepPages: 10, // maximum number of pages that should exists at one time
+ pageCount: 0,
+ windowHeight: 0,
+ firstVisibleRow: 0,
+ lastVisibleRow: 0,
+ averageRowHeight: 0, // the average height of a row
+ // private
+ page: 0,
+ pageTop: 0,
+ // init
+ init: function(inRowCount, inKeepRows, inRowsPerPage){
+ switch(arguments.length){
+ case 3: this.rowsPerPage = inRowsPerPage;
+ case 2: this.keepRows = inKeepRows;
+ case 1: this.rowCount = inRowCount;
+ default: break;
+ }
+ this.defaultPageHeight = this.defaultRowHeight * this.rowsPerPage;
+ this.pageCount = this._getPageCount(this.rowCount, this.rowsPerPage);
+ this.setKeepInfo(this.keepRows);
+ this.invalidate();
+ if(this.scrollboxNode){
+ this.scrollboxNode.scrollTop = 0;
+ this.scroll(0);
+ this.scrollboxNode.onscroll = lang.hitch(this, 'onscroll');
+ }
+ },
+ _getPageCount: function(rowCount, rowsPerPage){
+ return rowCount ? (Math.ceil(rowCount / rowsPerPage) || 1) : 0;
+ },
+ destroy: function(){
+ this.invalidateNodes();
+ delete this.contentNodes;
+ delete this.contentNode;
+ delete this.scrollboxNode;
+ },
+ setKeepInfo: function(inKeepRows){
+ this.keepRows = inKeepRows;
+ this.keepPages = !this.keepRows ? this.keepPages : Math.max(Math.ceil(this.keepRows / this.rowsPerPage), 2);
+ },
+ // nodes
+ setContentNodes: function(inNodes){
+ this.contentNodes = inNodes;
+ this.colCount = (this.contentNodes ? this.contentNodes.length : 0);
+ this.pageNodes = [];
+ for(var i=0; i<this.colCount; i++){
+ this.pageNodes[i] = [];
+ }
+ },
+ getDefaultNodes: function(){
+ return this.pageNodes[0] || [];
+ },
+ // updating
+ invalidate: function(){
+ this._invalidating = true;
+ this.invalidateNodes();
+ this.pageHeights = [];
+ this.height = (this.pageCount ? (this.pageCount - 1)* this.defaultPageHeight + this.calcLastPageHeight() : 0);
+ this.resize();
+ this._invalidating = false;
+ },
+ updateRowCount: function(inRowCount){
+ this.invalidateNodes();
+ this.rowCount = inRowCount;
+ // update page count, adjust document height
+ var oldPageCount = this.pageCount;
+ if(oldPageCount === 0){
+ //We want to have at least 1px in height to keep scroller. Otherwise with an
+ //empty grid you can't scroll to see the header.
+ this.height = 1;
+ }
+ this.pageCount = this._getPageCount(this.rowCount, this.rowsPerPage);
+ if(this.pageCount < oldPageCount){
+ for(var i=oldPageCount-1; i>=this.pageCount; i--){
+ this.height -= this.getPageHeight(i);
+ delete this.pageHeights[i];
+ }
+ }else if(this.pageCount > oldPageCount){
+ this.height += this.defaultPageHeight * (this.pageCount - oldPageCount - 1) + this.calcLastPageHeight();
+ }
+ this.resize();
+ },
+ // implementation for page manager
+ pageExists: function(inPageIndex){
+ return Boolean(this.getDefaultPageNode(inPageIndex));
+ },
+ measurePage: function(inPageIndex){
+ if(this.grid.rowHeight){
+ var height = this.grid.rowHeight + 1;
+ return ((inPageIndex + 1) * this.rowsPerPage > this.rowCount ?
+ this.rowCount - inPageIndex * this.rowsPerPage :
+ this.rowsPerPage) * height;
+
+ }
+ var n = this.getDefaultPageNode(inPageIndex);
+ return (n && n.innerHTML) ? n.offsetHeight : undefined;
+ },
+ positionPage: function(inPageIndex, inPos){
+ for(var i=0; i<this.colCount; i++){
+ this.pageNodes[i][inPageIndex].style.top = inPos + 'px';
+ }
+ },
+ repositionPages: function(inPageIndex){
+ var nodes = this.getDefaultNodes();
+ var last = 0;
+
+ for(var i=0; i<this.stack.length; i++){
+ last = Math.max(this.stack[i], last);
+ }
+ //
+ var n = nodes[inPageIndex];
+ var y = (n ? this.getPageNodePosition(n) + this.getPageHeight(inPageIndex) : 0);
+ for(var p=inPageIndex+1; p<=last; p++){
+ n = nodes[p];
+ if(n){
+ if(this.getPageNodePosition(n) == y){
+ return;
+ }
+ this.positionPage(p, y);
+ }
+ y += this.getPageHeight(p);
+ }
+ },
+ installPage: function(inPageIndex){
+ for(var i=0; i<this.colCount; i++){
+ this.contentNodes[i].appendChild(this.pageNodes[i][inPageIndex]);
+ }
+ },
+ preparePage: function(inPageIndex, inReuseNode){
+ var p = (inReuseNode ? this.popPage() : null);
+ for(var i=0; i<this.colCount; i++){
+ var nodes = this.pageNodes[i];
+ var new_p = (p === null ? this.createPageNode() : this.invalidatePageNode(p, nodes));
+ new_p.pageIndex = inPageIndex;
+ nodes[inPageIndex] = new_p;
+ }
+ },
+ // rendering implementation
+ renderPage: function(inPageIndex){
+ var nodes = [];
+ var i, j;
+ for(i=0; i<this.colCount; i++){
+ nodes[i] = this.pageNodes[i][inPageIndex];
+ }
+ for(i=0, j=inPageIndex*this.rowsPerPage; (i<this.rowsPerPage)&&(j<this.rowCount); i++, j++){
+ this.renderRow(j, nodes);
+ }
+ },
+ removePage: function(inPageIndex){
+ for(var i=0, j=inPageIndex*this.rowsPerPage; i<this.rowsPerPage; i++, j++){
+ this.removeRow(j);
+ }
+ },
+ destroyPage: function(inPageIndex){
+ for(var i=0; i<this.colCount; i++){
+ var n = this.invalidatePageNode(inPageIndex, this.pageNodes[i]);
+ if(n){
+ html.destroy(n);
+ }
+ }
+ },
+ pacify: function(inShouldPacify){
+ },
+ // pacification
+ pacifying: false,
+ pacifyTicks: 200,
+ setPacifying: function(inPacifying){
+ if(this.pacifying != inPacifying){
+ this.pacifying = inPacifying;
+ this.pacify(this.pacifying);
+ }
+ },
+ startPacify: function(){
+ this.startPacifyTicks = new Date().getTime();
+ },
+ doPacify: function(){
+ var result = (new Date().getTime() - this.startPacifyTicks) > this.pacifyTicks;
+ this.setPacifying(true);
+ this.startPacify();
+ return result;
+ },
+ endPacify: function(){
+ this.setPacifying(false);
+ },
+ // default sizing implementation
+ resize: function(){
+ if(this.scrollboxNode){
+ this.windowHeight = this.scrollboxNode.clientHeight;
+ }
+ for(var i=0; i<this.colCount; i++){
+ //We want to have 1px in height min to keep scroller. Otherwise can't scroll
+ //and see header in empty grid.
+ util.setStyleHeightPx(this.contentNodes[i], Math.max(1,this.height));
+ }
+
+ // Calculate the average row height and update the defaults (row and page).
+ var needPage = (!this._invalidating);
+ if(!needPage){
+ var ah = this.grid.get("autoHeight");
+ if(typeof ah == "number" && ah <= Math.min(this.rowsPerPage, this.rowCount)){
+ needPage = true;
+ }
+ }
+ if(needPage){
+ this.needPage(this.page, this.pageTop);
+ }
+ var rowsOnPage = (this.page < this.pageCount - 1) ? this.rowsPerPage : ((this.rowCount % this.rowsPerPage) || this.rowsPerPage);
+ var pageHeight = this.getPageHeight(this.page);
+ this.averageRowHeight = (pageHeight > 0 && rowsOnPage > 0) ? (pageHeight / rowsOnPage) : 0;
+ },
+ calcLastPageHeight: function(){
+ if(!this.pageCount){
+ return 0;
+ }
+ var lastPage = this.pageCount - 1;
+ var lastPageHeight = ((this.rowCount % this.rowsPerPage)||(this.rowsPerPage)) * this.defaultRowHeight;
+ this.pageHeights[lastPage] = lastPageHeight;
+ return lastPageHeight;
+ },
+ updateContentHeight: function(inDh){
+ this.height += inDh;
+ this.resize();
+ },
+ updatePageHeight: function(inPageIndex, fromBuild, fromAsynRendering){
+ if(this.pageExists(inPageIndex)){
+ var oh = this.getPageHeight(inPageIndex);
+ var h = (this.measurePage(inPageIndex));
+ if(h === undefined){
+ h = oh;
+ }
+ this.pageHeights[inPageIndex] = h;
+ if(oh != h){
+ this.updateContentHeight(h - oh);
+ var ah = this.grid.get("autoHeight");
+ if((typeof ah == "number" && ah > this.rowCount)||(ah === true && !fromBuild)){
+ if(!fromAsynRendering){
+ this.grid.sizeChange();
+ }else{//fix #11101 by using fromAsynRendering to avoid deadlock
+ var ns = this.grid.viewsNode.style;
+ ns.height = parseInt(ns.height) + h - oh + 'px';
+ this.repositionPages(inPageIndex);
+ }
+ }else{
+ this.repositionPages(inPageIndex);
+ }
+ }
+ return h;
+ }
+ return 0;
+ },
+ rowHeightChanged: function(inRowIndex, fromAsynRendering){
+ this.updatePageHeight(Math.floor(inRowIndex / this.rowsPerPage), false, fromAsynRendering);
+ },
+ // scroller core
+ invalidateNodes: function(){
+ while(this.stack.length){
+ this.destroyPage(this.popPage());
+ }
+ },
+ createPageNode: function(){
+ var p = document.createElement('div');
+ html.attr(p,"role","presentation");
+ p.style.position = 'absolute';
+ //p.style.width = '100%';
+ p.style[this.grid.isLeftToRight() ? "left" : "right"] = '0';
+ return p;
+ },
+ getPageHeight: function(inPageIndex){
+ var ph = this.pageHeights[inPageIndex];
+ return (ph !== undefined ? ph : this.defaultPageHeight);
+ },
+ // FIXME: this is not a stack, it's a FIFO list
+ pushPage: function(inPageIndex){
+ return this.stack.push(inPageIndex);
+ },
+ popPage: function(){
+ return this.stack.shift();
+ },
+ findPage: function(inTop){
+ var i = 0, h = 0;
+ for(var ph = 0; i<this.pageCount; i++, h += ph){
+ ph = this.getPageHeight(i);
+ if(h + ph >= inTop){
+ break;
+ }
+ }
+ this.page = i;
+ this.pageTop = h;
+ },
+ buildPage: function(inPageIndex, inReuseNode, inPos){
+ this.preparePage(inPageIndex, inReuseNode);
+ this.positionPage(inPageIndex, inPos);
+ // order of operations is key below
+ this.installPage(inPageIndex);
+ this.renderPage(inPageIndex);
+ // order of operations is key above
+ this.pushPage(inPageIndex);
+ },
+ needPage: function(inPageIndex, inPos){
+ var h = this.getPageHeight(inPageIndex), oh = h;
+ if(!this.pageExists(inPageIndex)){
+ this.buildPage(inPageIndex, (!this.grid._autoHeight/*fix #10543*/ && this.keepPages&&(this.stack.length >= this.keepPages)), inPos);
+ h = this.updatePageHeight(inPageIndex, true);
+ }else{
+ this.positionPage(inPageIndex, inPos);
+ }
+ return h;
+ },
+ onscroll: function(){
+ this.scroll(this.scrollboxNode.scrollTop);
+ },
+ scroll: function(inTop){
+ this.grid.scrollTop = inTop;
+ if(this.colCount){
+ this.startPacify();
+ this.findPage(inTop);
+ var h = this.height;
+ var b = this.getScrollBottom(inTop);
+ for(var p=this.page, y=this.pageTop; (p<this.pageCount)&&((b<0)||(y<b)); p++){
+ y += this.needPage(p, y);
+ }
+ this.firstVisibleRow = this.getFirstVisibleRow(this.page, this.pageTop, inTop);
+ this.lastVisibleRow = this.getLastVisibleRow(p - 1, y, b);
+ // indicates some page size has been updated
+ if(h != this.height){
+ this.repositionPages(p-1);
+ }
+ this.endPacify();
+ }
+ },
+ getScrollBottom: function(inTop){
+ return (this.windowHeight >= 0 ? inTop + this.windowHeight : -1);
+ },
+ // events
+ processNodeEvent: function(e, inNode){
+ var t = e.target;
+ while(t && (t != inNode) && t.parentNode && (t.parentNode.parentNode != inNode)){
+ t = t.parentNode;
+ }
+ if(!t || !t.parentNode || (t.parentNode.parentNode != inNode)){
+ return false;
+ }
+ var page = t.parentNode;
+ e.topRowIndex = page.pageIndex * this.rowsPerPage;
+ e.rowIndex = e.topRowIndex + indexInParent(t);
+ e.rowTarget = t;
+ return true;
+ },
+ processEvent: function(e){
+ return this.processNodeEvent(e, this.contentNode);
+ },
+ // virtual rendering interface
+ renderRow: function(inRowIndex, inPageNode){
+ },
+ removeRow: function(inRowIndex){
+ },
+ // page node operations
+ getDefaultPageNode: function(inPageIndex){
+ return this.getDefaultNodes()[inPageIndex];
+ },
+ positionPageNode: function(inNode, inPos){
+ },
+ getPageNodePosition: function(inNode){
+ return inNode.offsetTop;
+ },
+ invalidatePageNode: function(inPageIndex, inNodes){
+ var p = inNodes[inPageIndex];
+ if(p){
+ delete inNodes[inPageIndex];
+ this.removePage(inPageIndex, p);
+ cleanNode(p);
+ p.innerHTML = '';
+ }
+ return p;
+ },
+ // scroll control
+ getPageRow: function(inPage){
+ return inPage * this.rowsPerPage;
+ },
+ getLastPageRow: function(inPage){
+ return Math.min(this.rowCount, this.getPageRow(inPage + 1)) - 1;
+ },
+ getFirstVisibleRow: function(inPage, inPageTop, inScrollTop){
+ if(!this.pageExists(inPage)){
+ return 0;
+ }
+ var row = this.getPageRow(inPage);
+ var nodes = this.getDefaultNodes();
+ var rows = divkids(nodes[inPage]);
+ for(var i=0,l=rows.length; i<l && inPageTop<inScrollTop; i++, row++){
+ inPageTop += rows[i].offsetHeight;
+ }
+ return (row ? row - 1 : row);
+ },
+ getLastVisibleRow: function(inPage, inBottom, inScrollBottom){
+ if(!this.pageExists(inPage)){
+ return 0;
+ }
+ var nodes = this.getDefaultNodes();
+ var row = this.getLastPageRow(inPage);
+ var rows = divkids(nodes[inPage]);
+ for(var i=rows.length-1; i>=0 && inBottom>inScrollBottom; i--, row--){
+ inBottom -= rows[i].offsetHeight;
+ }
+ return row + 1;
+ },
+ findTopRow: function(inScrollTop){
+ var nodes = this.getDefaultNodes();
+ var rows = divkids(nodes[this.page]);
+ for(var i=0,l=rows.length,t=this.pageTop,h; i<l; i++){
+ h = rows[i].offsetHeight;
+ t += h;
+ if(t >= inScrollTop){
+ this.offset = h - (t - inScrollTop);
+ return i + this.page * this.rowsPerPage;
+ }
+ }
+ return -1;
+ },
+ findScrollTop: function(inRow){
+ var rowPage = Math.floor(inRow / this.rowsPerPage);
+ var t = 0;
+ var i, l;
+ for(i=0; i<rowPage; i++){
+ t += this.getPageHeight(i);
+ }
+ this.pageTop = t;
+ this.page = rowPage;//fix #10543
+ this.needPage(rowPage, this.pageTop);
+
+ var nodes = this.getDefaultNodes();
+ var rows = divkids(nodes[rowPage]);
+ var r = inRow - this.rowsPerPage * rowPage;
+ for(i=0,l=rows.length; i<l && i<r; i++){
+ t += rows[i].offsetHeight;
+ }
+ return t;
+ },
+ dummy: 0
+ });
+});
+
+},
+'dojox/grid/_Events':function(){
+define("dojox/grid/_Events", [
+ "dojo/keys",
+ "dojo/dom-class",
+ "dojo/_base/declare",
+ "dojo/_base/event",
+ "dojo/_base/sniff"
+], function(keys, domClass, declare, event, has){
+
+return declare("dojox.grid._Events", null, {
+ // summary:
+ // _Grid mixin that provides default implementations for grid events.
+ // description:
+ // Default synthetic events dispatched for _Grid. dojo.connect to events to
+ // retain default implementation or override them for custom handling.
+
+ // cellOverClass: String
+ // css class to apply to grid cells over which the cursor is placed.
+ cellOverClass: "dojoxGridCellOver",
+
+ onKeyEvent: function(e){
+ // summary: top level handler for Key Events
+ this.dispatchKeyEvent(e);
+ },
+
+ onContentEvent: function(e){
+ // summary: Top level handler for Content events
+ this.dispatchContentEvent(e);
+ },
+
+ onHeaderEvent: function(e){
+ // summary: Top level handler for header events
+ this.dispatchHeaderEvent(e);
+ },
+
+ onStyleRow: function(inRow){
+ // summary:
+ // Perform row styling on a given row. Called whenever row styling is updated.
+ //
+ // inRow: Object
+ // Object containing row state information: selected, true if the row is selcted; over:
+ // true of the mouse is over the row; odd: true if the row is odd. Use customClasses and
+ // customStyles to control row css classes and styles; both properties are strings.
+ //
+ // example: onStyleRow({ selected: true, over:true, odd:false })
+ var i = inRow;
+ i.customClasses += (i.odd?" dojoxGridRowOdd":"") + (i.selected?" dojoxGridRowSelected":"") + (i.over?" dojoxGridRowOver":"");
+ this.focus.styleRow(inRow);
+ this.edit.styleRow(inRow);
+ },
+
+ onKeyDown: function(e){
+ // summary:
+ // Grid key event handler. By default enter begins editing and applies edits, escape cancels an edit,
+ // tab, shift-tab, and arrow keys move grid cell focus.
+ if(e.altKey || e.metaKey){
+ return;
+ }
+ var colIdx;
+ switch(e.keyCode){
+ case keys.ESCAPE:
+ this.edit.cancel();
+ break;
+ case keys.ENTER:
+ if(!this.edit.isEditing()){
+ colIdx = this.focus.getHeaderIndex();
+ if(colIdx >= 0) {
+ this.setSortIndex(colIdx);
+ break;
+ }else {
+ this.selection.clickSelect(this.focus.rowIndex, dojo.isCopyKey(e), e.shiftKey);
+ }
+ event.stop(e);
+ }
+ if(!e.shiftKey){
+ var isEditing = this.edit.isEditing();
+ this.edit.apply();
+ if(!isEditing){
+ this.edit.setEditCell(this.focus.cell, this.focus.rowIndex);
+ }
+ }
+ if (!this.edit.isEditing()){
+ var curView = this.focus.focusView || this.views.views[0]; //if no focusView than only one view
+ curView.content.decorateEvent(e);
+ this.onRowClick(e);
+ event.stop(e);
+ }
+ break;
+ case keys.SPACE:
+ if(!this.edit.isEditing()){
+ colIdx = this.focus.getHeaderIndex();
+ if(colIdx >= 0) {
+ this.setSortIndex(colIdx);
+ break;
+ }else {
+ this.selection.clickSelect(this.focus.rowIndex, dojo.isCopyKey(e), e.shiftKey);
+ }
+ event.stop(e);
+ }
+ break;
+ case keys.TAB:
+ this.focus[e.shiftKey ? 'previousKey' : 'nextKey'](e);
+ break;
+ case keys.LEFT_ARROW:
+ case keys.RIGHT_ARROW:
+ if(!this.edit.isEditing()){
+ var keyCode = e.keyCode; // IE seems to lose after stopEvent when modifier keys
+ event.stop(e);
+ colIdx = this.focus.getHeaderIndex();
+ if (colIdx >= 0 && (e.shiftKey && e.ctrlKey)){
+ this.focus.colSizeAdjust(e, colIdx, (keyCode == keys.LEFT_ARROW ? -1 : 1)*5);
+ }
+ else{
+ var offset = (keyCode == keys.LEFT_ARROW) ? 1 : -1;
+ if(this.isLeftToRight()){ offset *= -1; }
+ this.focus.move(0, offset);
+ }
+ }
+ break;
+ case keys.UP_ARROW:
+ if(!this.edit.isEditing() && this.focus.rowIndex !== 0){
+ event.stop(e);
+ this.focus.move(-1, 0);
+ }
+ break;
+ case keys.DOWN_ARROW:
+ if(!this.edit.isEditing() && this.focus.rowIndex+1 != this.rowCount){
+ event.stop(e);
+ this.focus.move(1, 0);
+ }
+ break;
+ case keys.PAGE_UP:
+ if(!this.edit.isEditing() && this.focus.rowIndex !== 0){
+ event.stop(e);
+ if(this.focus.rowIndex != this.scroller.firstVisibleRow+1){
+ this.focus.move(this.scroller.firstVisibleRow-this.focus.rowIndex, 0);
+ }else{
+ this.setScrollTop(this.scroller.findScrollTop(this.focus.rowIndex-1));
+ this.focus.move(this.scroller.firstVisibleRow-this.scroller.lastVisibleRow+1, 0);
+ }
+ }
+ break;
+ case keys.PAGE_DOWN:
+ if(!this.edit.isEditing() && this.focus.rowIndex+1 != this.rowCount){
+ event.stop(e);
+ if(this.focus.rowIndex != this.scroller.lastVisibleRow-1){
+ this.focus.move(this.scroller.lastVisibleRow-this.focus.rowIndex-1, 0);
+ }else{
+ this.setScrollTop(this.scroller.findScrollTop(this.focus.rowIndex+1));
+ this.focus.move(this.scroller.lastVisibleRow-this.scroller.firstVisibleRow-1, 0);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ },
+
+ onMouseOver: function(e){
+ // summary:
+ // Event fired when mouse is over the grid.
+ // e: Event
+ // Decorated event object contains reference to grid, cell, and rowIndex
+ e.rowIndex == -1 ? this.onHeaderCellMouseOver(e) : this.onCellMouseOver(e);
+ },
+
+ onMouseOut: function(e){
+ // summary:
+ // Event fired when mouse moves out of the grid.
+ // e: Event
+ // Decorated event object that contains reference to grid, cell, and rowIndex
+ e.rowIndex == -1 ? this.onHeaderCellMouseOut(e) : this.onCellMouseOut(e);
+ },
+
+ onMouseDown: function(e){
+ // summary:
+ // Event fired when mouse is down inside grid.
+ // e: Event
+ // Decorated event object that contains reference to grid, cell, and rowIndex
+ e.rowIndex == -1 ? this.onHeaderCellMouseDown(e) : this.onCellMouseDown(e);
+ },
+
+ onMouseOverRow: function(e){
+ // summary:
+ // Event fired when mouse is over any row (data or header).
+ // e: Event
+ // Decorated event object contains reference to grid, cell, and rowIndex
+ if(!this.rows.isOver(e.rowIndex)){
+ this.rows.setOverRow(e.rowIndex);
+ e.rowIndex == -1 ? this.onHeaderMouseOver(e) : this.onRowMouseOver(e);
+ }
+ },
+ onMouseOutRow: function(e){
+ // summary:
+ // Event fired when mouse moves out of any row (data or header).
+ // e: Event
+ // Decorated event object contains reference to grid, cell, and rowIndex
+ if(this.rows.isOver(-1)){
+ this.onHeaderMouseOut(e);
+ }else if(!this.rows.isOver(-2)){
+ this.rows.setOverRow(-2);
+ this.onRowMouseOut(e);
+ }
+ },
+
+ onMouseDownRow: function(e){
+ // summary:
+ // Event fired when mouse is down inside grid row
+ // e: Event
+ // Decorated event object that contains reference to grid, cell, and rowIndex
+ if(e.rowIndex != -1)
+ this.onRowMouseDown(e);
+ },
+
+ // cell events
+ onCellMouseOver: function(e){
+ // summary:
+ // Event fired when mouse is over a cell.
+ // e: Event
+ // Decorated event object contains reference to grid, cell, and rowIndex
+ if(e.cellNode){
+ domClass.add(e.cellNode, this.cellOverClass);
+ }
+ },
+
+ onCellMouseOut: function(e){
+ // summary:
+ // Event fired when mouse moves out of a cell.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ if(e.cellNode){
+ domClass.remove(e.cellNode, this.cellOverClass);
+ }
+ },
+
+ onCellMouseDown: function(e){
+ // summary:
+ // Event fired when mouse is down in a header cell.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ },
+
+ onCellClick: function(e){
+ // summary:
+ // Event fired when a cell is clicked.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ this._click[0] = this._click[1];
+ this._click[1] = e;
+ if(!this.edit.isEditCell(e.rowIndex, e.cellIndex)){
+ this.focus.setFocusCell(e.cell, e.rowIndex);
+ }
+ // in some cases click[0] is null which causes false doubeClicks. Fixes #100703
+ if(this._click.length > 1 && this._click[0] == null){
+ this._click.shift();
+ }
+ this.onRowClick(e);
+ },
+
+ onCellDblClick: function(e){
+ // summary:
+ // Event fired when a cell is double-clicked.
+ // e: Event
+ // Decorated event object contains reference to grid, cell, and rowIndex
+ var event;
+ if(this._click.length > 1 && has("ie")){
+ event = this._click[1];
+ }else if(this._click.length > 1 && this._click[0].rowIndex != this._click[1].rowIndex){
+ event = this._click[0];
+ }else{
+ event = e;
+ }
+ this.focus.setFocusCell(event.cell, event.rowIndex);
+ this.onRowClick(event);
+ this.edit.setEditCell(event.cell, event.rowIndex);
+ this.onRowDblClick(e);
+ },
+
+ onCellContextMenu: function(e){
+ // summary:
+ // Event fired when a cell context menu is accessed via mouse right click.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ this.onRowContextMenu(e);
+ },
+
+ onCellFocus: function(inCell, inRowIndex){
+ // summary:
+ // Event fired when a cell receives focus.
+ // inCell: Object
+ // Cell object containing properties of the grid column.
+ // inRowIndex: Integer
+ // Index of the grid row
+ this.edit.cellFocus(inCell, inRowIndex);
+ },
+
+ // row events
+ onRowClick: function(e){
+ // summary:
+ // Event fired when a row is clicked.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ this.edit.rowClick(e);
+ this.selection.clickSelectEvent(e);
+ },
+
+ onRowDblClick: function(e){
+ // summary:
+ // Event fired when a row is double clicked.
+ // e: Event
+ // decorated event object which contains reference to grid, cell, and rowIndex
+ },
+
+ onRowMouseOver: function(e){
+ // summary:
+ // Event fired when mouse moves over a data row.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ },
+
+ onRowMouseOut: function(e){
+ // summary:
+ // Event fired when mouse moves out of a data row.
+ // e: Event
+ // Decorated event object contains reference to grid, cell, and rowIndex
+ },
+
+ onRowMouseDown: function(e){
+ // summary:
+ // Event fired when mouse is down in a row.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ },
+
+ onRowContextMenu: function(e){
+ // summary:
+ // Event fired when a row context menu is accessed via mouse right click.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ event.stop(e);
+ },
+
+ // header events
+ onHeaderMouseOver: function(e){
+ // summary:
+ // Event fired when mouse moves over the grid header.
+ // e: Event
+ // Decorated event object contains reference to grid, cell, and rowIndex
+ },
+
+ onHeaderMouseOut: function(e){
+ // summary:
+ // Event fired when mouse moves out of the grid header.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ },
+
+ onHeaderCellMouseOver: function(e){
+ // summary:
+ // Event fired when mouse moves over a header cell.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ if(e.cellNode){
+ domClass.add(e.cellNode, this.cellOverClass);
+ }
+ },
+
+ onHeaderCellMouseOut: function(e){
+ // summary:
+ // Event fired when mouse moves out of a header cell.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ if(e.cellNode){
+ domClass.remove(e.cellNode, this.cellOverClass);
+ }
+ },
+
+ onHeaderCellMouseDown: function(e) {
+ // summary:
+ // Event fired when mouse is down in a header cell.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ },
+
+ onHeaderClick: function(e){
+ // summary:
+ // Event fired when the grid header is clicked.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ },
+
+ onHeaderCellClick: function(e){
+ // summary:
+ // Event fired when a header cell is clicked.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ this.setSortIndex(e.cell.index);
+ this.onHeaderClick(e);
+ },
+
+ onHeaderDblClick: function(e){
+ // summary:
+ // Event fired when the grid header is double clicked.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ },
+
+ onHeaderCellDblClick: function(e){
+ // summary:
+ // Event fired when a header cell is double clicked.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ this.onHeaderDblClick(e);
+ },
+
+ onHeaderCellContextMenu: function(e){
+ // summary:
+ // Event fired when a header cell context menu is accessed via mouse right click.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ this.onHeaderContextMenu(e);
+ },
+
+ onHeaderContextMenu: function(e){
+ // summary:
+ // Event fired when the grid header context menu is accessed via mouse right click.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ if(!this.headerMenu){
+ event.stop(e);
+ }
+ },
+
+ // editing
+ onStartEdit: function(inCell, inRowIndex){
+ // summary:
+ // Event fired when editing is started for a given grid cell
+ // inCell: Object
+ // Cell object containing properties of the grid column.
+ // inRowIndex: Integer
+ // Index of the grid row
+ },
+
+ onApplyCellEdit: function(inValue, inRowIndex, inFieldIndex){
+ // summary:
+ // Event fired when editing is applied for a given grid cell
+ // inValue: String
+ // Value from cell editor
+ // inRowIndex: Integer
+ // Index of the grid row
+ // inFieldIndex: Integer
+ // Index in the grid's data store
+ },
+
+ onCancelEdit: function(inRowIndex){
+ // summary:
+ // Event fired when editing is cancelled for a given grid cell
+ // inRowIndex: Integer
+ // Index of the grid row
+ },
+
+ onApplyEdit: function(inRowIndex){
+ // summary:
+ // Event fired when editing is applied for a given grid row
+ // inRowIndex: Integer
+ // Index of the grid row
+ },
+
+ onCanSelect: function(inRowIndex){
+ // summary:
+ // Event to determine if a grid row may be selected
+ // inRowIndex: Integer
+ // Index of the grid row
+ // returns: Boolean
+ // true if the row can be selected
+ return true;
+ },
+
+ onCanDeselect: function(inRowIndex){
+ // summary:
+ // Event to determine if a grid row may be deselected
+ // inRowIndex: Integer
+ // Index of the grid row
+ // returns: Boolean
+ // true if the row can be deselected
+ return true;
+ },
+
+ onSelected: function(inRowIndex){
+ // summary:
+ // Event fired when a grid row is selected
+ // inRowIndex: Integer
+ // Index of the grid row
+ this.updateRowStyles(inRowIndex);
+ },
+
+ onDeselected: function(inRowIndex){
+ // summary:
+ // Event fired when a grid row is deselected
+ // inRowIndex: Integer
+ // Index of the grid row
+ this.updateRowStyles(inRowIndex);
+ },
+
+ onSelectionChanged: function(){
+ }
+});
+});
+},
+'dojo/dnd/autoscroll':function(){
+define(["../main", "../window"], function(dojo) {
+ // module:
+ // dojo/dnd/autoscroll
+ // summary:
+ // TODOC
+
+dojo.getObject("dnd", true, dojo);
+
+dojo.dnd.getViewport = dojo.window.getBox;
+
+dojo.dnd.V_TRIGGER_AUTOSCROLL = 32;
+dojo.dnd.H_TRIGGER_AUTOSCROLL = 32;
+
+dojo.dnd.V_AUTOSCROLL_VALUE = 16;
+dojo.dnd.H_AUTOSCROLL_VALUE = 16;
+
+dojo.dnd.autoScroll = function(e){
+ // summary:
+ // a handler for onmousemove event, which scrolls the window, if
+ // necesary
+ // e: Event
+ // onmousemove event
+
+ // FIXME: needs more docs!
+ var v = dojo.window.getBox(), dx = 0, dy = 0;
+ if(e.clientX < dojo.dnd.H_TRIGGER_AUTOSCROLL){
+ dx = -dojo.dnd.H_AUTOSCROLL_VALUE;
+ }else if(e.clientX > v.w - dojo.dnd.H_TRIGGER_AUTOSCROLL){
+ dx = dojo.dnd.H_AUTOSCROLL_VALUE;
+ }
+ if(e.clientY < dojo.dnd.V_TRIGGER_AUTOSCROLL){
+ dy = -dojo.dnd.V_AUTOSCROLL_VALUE;
+ }else if(e.clientY > v.h - dojo.dnd.V_TRIGGER_AUTOSCROLL){
+ dy = dojo.dnd.V_AUTOSCROLL_VALUE;
+ }
+ window.scrollBy(dx, dy);
+};
+
+dojo.dnd._validNodes = {"div": 1, "p": 1, "td": 1};
+dojo.dnd._validOverflow = {"auto": 1, "scroll": 1};
+
+dojo.dnd.autoScrollNodes = function(e){
+ // summary:
+ // a handler for onmousemove event, which scrolls the first avaialble
+ // Dom element, it falls back to dojo.dnd.autoScroll()
+ // e: Event
+ // onmousemove event
+
+ // FIXME: needs more docs!
+
+ var b, t, w, h, rx, ry, dx = 0, dy = 0, oldLeft, oldTop;
+
+ for(var n = e.target; n;){
+ if(n.nodeType == 1 && (n.tagName.toLowerCase() in dojo.dnd._validNodes)){
+ var s = dojo.getComputedStyle(n),
+ overflow = (s.overflow.toLowerCase() in dojo.dnd._validOverflow),
+ overflowX = (s.overflowX.toLowerCase() in dojo.dnd._validOverflow),
+ overflowY = (s.overflowY.toLowerCase() in dojo.dnd._validOverflow);
+ if(overflow || overflowX || overflowY){
+ b = dojo._getContentBox(n, s);
+ t = dojo.position(n, true);
+ }
+ // overflow-x
+ if(overflow || overflowX){
+ w = Math.min(dojo.dnd.H_TRIGGER_AUTOSCROLL, b.w / 2);
+ rx = e.pageX - t.x;
+ if(dojo.isWebKit || dojo.isOpera){
+ // FIXME: this code should not be here, it should be taken into account
+ // either by the event fixing code, or the dojo.position()
+ // FIXME: this code doesn't work on Opera 9.5 Beta
+ rx += dojo.body().scrollLeft;
+ }
+ dx = 0;
+ if(rx > 0 && rx < b.w){
+ if(rx < w){
+ dx = -w;
+ }else if(rx > b.w - w){
+ dx = w;
+ }
+ oldLeft = n.scrollLeft;
+ n.scrollLeft = n.scrollLeft + dx;
+ }
+ }
+ // overflow-y
+ if(overflow || overflowY){
+ //console.log(b.l, b.t, t.x, t.y, n.scrollLeft, n.scrollTop);
+ h = Math.min(dojo.dnd.V_TRIGGER_AUTOSCROLL, b.h / 2);
+ ry = e.pageY - t.y;
+ if(dojo.isWebKit || dojo.isOpera){
+ // FIXME: this code should not be here, it should be taken into account
+ // either by the event fixing code, or the dojo.position()
+ // FIXME: this code doesn't work on Opera 9.5 Beta
+ ry += dojo.body().scrollTop;
+ }
+ dy = 0;
+ if(ry > 0 && ry < b.h){
+ if(ry < h){
+ dy = -h;
+ }else if(ry > b.h - h){
+ dy = h;
+ }
+ oldTop = n.scrollTop;
+ n.scrollTop = n.scrollTop + dy;
+ }
+ }
+ if(dx || dy){ return; }
+ }
+ try{
+ n = n.parentNode;
+ }catch(x){
+ n = null;
+ }
+ }
+ dojo.dnd.autoScroll(e);
+};
+
+ return dojo.dnd;
+});
+
+},
+'dijit/registry':function(){
+define("dijit/registry", [
+ "dojo/_base/array", // array.forEach array.map
+ "dojo/_base/sniff", // has("ie")
+ "dojo/_base/unload", // unload.addOnWindowUnload
+ "dojo/_base/window", // win.body
+ "." // dijit._scopeName
+], function(array, has, unload, win, dijit){
+
+ // module:
+ // dijit/registry
+ // summary:
+ // Registry of existing widget on page, plus some utility methods.
+ // Must be accessed through AMD api, ex:
+ // require(["dijit/registry"], function(registry){ registry.byId("foo"); })
+
+ var _widgetTypeCtr = {}, hash = {};
+
+ var registry = {
+ // summary:
+ // A set of widgets indexed by id
+
+ length: 0,
+
+ add: function(/*dijit._Widget*/ widget){
+ // summary:
+ // Add a widget to the registry. If a duplicate ID is detected, a error is thrown.
+ //
+ // widget: dijit._Widget
+ // Any dijit._Widget subclass.
+ if(hash[widget.id]){
+ throw new Error("Tried to register widget with id==" + widget.id + " but that id is already registered");
+ }
+ hash[widget.id] = widget;
+ this.length++;
+ },
+
+ remove: function(/*String*/ id){
+ // summary:
+ // Remove a widget from the registry. Does not destroy the widget; simply
+ // removes the reference.
+ if(hash[id]){
+ delete hash[id];
+ this.length--;
+ }
+ },
+
+ byId: function(/*String|Widget*/ id){
+ // summary:
+ // Find a widget by it's id.
+ // If passed a widget then just returns the widget.
+ return typeof id == "string" ? hash[id] : id; // dijit._Widget
+ },
+
+ byNode: function(/*DOMNode*/ node){
+ // summary:
+ // Returns the widget corresponding to the given DOMNode
+ return hash[node.getAttribute("widgetId")]; // dijit._Widget
+ },
+
+ toArray: function(){
+ // summary:
+ // Convert registry into a true Array
+ //
+ // example:
+ // Work with the widget .domNodes in a real Array
+ // | array.map(dijit.registry.toArray(), function(w){ return w.domNode; });
+
+ var ar = [];
+ for(var id in hash){
+ ar.push(hash[id]);
+ }
+ return ar; // dijit._Widget[]
+ },
+
+ getUniqueId: function(/*String*/widgetType){
+ // summary:
+ // Generates a unique id for a given widgetType
+
+ var id;
+ do{
+ id = widgetType + "_" +
+ (widgetType in _widgetTypeCtr ?
+ ++_widgetTypeCtr[widgetType] : _widgetTypeCtr[widgetType] = 0);
+ }while(hash[id]);
+ return dijit._scopeName == "dijit" ? id : dijit._scopeName + "_" + id; // String
+ },
+
+ findWidgets: function(/*DomNode*/ root){
+ // summary:
+ // Search subtree under root returning widgets found.
+ // Doesn't search for nested widgets (ie, widgets inside other widgets).
+
+ var outAry = [];
+
+ function getChildrenHelper(root){
+ for(var node = root.firstChild; node; node = node.nextSibling){
+ if(node.nodeType == 1){
+ var widgetId = node.getAttribute("widgetId");
+ if(widgetId){
+ var widget = hash[widgetId];
+ if(widget){ // may be null on page w/multiple dojo's loaded
+ outAry.push(widget);
+ }
+ }else{
+ getChildrenHelper(node);
+ }
+ }
+ }
+ }
+
+ getChildrenHelper(root);
+ return outAry;
+ },
+
+ _destroyAll: function(){
+ // summary:
+ // Code to destroy all widgets and do other cleanup on page unload
+
+ // Clean up focus manager lingering references to widgets and nodes
+ dijit._curFocus = null;
+ dijit._prevFocus = null;
+ dijit._activeStack = [];
+
+ // Destroy all the widgets, top down
+ array.forEach(registry.findWidgets(win.body()), function(widget){
+ // Avoid double destroy of widgets like Menu that are attached to <body>
+ // even though they are logically children of other widgets.
+ if(!widget._destroyed){
+ if(widget.destroyRecursive){
+ widget.destroyRecursive();
+ }else if(widget.destroy){
+ widget.destroy();
+ }
+ }
+ });
+ },
+
+ getEnclosingWidget: function(/*DOMNode*/ node){
+ // summary:
+ // Returns the widget whose DOM tree contains the specified DOMNode, or null if
+ // the node is not contained within the DOM tree of any widget
+ while(node){
+ var id = node.getAttribute && node.getAttribute("widgetId");
+ if(id){
+ return hash[id];
+ }
+ node = node.parentNode;
+ }
+ return null;
+ },
+
+ // In case someone needs to access hash.
+ // Actually, this is accessed from WidgetSet back-compatibility code
+ _hash: hash
+ };
+
+ if(has("ie")){
+ // Only run _destroyAll() for IE because we think it's only necessary in that case,
+ // and because it causes problems on FF. See bug #3531 for details.
+ unload.addOnWindowUnload(function(){
+ registry._destroyAll();
+ });
+ }
+
+ /*=====
+ dijit.registry = {
+ // summary:
+ // A list of widgets on a page.
+ };
+ =====*/
+ dijit.registry = registry;
+
+ return registry;
+});
+
+},
+'dijit/_base/manager':function(){
+define("dijit/_base/manager", [
+ "dojo/_base/array",
+ "dojo/_base/config", // defaultDuration
+ "../registry",
+ ".." // for setting exports to dijit namespace
+], function(array, config, registry, dijit){
+
+ // module:
+ // dijit/_base/manager
+ // summary:
+ // Shim to methods on registry, plus a few other declarations.
+ // New code should access dijit/registry directly when possible.
+
+ /*=====
+ dijit.byId = function(id){
+ // summary:
+ // Returns a widget by it's id, or if passed a widget, no-op (like dom.byId())
+ // id: String|dijit._Widget
+ return registry.byId(id); // dijit._Widget
+ };
+
+ dijit.getUniqueId = function(widgetType){
+ // summary:
+ // Generates a unique id for a given widgetType
+ // widgetType: String
+ return registry.getUniqueId(widgetType); // String
+ };
+
+ dijit.findWidgets = function(root){
+ // summary:
+ // Search subtree under root returning widgets found.
+ // Doesn't search for nested widgets (ie, widgets inside other widgets).
+ // root: DOMNode
+ return registry.findWidgets(root);
+ };
+
+ dijit._destroyAll = function(){
+ // summary:
+ // Code to destroy all widgets and do other cleanup on page unload
+
+ return registry._destroyAll();
+ };
+
+ dijit.byNode = function(node){
+ // summary:
+ // Returns the widget corresponding to the given DOMNode
+ // node: DOMNode
+ return registry.byNode(node); // dijit._Widget
+ };
+
+ dijit.getEnclosingWidget = function(node){
+ // summary:
+ // Returns the widget whose DOM tree contains the specified DOMNode, or null if
+ // the node is not contained within the DOM tree of any widget
+ // node: DOMNode
+ return registry.getEnclosingWidget(node);
+ };
+ =====*/
+ array.forEach(["byId", "getUniqueId", "findWidgets", "_destroyAll", "byNode", "getEnclosingWidget"], function(name){
+ dijit[name] = registry[name];
+ });
+
+ /*=====
+ dojo.mixin(dijit, {
+ // defaultDuration: Integer
+ // The default fx.animation speed (in ms) to use for all Dijit
+ // transitional fx.animations, unless otherwise specified
+ // on a per-instance basis. Defaults to 200, overrided by
+ // `djConfig.defaultDuration`
+ defaultDuration: 200
+ });
+ =====*/
+ dijit.defaultDuration = config["defaultDuration"] || 200;
+
+ return dijit;
+});
+
+},
+'dojox/html/metrics':function(){
+define("dojox/html/metrics", ["dojo/_base/kernel","dojo/_base/lang", "dojo/_base/sniff", "dojo/ready", "dojo/_base/unload",
+ "dojo/_base/window", "dojo/dom-geometry"],
+ function(kernel,lang,has,ready,UnloadUtil,Window,DOMGeom){
+ var dhm = lang.getObject("dojox.html.metrics",true);
+ var dojox = lang.getObject("dojox");
+
+ // derived from Morris John's emResized measurer
+ dhm.getFontMeasurements = function(){
+ // summary
+ // Returns an object that has pixel equivilents of standard font size values.
+ var heights = {
+ '1em':0, '1ex':0, '100%':0, '12pt':0, '16px':0, 'xx-small':0, 'x-small':0,
+ 'small':0, 'medium':0, 'large':0, 'x-large':0, 'xx-large':0
+ };
+
+ if(has("ie")){
+ // we do a font-size fix if and only if one isn't applied already.
+ // NOTE: If someone set the fontSize on the HTML Element, this will kill it.
+ Window.doc.documentElement.style.fontSize="100%";
+ }
+
+ // set up the measuring node.
+ var div=Window.doc.createElement("div");
+ var ds = div.style;
+ ds.position="absolute";
+ ds.left="-100px";
+ ds.top="0";
+ ds.width="30px";
+ ds.height="1000em";
+ ds.borderWidth="0";
+ ds.margin="0";
+ ds.padding="0";
+ ds.outline="0";
+ ds.lineHeight="1";
+ ds.overflow="hidden";
+ Window.body().appendChild(div);
+
+ // do the measurements.
+ for(var p in heights){
+ ds.fontSize = p;
+ heights[p] = Math.round(div.offsetHeight * 12/16) * 16/12 / 1000;
+ }
+
+ Window.body().removeChild(div);
+ div = null;
+ return heights; // object
+ };
+
+ var fontMeasurements = null;
+
+ dhm.getCachedFontMeasurements = function(recalculate){
+ if(recalculate || !fontMeasurements){
+ fontMeasurements = dhm.getFontMeasurements();
+ }
+ return fontMeasurements;
+ };
+
+ var measuringNode = null, empty = {};
+ dhm.getTextBox = function(/* String */ text, /* Object */ style, /* String? */ className){
+ var m, s;
+ if(!measuringNode){
+ m = measuringNode = Window.doc.createElement("div");
+ // Container that we can set contraints on so that it doesn't
+ // trigger a scrollbar.
+ var c = Window.doc.createElement("div");
+ c.appendChild(m);
+ s = c.style;
+ s.overflow='scroll';
+ s.position = "absolute";
+ s.left = "0px";
+ s.top = "-10000px";
+ s.width = "1px";
+ s.height = "1px";
+ s.visibility = "hidden";
+ s.borderWidth = "0";
+ s.margin = "0";
+ s.padding = "0";
+ s.outline = "0";
+ Window.body().appendChild(c);
+ }else{
+ m = measuringNode;
+ }
+ // reset styles
+ m.className = "";
+ s = m.style;
+ s.borderWidth = "0";
+ s.margin = "0";
+ s.padding = "0";
+ s.outline = "0";
+ // set new style
+ if(arguments.length > 1 && style){
+ for(var i in style){
+ if(i in empty){ continue; }
+ s[i] = style[i];
+ }
+ }
+ // set classes
+ if(arguments.length > 2 && className){
+ m.className = className;
+ }
+ // take a measure
+ m.innerHTML = text;
+ var box = DOMGeom.position(m);
+ // position doesn't report right (reports 1, since parent is 1)
+ // So we have to look at the scrollWidth to get the real width
+ // Height is right.
+ box.w = m.parentNode.scrollWidth;
+ return box;
+ };
+
+ // determine the scrollbar sizes on load.
+ var scroll={ w:16, h:16 };
+ dhm.getScrollbar=function(){ return { w:scroll.w, h:scroll.h }; };
+
+ dhm._fontResizeNode = null;
+
+ dhm.initOnFontResize = function(interval){
+ var f = dhm._fontResizeNode = Window.doc.createElement("iframe");
+ var fs = f.style;
+ fs.position = "absolute";
+ fs.width = "5em";
+ fs.height = "10em";
+ fs.top = "-10000px";
+ if(has("ie")){
+ f.onreadystatechange = function(){
+ if(f.contentWindow.document.readyState == "complete"){
+ f.onresize = f.contentWindow.parent[dojox._scopeName].html.metrics._fontresize;
+ }
+ };
+ }else{
+ f.onload = function(){
+ f.contentWindow.onresize = f.contentWindow.parent[dojox._scopeName].html.metrics._fontresize;
+ };
+ }
+ //The script tag is to work around a known firebug race condition. See comments in bug #9046
+ f.setAttribute("src", "javascript:'<html><head><script>if(\"loadFirebugConsole\" in window){window.loadFirebugConsole();}</script></head><body></body></html>'");
+ Window.body().appendChild(f);
+ dhm.initOnFontResize = function(){};
+ };
+
+ dhm.onFontResize = function(){};
+ dhm._fontresize = function(){
+ dhm.onFontResize();
+ }
+
+ UnloadUtil.addOnUnload(function(){
+ // destroy our font resize iframe if we have one
+ var f = dhm._fontResizeNode;
+ if(f){
+ if(has("ie") && f.onresize){
+ f.onresize = null;
+ }else if(f.contentWindow && f.contentWindow.onresize){
+ f.contentWindow.onresize = null;
+ }
+ dhm._fontResizeNode = null;
+ }
+ });
+
+ ready(function(){
+ // getScrollbar metrics node
+ try{
+ var n=Window.doc.createElement("div");
+ n.style.cssText = "top:0;left:0;width:100px;height:100px;overflow:scroll;position:absolute;visibility:hidden;";
+ Window.body().appendChild(n);
+ scroll.w = n.offsetWidth - n.clientWidth;
+ scroll.h = n.offsetHeight - n.clientHeight;
+ Window.body().removeChild(n);
+ //console.log("Scroll bar dimensions: ", scroll);
+ delete n;
+ }catch(e){}
+
+ // text size poll setup
+ if("fontSizeWatch" in kernel.config && !!kernel.config.fontSizeWatch){
+ dhm.initOnFontResize();
+ }
+ });
+ return dhm;
+});
+},
+'dojox/grid/_EditManager':function(){
+define("dojox/grid/_EditManager", [
+ "dojo/_base/lang",
+ "dojo/_base/array",
+ "dojo/_base/declare",
+ "dojo/_base/connect",
+ "dojo/_base/sniff",
+ "./util"
+], function(lang, array, declare, connect, has, util){
+
+return declare("dojox.grid._EditManager", null, {
+ // summary:
+ // Controls grid cell editing process. Owned by grid and used internally for editing.
+ constructor: function(inGrid){
+ // inGrid: dojox.Grid
+ // The dojox.Grid this editor should be attached to
+ this.grid = inGrid;
+ if(has("ie")){
+ this.connections = [connect.connect(document.body, "onfocus", lang.hitch(this, "_boomerangFocus"))];
+ }else{
+ this.connections = [connect.connect(this.grid, 'onBlur', this, 'apply')];
+ }
+ },
+
+ info: {},
+
+ destroy: function(){
+ array.forEach(this.connections, connect.disconnect);
+ },
+
+ cellFocus: function(inCell, inRowIndex){
+ // summary:
+ // Invoke editing when cell is focused
+ // inCell: cell object
+ // Grid cell object
+ // inRowIndex: Integer
+ // Grid row index
+ if(this.grid.singleClickEdit || this.isEditRow(inRowIndex)){
+ // if same row or quick editing, edit
+ this.setEditCell(inCell, inRowIndex);
+ }else{
+ // otherwise, apply any pending row edits
+ this.apply();
+ }
+ // if dynamic or static editing...
+ if(this.isEditing() || (inCell && inCell.editable && inCell.alwaysEditing)){
+ // let the editor focus itself as needed
+ this._focusEditor(inCell, inRowIndex);
+ }
+ },
+
+ rowClick: function(e){
+ if(this.isEditing() && !this.isEditRow(e.rowIndex)){
+ this.apply();
+ }
+ },
+
+ styleRow: function(inRow){
+ if(inRow.index == this.info.rowIndex){
+ inRow.customClasses += ' dojoxGridRowEditing';
+ }
+ },
+
+ dispatchEvent: function(e){
+ var c = e.cell, ed = (c && c["editable"]) ? c : 0;
+ return ed && ed.dispatchEvent(e.dispatch, e);
+ },
+
+ // Editing
+ isEditing: function(){
+ // summary:
+ // Indicates editing state of the grid.
+ // returns: Boolean
+ // True if grid is actively editing
+ return this.info.rowIndex !== undefined;
+ },
+
+ isEditCell: function(inRowIndex, inCellIndex){
+ // summary:
+ // Indicates if the given cell is being edited.
+ // inRowIndex: Integer
+ // Grid row index
+ // inCellIndex: Integer
+ // Grid cell index
+ // returns: Boolean
+ // True if given cell is being edited
+ return (this.info.rowIndex === inRowIndex) && (this.info.cell.index == inCellIndex);
+ },
+
+ isEditRow: function(inRowIndex){
+ // summary:
+ // Indicates if the given row is being edited.
+ // inRowIndex: Integer
+ // Grid row index
+ // returns: Boolean
+ // True if given row is being edited
+ return this.info.rowIndex === inRowIndex;
+ },
+
+ setEditCell: function(inCell, inRowIndex){
+ // summary:
+ // Set the given cell to be edited
+ // inRowIndex: Integer
+ // Grid row index
+ // inCell: Object
+ // Grid cell object
+ if(!this.isEditCell(inRowIndex, inCell.index) && this.grid.canEdit && this.grid.canEdit(inCell, inRowIndex)){
+ this.start(inCell, inRowIndex, this.isEditRow(inRowIndex) || inCell.editable);
+ }
+ },
+
+ _focusEditor: function(inCell, inRowIndex){
+ util.fire(inCell, "focus", [inRowIndex]);
+ },
+
+ focusEditor: function(){
+ if(this.isEditing()){
+ this._focusEditor(this.info.cell, this.info.rowIndex);
+ }
+ },
+
+ // implement fix for focus boomerang effect on IE
+ _boomerangWindow: 500,
+ _shouldCatchBoomerang: function(){
+ return this._catchBoomerang > new Date().getTime();
+ },
+ _boomerangFocus: function(){
+ //console.log("_boomerangFocus");
+ if(this._shouldCatchBoomerang()){
+ // make sure we don't utterly lose focus
+ this.grid.focus.focusGrid();
+ // let the editor focus itself as needed
+ this.focusEditor();
+ // only catch once
+ this._catchBoomerang = 0;
+ }
+ },
+ _doCatchBoomerang: function(){
+ // give ourselves a few ms to boomerang IE focus effects
+ if(has("ie")){this._catchBoomerang = new Date().getTime() + this._boomerangWindow;}
+ },
+ // end boomerang fix API
+
+ start: function(inCell, inRowIndex, inEditing){
+ if(!this._isValidInput()){
+ return;
+ }
+ this.grid.beginUpdate();
+ this.editorApply();
+ if(this.isEditing() && !this.isEditRow(inRowIndex)){
+ this.applyRowEdit();
+ this.grid.updateRow(inRowIndex);
+ }
+ if(inEditing){
+ this.info = { cell: inCell, rowIndex: inRowIndex };
+ this.grid.doStartEdit(inCell, inRowIndex);
+ this.grid.updateRow(inRowIndex);
+ }else{
+ this.info = {};
+ }
+ this.grid.endUpdate();
+ // make sure we don't utterly lose focus
+ this.grid.focus.focusGrid();
+ // let the editor focus itself as needed
+ this._focusEditor(inCell, inRowIndex);
+ // give ourselves a few ms to boomerang IE focus effects
+ this._doCatchBoomerang();
+ },
+
+ _editorDo: function(inMethod){
+ var c = this.info.cell;
+ //c && c.editor && c.editor[inMethod](c, this.info.rowIndex);
+ if(c && c.editable){
+ c[inMethod](this.info.rowIndex);
+ }
+ },
+
+ editorApply: function(){
+ this._editorDo("apply");
+ },
+
+ editorCancel: function(){
+ this._editorDo("cancel");
+ },
+
+ applyCellEdit: function(inValue, inCell, inRowIndex){
+ if(this.grid.canEdit(inCell, inRowIndex)){
+ this.grid.doApplyCellEdit(inValue, inRowIndex, inCell.field);
+ }
+ },
+
+ applyRowEdit: function(){
+ this.grid.doApplyEdit(this.info.rowIndex, this.info.cell.field);
+ },
+
+ apply: function(){
+ // summary:
+ // Apply a grid edit
+ if(this.isEditing() && this._isValidInput()){
+ this.grid.beginUpdate();
+ this.editorApply();
+ this.applyRowEdit();
+ this.info = {};
+ this.grid.endUpdate();
+ this.grid.focus.focusGrid();
+ this._doCatchBoomerang();
+ }
+ },
+
+ cancel: function(){
+ // summary:
+ // Cancel a grid edit
+ if(this.isEditing()){
+ this.grid.beginUpdate();
+ this.editorCancel();
+ this.info = {};
+ this.grid.endUpdate();
+ this.grid.focus.focusGrid();
+ this._doCatchBoomerang();
+ }
+ },
+
+ save: function(inRowIndex, inView){
+ // summary:
+ // Save the grid editing state
+ // inRowIndex: Integer
+ // Grid row index
+ // inView: Object
+ // Grid view
+ var c = this.info.cell;
+ if(this.isEditRow(inRowIndex) && (!inView || c.view==inView) && c.editable){
+ c.save(c, this.info.rowIndex);
+ }
+ },
+
+ restore: function(inView, inRowIndex){
+ // summary:
+ // Restores the grid editing state
+ // inRowIndex: Integer
+ // Grid row index
+ // inView: Object
+ // Grid view
+ var c = this.info.cell;
+ if(this.isEditRow(inRowIndex) && c.view == inView && c.editable){
+ c.restore(this.info.rowIndex);
+ }
+ },
+
+ _isValidInput: function(){
+ var w = (this.info.cell || {}).widget;
+ if(!w || !w.isValid){
+ //no validation needed
+ return true;
+ }
+ w.focused = true;
+ return w.isValid(true);
+ }
+});
+});
+},
+'dijit/a11y':function(){
+define("dijit/a11y", [
+ "dojo/_base/array", // array.forEach array.map
+ "dojo/_base/config", // defaultDuration
+ "dojo/_base/declare", // declare
+ "dojo/dom", // dom.byId
+ "dojo/dom-attr", // domAttr.attr domAttr.has
+ "dojo/dom-style", // style.style
+ "dojo/_base/sniff", // has("ie")
+ "./_base/manager", // manager._isElementShown
+ "." // for exporting methods to dijit namespace
+], function(array, config, declare, dom, domAttr, domStyle, has, manager, dijit){
+
+ // module:
+ // dijit/a11y
+ // summary:
+ // Accessibility utility functions (keyboard, tab stops, etc.)
+
+ var shown = (dijit._isElementShown = function(/*Element*/ elem){
+ var s = domStyle.get(elem);
+ return (s.visibility != "hidden")
+ && (s.visibility != "collapsed")
+ && (s.display != "none")
+ && (domAttr.get(elem, "type") != "hidden");
+ });
+
+ dijit.hasDefaultTabStop = function(/*Element*/ elem){
+ // summary:
+ // Tests if element is tab-navigable even without an explicit tabIndex setting
+
+ // No explicit tabIndex setting, need to investigate node type
+ switch(elem.nodeName.toLowerCase()){
+ case "a":
+ // An <a> w/out a tabindex is only navigable if it has an href
+ return domAttr.has(elem, "href");
+ case "area":
+ case "button":
+ case "input":
+ case "object":
+ case "select":
+ case "textarea":
+ // These are navigable by default
+ return true;
+ case "iframe":
+ // If it's an editor <iframe> then it's tab navigable.
+ var body;
+ try{
+ // non-IE
+ var contentDocument = elem.contentDocument;
+ if("designMode" in contentDocument && contentDocument.designMode == "on"){
+ return true;
+ }
+ body = contentDocument.body;
+ }catch(e1){
+ // contentWindow.document isn't accessible within IE7/8
+ // if the iframe.src points to a foreign url and this
+ // page contains an element, that could get focus
+ try{
+ body = elem.contentWindow.document.body;
+ }catch(e2){
+ return false;
+ }
+ }
+ return body && (body.contentEditable == 'true' ||
+ (body.firstChild && body.firstChild.contentEditable == 'true'));
+ default:
+ return elem.contentEditable == 'true';
+ }
+ };
+
+ var isTabNavigable = (dijit.isTabNavigable = function(/*Element*/ elem){
+ // summary:
+ // Tests if an element is tab-navigable
+
+ // TODO: convert (and rename method) to return effective tabIndex; will save time in _getTabNavigable()
+ if(domAttr.get(elem, "disabled")){
+ return false;
+ }else if(domAttr.has(elem, "tabIndex")){
+ // Explicit tab index setting
+ return domAttr.get(elem, "tabIndex") >= 0; // boolean
+ }else{
+ // No explicit tabIndex setting, so depends on node type
+ return dijit.hasDefaultTabStop(elem);
+ }
+ });
+
+ dijit._getTabNavigable = function(/*DOMNode*/ root){
+ // summary:
+ // Finds descendants of the specified root node.
+ //
+ // description:
+ // Finds the following descendants of the specified root node:
+ // * the first tab-navigable element in document order
+ // without a tabIndex or with tabIndex="0"
+ // * the last tab-navigable element in document order
+ // without a tabIndex or with tabIndex="0"
+ // * the first element in document order with the lowest
+ // positive tabIndex value
+ // * the last element in document order with the highest
+ // positive tabIndex value
+ var first, last, lowest, lowestTabindex, highest, highestTabindex, radioSelected = {};
+
+ function radioName(node){
+ // If this element is part of a radio button group, return the name for that group.
+ return node && node.tagName.toLowerCase() == "input" &&
+ node.type && node.type.toLowerCase() == "radio" &&
+ node.name && node.name.toLowerCase();
+ }
+
+ var walkTree = function(/*DOMNode*/parent){
+ for(var child = parent.firstChild; child; child = child.nextSibling){
+ // Skip text elements, hidden elements, and also non-HTML elements (those in custom namespaces) in IE,
+ // since show() invokes getAttribute("type"), which crash on VML nodes in IE.
+ if(child.nodeType != 1 || (has("ie") && child.scopeName !== "HTML") || !shown(child)){
+ continue;
+ }
+
+ if(isTabNavigable(child)){
+ var tabindex = domAttr.get(child, "tabIndex");
+ if(!domAttr.has(child, "tabIndex") || tabindex == 0){
+ if(!first){
+ first = child;
+ }
+ last = child;
+ }else if(tabindex > 0){
+ if(!lowest || tabindex < lowestTabindex){
+ lowestTabindex = tabindex;
+ lowest = child;
+ }
+ if(!highest || tabindex >= highestTabindex){
+ highestTabindex = tabindex;
+ highest = child;
+ }
+ }
+ var rn = radioName(child);
+ if(domAttr.get(child, "checked") && rn){
+ radioSelected[rn] = child;
+ }
+ }
+ if(child.nodeName.toUpperCase() != 'SELECT'){
+ walkTree(child);
+ }
+ }
+ };
+ if(shown(root)){
+ walkTree(root);
+ }
+ function rs(node){
+ // substitute checked radio button for unchecked one, if there is a checked one with the same name.
+ return radioSelected[radioName(node)] || node;
+ }
+
+ return { first: rs(first), last: rs(last), lowest: rs(lowest), highest: rs(highest) };
+ };
+ dijit.getFirstInTabbingOrder = function(/*String|DOMNode*/ root){
+ // summary:
+ // Finds the descendant of the specified root node
+ // that is first in the tabbing order
+ var elems = dijit._getTabNavigable(dom.byId(root));
+ return elems.lowest ? elems.lowest : elems.first; // DomNode
+ };
+
+ dijit.getLastInTabbingOrder = function(/*String|DOMNode*/ root){
+ // summary:
+ // Finds the descendant of the specified root node
+ // that is last in the tabbing order
+ var elems = dijit._getTabNavigable(dom.byId(root));
+ return elems.last ? elems.last : elems.highest; // DomNode
+ };
+
+ return {
+ hasDefaultTabStop: dijit.hasDefaultTabStop,
+ isTabNavigable: dijit.isTabNavigable,
+ _getTabNavigable: dijit._getTabNavigable,
+ getFirstInTabbingOrder: dijit.getFirstInTabbingOrder,
+ getLastInTabbingOrder: dijit.getLastInTabbingOrder
+ };
+});
+
+},
+'dijit/CheckedMenuItem':function(){
+require({cache:{
+'url:dijit/templates/CheckedMenuItem.html':"<tr class=\"dijitReset dijitMenuItem\" data-dojo-attach-point=\"focusNode\" role=\"menuitemcheckbox\" tabIndex=\"-1\"\n\t\tdata-dojo-attach-event=\"onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick\">\n\t<td class=\"dijitReset dijitMenuItemIconCell\" role=\"presentation\">\n\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitMenuItemIcon dijitCheckedMenuItemIcon\" data-dojo-attach-point=\"iconNode\"/>\n\t\t<span class=\"dijitCheckedMenuItemIconChar\">&#10003;</span>\n\t</td>\n\t<td class=\"dijitReset dijitMenuItemLabel\" colspan=\"2\" data-dojo-attach-point=\"containerNode,labelNode\"></td>\n\t<td class=\"dijitReset dijitMenuItemAccelKey\" style=\"display: none\" data-dojo-attach-point=\"accelKeyNode\"></td>\n\t<td class=\"dijitReset dijitMenuArrowCell\" role=\"presentation\">&#160;</td>\n</tr>\n"}});
+define("dijit/CheckedMenuItem", [
+ "dojo/_base/declare", // declare
+ "dojo/dom-class", // domClass.toggle
+ "./MenuItem",
+ "dojo/text!./templates/CheckedMenuItem.html",
+ "./hccss"
+], function(declare, domClass, MenuItem, template){
+
+/*=====
+ var MenuItem = dijit.MenuItem;
+=====*/
+
+ // module:
+ // dijit/CheckedMenuItem
+ // summary:
+ // A checkbox-like menu item for toggling on and off
+
+ return declare("dijit.CheckedMenuItem", MenuItem, {
+ // summary:
+ // A checkbox-like menu item for toggling on and off
+
+ templateString: template,
+
+ // checked: Boolean
+ // Our checked state
+ checked: false,
+ _setCheckedAttr: function(/*Boolean*/ checked){
+ // summary:
+ // Hook so attr('checked', bool) works.
+ // Sets the class and state for the check box.
+ domClass.toggle(this.domNode, "dijitCheckedMenuItemChecked", checked);
+ this.domNode.setAttribute("aria-checked", checked);
+ this._set("checked", checked);
+ },
+
+ iconClass: "", // override dijitNoIcon
+
+ onChange: function(/*Boolean*/ /*===== checked =====*/){
+ // summary:
+ // User defined function to handle check/uncheck events
+ // tags:
+ // callback
+ },
+
+ _onClick: function(/*Event*/ e){
+ // summary:
+ // Clicking this item just toggles its state
+ // tags:
+ // private
+ if(!this.disabled){
+ this.set("checked", !this.checked);
+ this.onChange(this.checked);
+ }
+ this.inherited(arguments);
+ }
+ });
+});
+
+},
+'dojo/dnd/Container':function(){
+define(["../main", "../Evented", "./common", "../parser"], function(dojo, Evented) {
+ // module:
+ // dojo/dnd/Container
+ // summary:
+ // TODOC
+
+
+/*
+ Container states:
+ "" - normal state
+ "Over" - mouse over a container
+ Container item states:
+ "" - normal state
+ "Over" - mouse over a container item
+*/
+
+/*=====
+dojo.declare("dojo.dnd.__ContainerArgs", [], {
+ creator: function(){
+ // summary:
+ // a creator function, which takes a data item, and returns an object like that:
+ // {node: newNode, data: usedData, type: arrayOfStrings}
+ },
+
+ // skipForm: Boolean
+ // don't start the drag operation, if clicked on form elements
+ skipForm: false,
+
+ // dropParent: Node||String
+ // node or node's id to use as the parent node for dropped items
+ // (must be underneath the 'node' parameter in the DOM)
+ dropParent: null,
+
+ // _skipStartup: Boolean
+ // skip startup(), which collects children, for deferred initialization
+ // (this is used in the markup mode)
+ _skipStartup: false
+});
+
+dojo.dnd.Item = function(){
+ // summary:
+ // Represents (one of) the source node(s) being dragged.
+ // Contains (at least) the "type" and "data" attributes.
+ // type: String[]
+ // Type(s) of this item, by default this is ["text"]
+ // data: Object
+ // Logical representation of the object being dragged.
+ // If the drag object's type is "text" then data is a String,
+ // if it's another type then data could be a different Object,
+ // perhaps a name/value hash.
+
+ this.type = type;
+ this.data = data;
+}
+=====*/
+
+dojo.declare("dojo.dnd.Container", Evented, {
+ // summary:
+ // a Container object, which knows when mouse hovers over it,
+ // and over which element it hovers
+
+ // object attributes (for markup)
+ skipForm: false,
+
+ /*=====
+ // current: DomNode
+ // The DOM node the mouse is currently hovered over
+ current: null,
+
+ // map: Hash<String, dojo.dnd.Item>
+ // Map from an item's id (which is also the DOMNode's id) to
+ // the dojo.dnd.Item itself.
+ map: {},
+ =====*/
+
+ constructor: function(node, params){
+ // summary:
+ // a constructor of the Container
+ // node: Node
+ // node or node's id to build the container on
+ // params: dojo.dnd.__ContainerArgs
+ // a dictionary of parameters
+ this.node = dojo.byId(node);
+ if(!params){ params = {}; }
+ this.creator = params.creator || null;
+ this.skipForm = params.skipForm;
+ this.parent = params.dropParent && dojo.byId(params.dropParent);
+
+ // class-specific variables
+ this.map = {};
+ this.current = null;
+
+ // states
+ this.containerState = "";
+ dojo.addClass(this.node, "dojoDndContainer");
+
+ // mark up children
+ if(!(params && params._skipStartup)){
+ this.startup();
+ }
+
+ // set up events
+ this.events = [
+ dojo.connect(this.node, "onmouseover", this, "onMouseOver"),
+ dojo.connect(this.node, "onmouseout", this, "onMouseOut"),
+ // cancel text selection and text dragging
+ dojo.connect(this.node, "ondragstart", this, "onSelectStart"),
+ dojo.connect(this.node, "onselectstart", this, "onSelectStart")
+ ];
+ },
+
+ // object attributes (for markup)
+ creator: function(){
+ // summary:
+ // creator function, dummy at the moment
+ },
+
+ // abstract access to the map
+ getItem: function(/*String*/ key){
+ // summary:
+ // returns a data item by its key (id)
+ return this.map[key]; // dojo.dnd.Item
+ },
+ setItem: function(/*String*/ key, /*dojo.dnd.Item*/ data){
+ // summary:
+ // associates a data item with its key (id)
+ this.map[key] = data;
+ },
+ delItem: function(/*String*/ key){
+ // summary:
+ // removes a data item from the map by its key (id)
+ delete this.map[key];
+ },
+ forInItems: function(/*Function*/ f, /*Object?*/ o){
+ // summary:
+ // iterates over a data map skipping members that
+ // are present in the empty object (IE and/or 3rd-party libraries).
+ o = o || dojo.global;
+ var m = this.map, e = dojo.dnd._empty;
+ for(var i in m){
+ if(i in e){ continue; }
+ f.call(o, m[i], i, this);
+ }
+ return o; // Object
+ },
+ clearItems: function(){
+ // summary:
+ // removes all data items from the map
+ this.map = {};
+ },
+
+ // methods
+ getAllNodes: function(){
+ // summary:
+ // returns a list (an array) of all valid child nodes
+ return dojo.query("> .dojoDndItem", this.parent); // NodeList
+ },
+ sync: function(){
+ // summary:
+ // sync up the node list with the data map
+ var map = {};
+ this.getAllNodes().forEach(function(node){
+ if(node.id){
+ var item = this.getItem(node.id);
+ if(item){
+ map[node.id] = item;
+ return;
+ }
+ }else{
+ node.id = dojo.dnd.getUniqueId();
+ }
+ var type = node.getAttribute("dndType"),
+ data = node.getAttribute("dndData");
+ map[node.id] = {
+ data: data || node.innerHTML,
+ type: type ? type.split(/\s*,\s*/) : ["text"]
+ };
+ }, this);
+ this.map = map;
+ return this; // self
+ },
+ insertNodes: function(data, before, anchor){
+ // summary:
+ // inserts an array of new nodes before/after an anchor node
+ // data: Array
+ // a list of data items, which should be processed by the creator function
+ // before: Boolean
+ // insert before the anchor, if true, and after the anchor otherwise
+ // anchor: Node
+ // the anchor node to be used as a point of insertion
+ if(!this.parent.firstChild){
+ anchor = null;
+ }else if(before){
+ if(!anchor){
+ anchor = this.parent.firstChild;
+ }
+ }else{
+ if(anchor){
+ anchor = anchor.nextSibling;
+ }
+ }
+ if(anchor){
+ for(var i = 0; i < data.length; ++i){
+ var t = this._normalizedCreator(data[i]);
+ this.setItem(t.node.id, {data: t.data, type: t.type});
+ this.parent.insertBefore(t.node, anchor);
+ }
+ }else{
+ for(var i = 0; i < data.length; ++i){
+ var t = this._normalizedCreator(data[i]);
+ this.setItem(t.node.id, {data: t.data, type: t.type});
+ this.parent.appendChild(t.node);
+ }
+ }
+ return this; // self
+ },
+ destroy: function(){
+ // summary:
+ // prepares this object to be garbage-collected
+ dojo.forEach(this.events, dojo.disconnect);
+ this.clearItems();
+ this.node = this.parent = this.current = null;
+ },
+
+ // markup methods
+ markupFactory: function(params, node, ctor){
+ params._skipStartup = true;
+ return new ctor(node, params);
+ },
+ startup: function(){
+ // summary:
+ // collects valid child items and populate the map
+
+ // set up the real parent node
+ if(!this.parent){
+ // use the standard algorithm, if not assigned
+ this.parent = this.node;
+ if(this.parent.tagName.toLowerCase() == "table"){
+ var c = this.parent.getElementsByTagName("tbody");
+ if(c && c.length){ this.parent = c[0]; }
+ }
+ }
+ this.defaultCreator = dojo.dnd._defaultCreator(this.parent);
+
+ // process specially marked children
+ this.sync();
+ },
+
+ // mouse events
+ onMouseOver: function(e){
+ // summary:
+ // event processor for onmouseover
+ // e: Event
+ // mouse event
+ var n = e.relatedTarget;
+ while(n){
+ if(n == this.node){ break; }
+ try{
+ n = n.parentNode;
+ }catch(x){
+ n = null;
+ }
+ }
+ if(!n){
+ this._changeState("Container", "Over");
+ this.onOverEvent();
+ }
+ n = this._getChildByEvent(e);
+ if(this.current == n){ return; }
+ if(this.current){ this._removeItemClass(this.current, "Over"); }
+ if(n){ this._addItemClass(n, "Over"); }
+ this.current = n;
+ },
+ onMouseOut: function(e){
+ // summary:
+ // event processor for onmouseout
+ // e: Event
+ // mouse event
+ for(var n = e.relatedTarget; n;){
+ if(n == this.node){ return; }
+ try{
+ n = n.parentNode;
+ }catch(x){
+ n = null;
+ }
+ }
+ if(this.current){
+ this._removeItemClass(this.current, "Over");
+ this.current = null;
+ }
+ this._changeState("Container", "");
+ this.onOutEvent();
+ },
+ onSelectStart: function(e){
+ // summary:
+ // event processor for onselectevent and ondragevent
+ // e: Event
+ // mouse event
+ if(!this.skipForm || !dojo.dnd.isFormElement(e)){
+ dojo.stopEvent(e);
+ }
+ },
+
+ // utilities
+ onOverEvent: function(){
+ // summary:
+ // this function is called once, when mouse is over our container
+ },
+ onOutEvent: function(){
+ // summary:
+ // this function is called once, when mouse is out of our container
+ },
+ _changeState: function(type, newState){
+ // summary:
+ // changes a named state to new state value
+ // type: String
+ // a name of the state to change
+ // newState: String
+ // new state
+ var prefix = "dojoDnd" + type;
+ var state = type.toLowerCase() + "State";
+ //dojo.replaceClass(this.node, prefix + newState, prefix + this[state]);
+ dojo.replaceClass(this.node, prefix + newState, prefix + this[state]);
+ this[state] = newState;
+ },
+ _addItemClass: function(node, type){
+ // summary:
+ // adds a class with prefix "dojoDndItem"
+ // node: Node
+ // a node
+ // type: String
+ // a variable suffix for a class name
+ dojo.addClass(node, "dojoDndItem" + type);
+ },
+ _removeItemClass: function(node, type){
+ // summary:
+ // removes a class with prefix "dojoDndItem"
+ // node: Node
+ // a node
+ // type: String
+ // a variable suffix for a class name
+ dojo.removeClass(node, "dojoDndItem" + type);
+ },
+ _getChildByEvent: function(e){
+ // summary:
+ // gets a child, which is under the mouse at the moment, or null
+ // e: Event
+ // a mouse event
+ var node = e.target;
+ if(node){
+ for(var parent = node.parentNode; parent; node = parent, parent = node.parentNode){
+ if(parent == this.parent && dojo.hasClass(node, "dojoDndItem")){ return node; }
+ }
+ }
+ return null;
+ },
+ _normalizedCreator: function(/*dojo.dnd.Item*/ item, /*String*/ hint){
+ // summary:
+ // adds all necessary data to the output of the user-supplied creator function
+ var t = (this.creator || this.defaultCreator).call(this, item, hint);
+ if(!dojo.isArray(t.type)){ t.type = ["text"]; }
+ if(!t.node.id){ t.node.id = dojo.dnd.getUniqueId(); }
+ dojo.addClass(t.node, "dojoDndItem");
+ return t;
+ }
+});
+
+dojo.dnd._createNode = function(tag){
+ // summary:
+ // returns a function, which creates an element of given tag
+ // (SPAN by default) and sets its innerHTML to given text
+ // tag: String
+ // a tag name or empty for SPAN
+ if(!tag){ return dojo.dnd._createSpan; }
+ return function(text){ // Function
+ return dojo.create(tag, {innerHTML: text}); // Node
+ };
+};
+
+dojo.dnd._createTrTd = function(text){
+ // summary:
+ // creates a TR/TD structure with given text as an innerHTML of TD
+ // text: String
+ // a text for TD
+ var tr = dojo.create("tr");
+ dojo.create("td", {innerHTML: text}, tr);
+ return tr; // Node
+};
+
+dojo.dnd._createSpan = function(text){
+ // summary:
+ // creates a SPAN element with given text as its innerHTML
+ // text: String
+ // a text for SPAN
+ return dojo.create("span", {innerHTML: text}); // Node
+};
+
+// dojo.dnd._defaultCreatorNodes: Object
+// a dictionary that maps container tag names to child tag names
+dojo.dnd._defaultCreatorNodes = {ul: "li", ol: "li", div: "div", p: "div"};
+
+dojo.dnd._defaultCreator = function(node){
+ // summary:
+ // takes a parent node, and returns an appropriate creator function
+ // node: Node
+ // a container node
+ var tag = node.tagName.toLowerCase();
+ var c = tag == "tbody" || tag == "thead" ? dojo.dnd._createTrTd :
+ dojo.dnd._createNode(dojo.dnd._defaultCreatorNodes[tag]);
+ return function(item, hint){ // Function
+ var isObj = item && dojo.isObject(item), data, type, n;
+ if(isObj && item.tagName && item.nodeType && item.getAttribute){
+ // process a DOM node
+ data = item.getAttribute("dndData") || item.innerHTML;
+ type = item.getAttribute("dndType");
+ type = type ? type.split(/\s*,\s*/) : ["text"];
+ n = item; // this node is going to be moved rather than copied
+ }else{
+ // process a DnD item object or a string
+ data = (isObj && item.data) ? item.data : item;
+ type = (isObj && item.type) ? item.type : ["text"];
+ n = (hint == "avatar" ? dojo.dnd._createSpan : c)(String(data));
+ }
+ if(!n.id){
+ n.id = dojo.dnd.getUniqueId();
+ }
+ return {node: n, data: data, type: type};
+ };
+};
+
+return dojo.dnd.Container;
+});
+
+},
+'dojo/dnd/common':function(){
+define(["../main"], function(dojo) {
+ // module:
+ // dojo/dnd/common
+ // summary:
+ // TODOC
+
+dojo.getObject("dnd", true, dojo);
+
+dojo.dnd.getCopyKeyState = dojo.isCopyKey;
+
+dojo.dnd._uniqueId = 0;
+dojo.dnd.getUniqueId = function(){
+ // summary:
+ // returns a unique string for use with any DOM element
+ var id;
+ do{
+ id = dojo._scopeName + "Unique" + (++dojo.dnd._uniqueId);
+ }while(dojo.byId(id));
+ return id;
+};
+
+dojo.dnd._empty = {};
+
+dojo.dnd.isFormElement = function(/*Event*/ e){
+ // summary:
+ // returns true if user clicked on a form element
+ var t = e.target;
+ if(t.nodeType == 3 /*TEXT_NODE*/){
+ t = t.parentNode;
+ }
+ return " button textarea input select option ".indexOf(" " + t.tagName.toLowerCase() + " ") >= 0; // Boolean
+};
+
+return dojo.dnd;
+});
+
+},
+'dojox/grid/_ViewManager':function(){
+define("dojox/grid/_ViewManager", [
+ "dojo/_base/declare",
+ "dojo/_base/sniff",
+ "dojo/dom-class"
+], function(declare, has, domClass){
+
+return declare('dojox.grid._ViewManager', null, {
+ // summary:
+ // A collection of grid views. Owned by grid and used internally for managing grid views.
+ // description:
+ // Grid creates views automatically based on grid's layout structure.
+ // Users should typically not need to access individual views or the views collection directly.
+ constructor: function(inGrid){
+ this.grid = inGrid;
+ },
+
+ defaultWidth: 200,
+
+ views: [],
+
+ // operations
+ resize: function(){
+ this.onEach("resize");
+ },
+
+ render: function(){
+ this.onEach("render");
+ },
+
+ // views
+ addView: function(inView){
+ inView.idx = this.views.length;
+ this.views.push(inView);
+ },
+
+ destroyViews: function(){
+ for(var i=0, v; v=this.views[i]; i++){
+ v.destroy();
+ }
+ this.views = [];
+ },
+
+ getContentNodes: function(){
+ var nodes = [];
+ for(var i=0, v; v=this.views[i]; i++){
+ nodes.push(v.contentNode);
+ }
+ return nodes;
+ },
+
+ forEach: function(inCallback){
+ for(var i=0, v; v=this.views[i]; i++){
+ inCallback(v, i);
+ }
+ },
+
+ onEach: function(inMethod, inArgs){
+ inArgs = inArgs || [];
+ for(var i=0, v; v=this.views[i]; i++){
+ if(inMethod in v){
+ v[inMethod].apply(v, inArgs);
+ }
+ }
+ },
+
+ // layout
+ normalizeHeaderNodeHeight: function(){
+ var rowNodes = [];
+ for(var i=0, v; (v=this.views[i]); i++){
+ if(v.headerContentNode.firstChild){
+ rowNodes.push(v.headerContentNode);
+ }
+ }
+ this.normalizeRowNodeHeights(rowNodes);
+ },
+
+ normalizeRowNodeHeights: function(inRowNodes){
+ var h = 0;
+ var currHeights = [];
+ if(this.grid.rowHeight){
+ h = this.grid.rowHeight;
+ }else{
+ if(inRowNodes.length <= 1){
+ // no need to normalize if we are the only one...
+ return;
+ }
+ for(var i=0, n; (n=inRowNodes[i]); i++){
+ // We only care about the height - so don't use marginBox. This
+ // depends on the container not having any margin (which it shouldn't)
+ // Also - we only look up the height if the cell doesn't have the
+ // dojoxGridNonNormalizedCell class (like for row selectors)
+ if(!domClass.contains(n, "dojoxGridNonNormalizedCell")){
+ currHeights[i] = n.firstChild.offsetHeight;
+ h = Math.max(h, currHeights[i]);
+ }
+ }
+ h = (h >= 0 ? h : 0);
+
+ //Work around odd FF3 rendering bug: #8864.
+ //A one px increase fixes FireFox 3's rounding bug for fractional font sizes.
+ if((has("mozilla") || has("ie") > 8 ) && h){h++;}
+ }
+ for(i=0; (n=inRowNodes[i]); i++){
+ if(currHeights[i] != h){
+ n.firstChild.style.height = h + "px";
+ }
+ }
+ },
+
+ resetHeaderNodeHeight: function(){
+ for(var i=0, v, n; (v=this.views[i]); i++){
+ n = v.headerContentNode.firstChild;
+ if(n){
+ n.style.height = "";
+ }
+ }
+ },
+
+ renormalizeRow: function(inRowIndex){
+ var rowNodes = [];
+ for(var i=0, v, n; (v=this.views[i])&&(n=v.getRowNode(inRowIndex)); i++){
+ n.firstChild.style.height = '';
+ rowNodes.push(n);
+ }
+ this.normalizeRowNodeHeights(rowNodes);
+ },
+
+ getViewWidth: function(inIndex){
+ return this.views[inIndex].getWidth() || this.defaultWidth;
+ },
+
+ // must be called after view widths are properly set or height can be miscalculated
+ // if there are flex columns
+ measureHeader: function(){
+ // need to reset view header heights so they are properly measured.
+ this.resetHeaderNodeHeight();
+ this.forEach(function(inView){
+ inView.headerContentNode.style.height = '';
+ });
+ var h = 0;
+ // calculate maximum view header height
+ this.forEach(function(inView){
+ h = Math.max(inView.headerNode.offsetHeight, h);
+ });
+ return h;
+ },
+
+ measureContent: function(){
+ var h = 0;
+ this.forEach(function(inView){
+ h = Math.max(inView.domNode.offsetHeight, h);
+ });
+ return h;
+ },
+
+ findClient: function(inAutoWidth){
+ // try to use user defined client
+ var c = this.grid.elasticView || -1;
+ // attempt to find implicit client
+ if(c < 0){
+ for(var i=1, v; (v=this.views[i]); i++){
+ if(v.viewWidth){
+ for(i=1; (v=this.views[i]); i++){
+ if(!v.viewWidth){
+ c = i;
+ break;
+ }
+ }
+ break;
+ }
+ }
+ }
+ // client is in the middle by default
+ if(c < 0){
+ c = Math.floor(this.views.length / 2);
+ }
+ return c;
+ },
+
+ arrange: function(l, w){
+ var i, v, vw, len = this.views.length, self = this;
+ // find the client
+ var c = (w <= 0 ? len : this.findClient());
+ // layout views
+ var setPosition = function(v, l){
+ var ds = v.domNode.style;
+ var hs = v.headerNode.style;
+
+ if(!self.grid.isLeftToRight()){
+ ds.right = l + 'px';
+ // fixed rtl, the scrollbar is on the right side in FF or WebKit
+ if (has("ff") < 4 || has("webkit")){
+ hs.right = l + v.getScrollbarWidth() + 'px';
+ hs.width = parseInt(hs.width, 10) - v.getScrollbarWidth() + 'px';
+ }else{
+ hs.right = l + 'px';
+ }
+ }else{
+ ds.left = l + 'px';
+ hs.left = l + 'px';
+ }
+ ds.top = 0 + 'px';
+ hs.top = 0;
+ };
+ // for views left of the client
+ //BiDi TODO: The left and right should not appear in BIDI environment. Should be replaced with
+ //leading and tailing concept.
+ for(i=0; (v=this.views[i])&&(i<c); i++){
+ // get width
+ vw = this.getViewWidth(i);
+ // process boxes
+ v.setSize(vw, 0);
+ setPosition(v, l);
+ if(v.headerContentNode && v.headerContentNode.firstChild){
+ vw = v.getColumnsWidth()+v.getScrollbarWidth();
+ }else{
+ vw = v.domNode.offsetWidth;
+ }
+ // update position
+ l += vw;
+ }
+ // next view (is the client, i++ == c)
+ i++;
+ // start from the right edge
+ var r = w;
+ // for views right of the client (iterated from the right)
+ for(var j=len-1; (v=this.views[j])&&(i<=j); j--){
+ // get width
+ vw = this.getViewWidth(j);
+ // set size
+ v.setSize(vw, 0);
+ // measure in pixels
+ vw = v.domNode.offsetWidth;
+ // update position
+ r -= vw;
+ // set position
+ setPosition(v, r);
+ }
+ if(c<len){
+ v = this.views[c];
+ // position the client box between left and right boxes
+ vw = Math.max(1, r-l);
+ // set size
+ v.setSize(vw + 'px', 0);
+ setPosition(v, l);
+ }
+ return l;
+ },
+
+ // rendering
+ renderRow: function(inRowIndex, inNodes, skipRenorm){
+ var rowNodes = [];
+ for(var i=0, v, n, rowNode; (v=this.views[i])&&(n=inNodes[i]); i++){
+ rowNode = v.renderRow(inRowIndex);
+ n.appendChild(rowNode);
+ rowNodes.push(rowNode);
+ }
+ if(!skipRenorm){
+ this.normalizeRowNodeHeights(rowNodes);
+ }
+ },
+
+ rowRemoved: function(inRowIndex){
+ this.onEach("rowRemoved", [ inRowIndex ]);
+ },
+
+ // updating
+ updateRow: function(inRowIndex, skipRenorm){
+ for(var i=0, v; v=this.views[i]; i++){
+ v.updateRow(inRowIndex);
+ }
+ if(!skipRenorm){
+ this.renormalizeRow(inRowIndex);
+ }
+ },
+
+ updateRowStyles: function(inRowIndex){
+ this.onEach("updateRowStyles", [ inRowIndex ]);
+ },
+
+ // scrolling
+ setScrollTop: function(inTop){
+ var top = inTop;
+ for(var i=0, v; v=this.views[i]; i++){
+ top = v.setScrollTop(inTop);
+ // Work around IE not firing scroll events that cause header offset
+ // issues to occur.
+ if(has("ie") && v.headerNode && v.scrollboxNode){
+ v.headerNode.scrollLeft = v.scrollboxNode.scrollLeft;
+ }
+ }
+ return top;
+ //this.onEach("setScrollTop", [ inTop ]);
+ },
+
+ getFirstScrollingView: function(){
+ // summary: Returns the first grid view with a scroll bar
+ for(var i=0, v; (v=this.views[i]); i++){
+ if(v.hasHScrollbar() || v.hasVScrollbar()){
+ return v;
+ }
+ }
+ return null;
+ }
+});
+});
+},
+'dojox/grid/cells':function(){
+define("dojox/grid/cells", ["../main", "./cells/_base"], function(dojox){
+ return dojox.grid.cells;
+});
+},
+'dijit/_Widget':function(){
+define("dijit/_Widget", [
+ "dojo/aspect", // aspect.around
+ "dojo/_base/config", // config.isDebug
+ "dojo/_base/connect", // connect.connect
+ "dojo/_base/declare", // declare
+ "dojo/_base/kernel", // kernel.deprecated
+ "dojo/_base/lang", // lang.hitch
+ "dojo/query",
+ "dojo/ready",
+ "./registry", // registry.byNode
+ "./_WidgetBase",
+ "./_OnDijitClickMixin",
+ "./_FocusMixin",
+ "dojo/uacss", // browser sniffing (included for back-compat; subclasses may be using)
+ "./hccss" // high contrast mode sniffing (included to set CSS classes on <body>, module ret value unused)
+], function(aspect, config, connect, declare, kernel, lang, query, ready,
+ registry, _WidgetBase, _OnDijitClickMixin, _FocusMixin){
+
+/*=====
+ var _WidgetBase = dijit._WidgetBase;
+ var _OnDijitClickMixin = dijit._OnDijitClickMixin;
+ var _FocusMixin = dijit._FocusMixin;
+=====*/
+
+
+// module:
+// dijit/_Widget
+// summary:
+// Old base for widgets. New widgets should extend _WidgetBase instead
+
+
+function connectToDomNode(){
+ // summary:
+ // If user connects to a widget method === this function, then they will
+ // instead actually be connecting the equivalent event on this.domNode
+}
+
+// Trap dojo.connect() calls to connectToDomNode methods, and redirect to _Widget.on()
+function aroundAdvice(originalConnect){
+ return function(obj, event, scope, method){
+ if(obj && typeof event == "string" && obj[event] == connectToDomNode){
+ return obj.on(event.substring(2).toLowerCase(), lang.hitch(scope, method));
+ }
+ return originalConnect.apply(connect, arguments);
+ };
+}
+aspect.around(connect, "connect", aroundAdvice);
+if(kernel.connect){
+ aspect.around(kernel, "connect", aroundAdvice);
+}
+
+var _Widget = declare("dijit._Widget", [_WidgetBase, _OnDijitClickMixin, _FocusMixin], {
+ // summary:
+ // Base class for all Dijit widgets.
+ //
+ // Extends _WidgetBase, adding support for:
+ // - declaratively/programatically specifying widget initialization parameters like
+ // onMouseMove="foo" that call foo when this.domNode gets a mousemove event
+ // - ondijitclick
+ // Support new data-dojo-attach-event="ondijitclick: ..." that is triggered by a mouse click or a SPACE/ENTER keypress
+ // - focus related functions
+ // In particular, the onFocus()/onBlur() callbacks. Driven internally by
+ // dijit/_base/focus.js.
+ // - deprecated methods
+ // - onShow(), onHide(), onClose()
+ //
+ // Also, by loading code in dijit/_base, turns on:
+ // - browser sniffing (putting browser id like .dj_ie on <html> node)
+ // - high contrast mode sniffing (add .dijit_a11y class to <body> if machine is in high contrast mode)
+
+
+ ////////////////// DEFERRED CONNECTS ///////////////////
+
+ onClick: connectToDomNode,
+ /*=====
+ onClick: function(event){
+ // summary:
+ // Connect to this function to receive notifications of mouse click events.
+ // event:
+ // mouse Event
+ // tags:
+ // callback
+ },
+ =====*/
+ onDblClick: connectToDomNode,
+ /*=====
+ onDblClick: function(event){
+ // summary:
+ // Connect to this function to receive notifications of mouse double click events.
+ // event:
+ // mouse Event
+ // tags:
+ // callback
+ },
+ =====*/
+ onKeyDown: connectToDomNode,
+ /*=====
+ onKeyDown: function(event){
+ // summary:
+ // Connect to this function to receive notifications of keys being pressed down.
+ // event:
+ // key Event
+ // tags:
+ // callback
+ },
+ =====*/
+ onKeyPress: connectToDomNode,
+ /*=====
+ onKeyPress: function(event){
+ // summary:
+ // Connect to this function to receive notifications of printable keys being typed.
+ // event:
+ // key Event
+ // tags:
+ // callback
+ },
+ =====*/
+ onKeyUp: connectToDomNode,
+ /*=====
+ onKeyUp: function(event){
+ // summary:
+ // Connect to this function to receive notifications of keys being released.
+ // event:
+ // key Event
+ // tags:
+ // callback
+ },
+ =====*/
+ onMouseDown: connectToDomNode,
+ /*=====
+ onMouseDown: function(event){
+ // summary:
+ // Connect to this function to receive notifications of when the mouse button is pressed down.
+ // event:
+ // mouse Event
+ // tags:
+ // callback
+ },
+ =====*/
+ onMouseMove: connectToDomNode,
+ /*=====
+ onMouseMove: function(event){
+ // summary:
+ // Connect to this function to receive notifications of when the mouse moves over nodes contained within this widget.
+ // event:
+ // mouse Event
+ // tags:
+ // callback
+ },
+ =====*/
+ onMouseOut: connectToDomNode,
+ /*=====
+ onMouseOut: function(event){
+ // summary:
+ // Connect to this function to receive notifications of when the mouse moves off of nodes contained within this widget.
+ // event:
+ // mouse Event
+ // tags:
+ // callback
+ },
+ =====*/
+ onMouseOver: connectToDomNode,
+ /*=====
+ onMouseOver: function(event){
+ // summary:
+ // Connect to this function to receive notifications of when the mouse moves onto nodes contained within this widget.
+ // event:
+ // mouse Event
+ // tags:
+ // callback
+ },
+ =====*/
+ onMouseLeave: connectToDomNode,
+ /*=====
+ onMouseLeave: function(event){
+ // summary:
+ // Connect to this function to receive notifications of when the mouse moves off of this widget.
+ // event:
+ // mouse Event
+ // tags:
+ // callback
+ },
+ =====*/
+ onMouseEnter: connectToDomNode,
+ /*=====
+ onMouseEnter: function(event){
+ // summary:
+ // Connect to this function to receive notifications of when the mouse moves onto this widget.
+ // event:
+ // mouse Event
+ // tags:
+ // callback
+ },
+ =====*/
+ onMouseUp: connectToDomNode,
+ /*=====
+ onMouseUp: function(event){
+ // summary:
+ // Connect to this function to receive notifications of when the mouse button is released.
+ // event:
+ // mouse Event
+ // tags:
+ // callback
+ },
+ =====*/
+
+ constructor: function(params){
+ // extract parameters like onMouseMove that should connect directly to this.domNode
+ this._toConnect = {};
+ for(var name in params){
+ if(this[name] === connectToDomNode){
+ this._toConnect[name.replace(/^on/, "").toLowerCase()] = params[name];
+ delete params[name];
+ }
+ }
+ },
+
+ postCreate: function(){
+ this.inherited(arguments);
+
+ // perform connection from this.domNode to user specified handlers (ex: onMouseMove)
+ for(var name in this._toConnect){
+ this.on(name, this._toConnect[name]);
+ }
+ delete this._toConnect;
+ },
+
+ on: function(/*String*/ type, /*Function*/ func){
+ if(this[this._onMap(type)] === connectToDomNode){
+ // Use connect.connect() rather than on() to get handling for "onmouseenter" on non-IE, etc.
+ // Also, need to specify context as "this" rather than the default context of the DOMNode
+ return connect.connect(this.domNode, type.toLowerCase(), this, func);
+ }
+ return this.inherited(arguments);
+ },
+
+ _setFocusedAttr: function(val){
+ // Remove this method in 2.0 (or sooner), just here to set _focused == focused, for back compat
+ // (but since it's a private variable we aren't required to keep supporting it).
+ this._focused = val;
+ this._set("focused", val);
+ },
+
+ ////////////////// DEPRECATED METHODS ///////////////////
+
+ setAttribute: function(/*String*/ attr, /*anything*/ value){
+ // summary:
+ // Deprecated. Use set() instead.
+ // tags:
+ // deprecated
+ kernel.deprecated(this.declaredClass+"::setAttribute(attr, value) is deprecated. Use set() instead.", "", "2.0");
+ this.set(attr, value);
+ },
+
+ attr: function(/*String|Object*/name, /*Object?*/value){
+ // summary:
+ // Set or get properties on a widget instance.
+ // name:
+ // The property to get or set. If an object is passed here and not
+ // a string, its keys are used as names of attributes to be set
+ // and the value of the object as values to set in the widget.
+ // value:
+ // Optional. If provided, attr() operates as a setter. If omitted,
+ // the current value of the named property is returned.
+ // description:
+ // This method is deprecated, use get() or set() directly.
+
+ // Print deprecation warning but only once per calling function
+ if(config.isDebug){
+ var alreadyCalledHash = arguments.callee._ach || (arguments.callee._ach = {}),
+ caller = (arguments.callee.caller || "unknown caller").toString();
+ if(!alreadyCalledHash[caller]){
+ kernel.deprecated(this.declaredClass + "::attr() is deprecated. Use get() or set() instead, called from " +
+ caller, "", "2.0");
+ alreadyCalledHash[caller] = true;
+ }
+ }
+
+ var args = arguments.length;
+ if(args >= 2 || typeof name === "object"){ // setter
+ return this.set.apply(this, arguments);
+ }else{ // getter
+ return this.get(name);
+ }
+ },
+
+ getDescendants: function(){
+ // summary:
+ // Returns all the widgets contained by this, i.e., all widgets underneath this.containerNode.
+ // This method should generally be avoided as it returns widgets declared in templates, which are
+ // supposed to be internal/hidden, but it's left here for back-compat reasons.
+
+ kernel.deprecated(this.declaredClass+"::getDescendants() is deprecated. Use getChildren() instead.", "", "2.0");
+ return this.containerNode ? query('[widgetId]', this.containerNode).map(registry.byNode) : []; // dijit._Widget[]
+ },
+
+ ////////////////// MISCELLANEOUS METHODS ///////////////////
+
+ _onShow: function(){
+ // summary:
+ // Internal method called when this widget is made visible.
+ // See `onShow` for details.
+ this.onShow();
+ },
+
+ onShow: function(){
+ // summary:
+ // Called when this widget becomes the selected pane in a
+ // `dijit.layout.TabContainer`, `dijit.layout.StackContainer`,
+ // `dijit.layout.AccordionContainer`, etc.
+ //
+ // Also called to indicate display of a `dijit.Dialog`, `dijit.TooltipDialog`, or `dijit.TitlePane`.
+ // tags:
+ // callback
+ },
+
+ onHide: function(){
+ // summary:
+ // Called when another widget becomes the selected pane in a
+ // `dijit.layout.TabContainer`, `dijit.layout.StackContainer`,
+ // `dijit.layout.AccordionContainer`, etc.
+ //
+ // Also called to indicate hide of a `dijit.Dialog`, `dijit.TooltipDialog`, or `dijit.TitlePane`.
+ // tags:
+ // callback
+ },
+
+ onClose: function(){
+ // summary:
+ // Called when this widget is being displayed as a popup (ex: a Calendar popped
+ // up from a DateTextBox), and it is hidden.
+ // This is called from the dijit.popup code, and should not be called directly.
+ //
+ // Also used as a parameter for children of `dijit.layout.StackContainer` or subclasses.
+ // Callback if a user tries to close the child. Child will be closed if this function returns true.
+ // tags:
+ // extension
+
+ return true; // Boolean
+ }
+});
+
+// For back-compat, remove in 2.0.
+if(!kernel.isAsync){
+ ready(0, function(){
+ var requires = ["dijit/_base"];
+ require(requires); // use indirection so modules not rolled into a build
+ });
+}
+return _Widget;
+});
+
+},
+'dijit/_FocusMixin':function(){
+define("dijit/_FocusMixin", [
+ "./focus",
+ "./_WidgetBase",
+ "dojo/_base/declare", // declare
+ "dojo/_base/lang" // lang.extend
+], function(focus, _WidgetBase, declare, lang){
+
+/*=====
+ var _WidgetBase = dijit._WidgetBase;
+=====*/
+
+ // module:
+ // dijit/_FocusMixin
+ // summary:
+ // Mixin to widget to provide _onFocus() and _onBlur() methods that
+ // fire when a widget or it's descendants get/lose focus
+
+ // We don't know where _FocusMixin will occur in the inheritance chain, but we need the _onFocus()/_onBlur() below
+ // to be last in the inheritance chain, so mixin to _WidgetBase.
+ lang.extend(_WidgetBase, {
+ // focused: [readonly] Boolean
+ // This widget or a widget it contains has focus, or is "active" because
+ // it was recently clicked.
+ focused: false,
+
+ onFocus: function(){
+ // summary:
+ // Called when the widget becomes "active" because
+ // it or a widget inside of it either has focus, or has recently
+ // been clicked.
+ // tags:
+ // callback
+ },
+
+ onBlur: function(){
+ // summary:
+ // Called when the widget stops being "active" because
+ // focus moved to something outside of it, or the user
+ // clicked somewhere outside of it, or the widget was
+ // hidden.
+ // tags:
+ // callback
+ },
+
+ _onFocus: function(){
+ // summary:
+ // This is where widgets do processing for when they are active,
+ // such as changing CSS classes. See onFocus() for more details.
+ // tags:
+ // protected
+ this.onFocus();
+ },
+
+ _onBlur: function(){
+ // summary:
+ // This is where widgets do processing for when they stop being active,
+ // such as changing CSS classes. See onBlur() for more details.
+ // tags:
+ // protected
+ this.onBlur();
+ }
+ });
+
+ return declare("dijit._FocusMixin", null, {
+ // summary:
+ // Mixin to widget to provide _onFocus() and _onBlur() methods that
+ // fire when a widget or it's descendants get/lose focus
+
+ // flag that I want _onFocus()/_onBlur() notifications from focus manager
+ _focusManager: focus
+ });
+
+});
+
+},
+'dijit/_OnDijitClickMixin':function(){
+define("dijit/_OnDijitClickMixin", [
+ "dojo/on",
+ "dojo/_base/array", // array.forEach
+ "dojo/keys", // keys.ENTER keys.SPACE
+ "dojo/_base/declare", // declare
+ "dojo/_base/sniff", // has("ie")
+ "dojo/_base/unload", // unload.addOnWindowUnload
+ "dojo/_base/window" // win.doc.addEventListener win.doc.attachEvent win.doc.detachEvent
+], function(on, array, keys, declare, has, unload, win){
+
+ // module:
+ // dijit/_OnDijitClickMixin
+ // summary:
+ // Mixin so you can pass "ondijitclick" to this.connect() method,
+ // as a way to handle clicks by mouse, or by keyboard (SPACE/ENTER key)
+
+
+ // Keep track of where the last keydown event was, to help avoid generating
+ // spurious ondijitclick events when:
+ // 1. focus is on a <button> or <a>
+ // 2. user presses then releases the ENTER key
+ // 3. onclick handler fires and shifts focus to another node, with an ondijitclick handler
+ // 4. onkeyup event fires, causing the ondijitclick handler to fire
+ var lastKeyDownNode = null;
+ if(has("ie")){
+ (function(){
+ var keydownCallback = function(evt){
+ lastKeyDownNode = evt.srcElement;
+ };
+ win.doc.attachEvent('onkeydown', keydownCallback);
+ unload.addOnWindowUnload(function(){
+ win.doc.detachEvent('onkeydown', keydownCallback);
+ });
+ })();
+ }else{
+ win.doc.addEventListener('keydown', function(evt){
+ lastKeyDownNode = evt.target;
+ }, true);
+ }
+
+ // Custom a11yclick (a.k.a. ondijitclick) event
+ var a11yclick = function(node, listener){
+ if(/input|button/i.test(node.nodeName)){
+ // pass through, the browser already generates click event on SPACE/ENTER key
+ return on(node, "click", listener);
+ }else{
+ // Don't fire the click event unless both the keydown and keyup occur on this node.
+ // Avoids problems where focus shifted to this node or away from the node on keydown,
+ // either causing this node to process a stray keyup event, or causing another node
+ // to get a stray keyup event.
+
+ function clickKey(/*Event*/ e){
+ return (e.keyCode == keys.ENTER || e.keyCode == keys.SPACE) &&
+ !e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey;
+ }
+ var handles = [
+ on(node, "keypress", function(e){
+ //console.log(this.id + ": onkeydown, e.target = ", e.target, ", lastKeyDownNode was ", lastKeyDownNode, ", equality is ", (e.target === lastKeyDownNode));
+ if(clickKey(e)){
+ // needed on IE for when focus changes between keydown and keyup - otherwise dropdown menus do not work
+ lastKeyDownNode = e.target;
+
+ // Prevent viewport scrolling on space key in IE<9.
+ // (Reproducible on test_Button.html on any of the first dijit.form.Button examples)
+ // Do this onkeypress rather than onkeydown because onkeydown.preventDefault() will
+ // suppress the onkeypress event, breaking _HasDropDown
+ e.preventDefault();
+ }
+ }),
+
+ on(node, "keyup", function(e){
+ //console.log(this.id + ": onkeyup, e.target = ", e.target, ", lastKeyDownNode was ", lastKeyDownNode, ", equality is ", (e.target === lastKeyDownNode));
+ if(clickKey(e) && e.target == lastKeyDownNode){ // === breaks greasemonkey
+ //need reset here or have problems in FF when focus returns to trigger element after closing popup/alert
+ lastKeyDownNode = null;
+ listener.call(this, e);
+ }
+ }),
+
+ on(node, "click", function(e){
+ // and connect for mouse clicks too (or touch-clicks on mobile)
+ listener.call(this, e);
+ })
+ ];
+
+ return {
+ remove: function(){
+ array.forEach(handles, function(h){ h.remove(); });
+ }
+ };
+ }
+ };
+
+ return declare("dijit._OnDijitClickMixin", null, {
+ connect: function(
+ /*Object|null*/ obj,
+ /*String|Function*/ event,
+ /*String|Function*/ method){
+ // summary:
+ // Connects specified obj/event to specified method of this object
+ // and registers for disconnect() on widget destroy.
+ // description:
+ // Provide widget-specific analog to connect.connect, except with the
+ // implicit use of this widget as the target object.
+ // This version of connect also provides a special "ondijitclick"
+ // event which triggers on a click or space or enter keyup.
+ // Events connected with `this.connect` are disconnected upon
+ // destruction.
+ // returns:
+ // A handle that can be passed to `disconnect` in order to disconnect before
+ // the widget is destroyed.
+ // example:
+ // | var btn = new dijit.form.Button();
+ // | // when foo.bar() is called, call the listener we're going to
+ // | // provide in the scope of btn
+ // | btn.connect(foo, "bar", function(){
+ // | console.debug(this.toString());
+ // | });
+ // tags:
+ // protected
+
+ return this.inherited(arguments, [obj, event == "ondijitclick" ? a11yclick : event, method]);
+ }
+ });
+});
+
+},
+'dojo/cache':function(){
+define(["./_base/kernel", "./text"], function(dojo, text){
+ // module:
+ // dojo/cache
+ // summary:
+ // The module defines dojo.cache by loading dojo/text.
+
+ //dojo.cache is defined in dojo/text
+ return dojo.cache;
+});
+
+},
+'dijit/focus':function(){
+define("dijit/focus", [
+ "dojo/aspect",
+ "dojo/_base/declare", // declare
+ "dojo/dom", // domAttr.get dom.isDescendant
+ "dojo/dom-attr", // domAttr.get dom.isDescendant
+ "dojo/dom-construct", // connect to domConstruct.empty, domConstruct.destroy
+ "dojo/Evented",
+ "dojo/_base/lang", // lang.hitch
+ "dojo/on",
+ "dojo/ready",
+ "dojo/_base/sniff", // has("ie")
+ "dojo/Stateful",
+ "dojo/_base/unload", // unload.addOnWindowUnload
+ "dojo/_base/window", // win.body
+ "dojo/window", // winUtils.get
+ "./a11y", // a11y.isTabNavigable
+ "./registry", // registry.byId
+ "." // to set dijit.focus
+], function(aspect, declare, dom, domAttr, domConstruct, Evented, lang, on, ready, has, Stateful, unload, win, winUtils,
+ a11y, registry, dijit){
+
+ // module:
+ // dijit/focus
+ // summary:
+ // Returns a singleton that tracks the currently focused node, and which widgets are currently "active".
+
+/*=====
+ dijit.focus = {
+ // summary:
+ // Tracks the currently focused node, and which widgets are currently "active".
+ // Access via require(["dijit/focus"], function(focus){ ... }).
+ //
+ // A widget is considered active if it or a descendant widget has focus,
+ // or if a non-focusable node of this widget or a descendant was recently clicked.
+ //
+ // Call focus.watch("curNode", callback) to track the current focused DOMNode,
+ // or focus.watch("activeStack", callback) to track the currently focused stack of widgets.
+ //
+ // Call focus.on("widget-blur", func) or focus.on("widget-focus", ...) to monitor when
+ // when widgets become active/inactive
+ //
+ // Finally, focus(node) will focus a node, suppressing errors if the node doesn't exist.
+
+ // curNode: DomNode
+ // Currently focused item on screen
+ curNode: null,
+
+ // activeStack: dijit._Widget[]
+ // List of currently active widgets (focused widget and it's ancestors)
+ activeStack: [],
+
+ registerIframe: function(iframe){
+ // summary:
+ // Registers listeners on the specified iframe so that any click
+ // or focus event on that iframe (or anything in it) is reported
+ // as a focus/click event on the <iframe> itself.
+ // description:
+ // Currently only used by editor.
+ // returns:
+ // Handle with remove() method to deregister.
+ },
+
+ registerWin: function(targetWindow, effectiveNode){
+ // summary:
+ // Registers listeners on the specified window (either the main
+ // window or an iframe's window) to detect when the user has clicked somewhere
+ // or focused somewhere.
+ // description:
+ // Users should call registerIframe() instead of this method.
+ // targetWindow: Window?
+ // If specified this is the window associated with the iframe,
+ // i.e. iframe.contentWindow.
+ // effectiveNode: DOMNode?
+ // If specified, report any focus events inside targetWindow as
+ // an event on effectiveNode, rather than on evt.target.
+ // returns:
+ // Handle with remove() method to deregister.
+ }
+ };
+=====*/
+
+ var FocusManager = declare([Stateful, Evented], {
+ // curNode: DomNode
+ // Currently focused item on screen
+ curNode: null,
+
+ // activeStack: dijit._Widget[]
+ // List of currently active widgets (focused widget and it's ancestors)
+ activeStack: [],
+
+ constructor: function(){
+ // Don't leave curNode/prevNode pointing to bogus elements
+ var check = lang.hitch(this, function(node){
+ if(dom.isDescendant(this.curNode, node)){
+ this.set("curNode", null);
+ }
+ if(dom.isDescendant(this.prevNode, node)){
+ this.set("prevNode", null);
+ }
+ });
+ aspect.before(domConstruct, "empty", check);
+ aspect.before(domConstruct, "destroy", check);
+ },
+
+ registerIframe: function(/*DomNode*/ iframe){
+ // summary:
+ // Registers listeners on the specified iframe so that any click
+ // or focus event on that iframe (or anything in it) is reported
+ // as a focus/click event on the <iframe> itself.
+ // description:
+ // Currently only used by editor.
+ // returns:
+ // Handle with remove() method to deregister.
+ return this.registerWin(iframe.contentWindow, iframe);
+ },
+
+ registerWin: function(/*Window?*/targetWindow, /*DomNode?*/ effectiveNode){
+ // summary:
+ // Registers listeners on the specified window (either the main
+ // window or an iframe's window) to detect when the user has clicked somewhere
+ // or focused somewhere.
+ // description:
+ // Users should call registerIframe() instead of this method.
+ // targetWindow:
+ // If specified this is the window associated with the iframe,
+ // i.e. iframe.contentWindow.
+ // effectiveNode:
+ // If specified, report any focus events inside targetWindow as
+ // an event on effectiveNode, rather than on evt.target.
+ // returns:
+ // Handle with remove() method to deregister.
+
+ // TODO: make this function private in 2.0; Editor/users should call registerIframe(),
+
+ var _this = this;
+ var mousedownListener = function(evt){
+ _this._justMouseDowned = true;
+ setTimeout(function(){ _this._justMouseDowned = false; }, 0);
+
+ // workaround weird IE bug where the click is on an orphaned node
+ // (first time clicking a Select/DropDownButton inside a TooltipDialog)
+ if(has("ie") && evt && evt.srcElement && evt.srcElement.parentNode == null){
+ return;
+ }
+
+ _this._onTouchNode(effectiveNode || evt.target || evt.srcElement, "mouse");
+ };
+
+ // Listen for blur and focus events on targetWindow's document.
+ // IIRC, I'm using attachEvent() rather than dojo.connect() because focus/blur events don't bubble
+ // through dojo.connect(), and also maybe to catch the focus events early, before onfocus handlers
+ // fire.
+ // Connect to <html> (rather than document) on IE to avoid memory leaks, but document on other browsers because
+ // (at least for FF) the focus event doesn't fire on <html> or <body>.
+ var doc = has("ie") ? targetWindow.document.documentElement : targetWindow.document;
+ if(doc){
+ if(has("ie")){
+ targetWindow.document.body.attachEvent('onmousedown', mousedownListener);
+ var activateListener = function(evt){
+ // IE reports that nodes like <body> have gotten focus, even though they have tabIndex=-1,
+ // ignore those events
+ var tag = evt.srcElement.tagName.toLowerCase();
+ if(tag == "#document" || tag == "body"){ return; }
+
+ // Previous code called _onTouchNode() for any activate event on a non-focusable node. Can
+ // probably just ignore such an event as it will be handled by onmousedown handler above, but
+ // leaving the code for now.
+ if(a11y.isTabNavigable(evt.srcElement)){
+ _this._onFocusNode(effectiveNode || evt.srcElement);
+ }else{
+ _this._onTouchNode(effectiveNode || evt.srcElement);
+ }
+ };
+ doc.attachEvent('onactivate', activateListener);
+ var deactivateListener = function(evt){
+ _this._onBlurNode(effectiveNode || evt.srcElement);
+ };
+ doc.attachEvent('ondeactivate', deactivateListener);
+
+ return {
+ remove: function(){
+ targetWindow.document.detachEvent('onmousedown', mousedownListener);
+ doc.detachEvent('onactivate', activateListener);
+ doc.detachEvent('ondeactivate', deactivateListener);
+ doc = null; // prevent memory leak (apparent circular reference via closure)
+ }
+ };
+ }else{
+ doc.body.addEventListener('mousedown', mousedownListener, true);
+ doc.body.addEventListener('touchstart', mousedownListener, true);
+ var focusListener = function(evt){
+ _this._onFocusNode(effectiveNode || evt.target);
+ };
+ doc.addEventListener('focus', focusListener, true);
+ var blurListener = function(evt){
+ _this._onBlurNode(effectiveNode || evt.target);
+ };
+ doc.addEventListener('blur', blurListener, true);
+
+ return {
+ remove: function(){
+ doc.body.removeEventListener('mousedown', mousedownListener, true);
+ doc.body.removeEventListener('touchstart', mousedownListener, true);
+ doc.removeEventListener('focus', focusListener, true);
+ doc.removeEventListener('blur', blurListener, true);
+ doc = null; // prevent memory leak (apparent circular reference via closure)
+ }
+ };
+ }
+ }
+ },
+
+ _onBlurNode: function(/*DomNode*/ /*===== node =====*/){
+ // summary:
+ // Called when focus leaves a node.
+ // Usually ignored, _unless_ it *isn't* followed by touching another node,
+ // which indicates that we tabbed off the last field on the page,
+ // in which case every widget is marked inactive
+ this.set("prevNode", this.curNode);
+ this.set("curNode", null);
+
+ if(this._justMouseDowned){
+ // the mouse down caused a new widget to be marked as active; this blur event
+ // is coming late, so ignore it.
+ return;
+ }
+
+ // if the blur event isn't followed by a focus event then mark all widgets as inactive.
+ if(this._clearActiveWidgetsTimer){
+ clearTimeout(this._clearActiveWidgetsTimer);
+ }
+ this._clearActiveWidgetsTimer = setTimeout(lang.hitch(this, function(){
+ delete this._clearActiveWidgetsTimer;
+ this._setStack([]);
+ this.prevNode = null;
+ }), 100);
+ },
+
+ _onTouchNode: function(/*DomNode*/ node, /*String*/ by){
+ // summary:
+ // Callback when node is focused or mouse-downed
+ // node:
+ // The node that was touched.
+ // by:
+ // "mouse" if the focus/touch was caused by a mouse down event
+
+ // ignore the recent blurNode event
+ if(this._clearActiveWidgetsTimer){
+ clearTimeout(this._clearActiveWidgetsTimer);
+ delete this._clearActiveWidgetsTimer;
+ }
+
+ // compute stack of active widgets (ex: ComboButton --> Menu --> MenuItem)
+ var newStack=[];
+ try{
+ while(node){
+ var popupParent = domAttr.get(node, "dijitPopupParent");
+ if(popupParent){
+ node=registry.byId(popupParent).domNode;
+ }else if(node.tagName && node.tagName.toLowerCase() == "body"){
+ // is this the root of the document or just the root of an iframe?
+ if(node === win.body()){
+ // node is the root of the main document
+ break;
+ }
+ // otherwise, find the iframe this node refers to (can't access it via parentNode,
+ // need to do this trick instead). window.frameElement is supported in IE/FF/Webkit
+ node=winUtils.get(node.ownerDocument).frameElement;
+ }else{
+ // if this node is the root node of a widget, then add widget id to stack,
+ // except ignore clicks on disabled widgets (actually focusing a disabled widget still works,
+ // to support MenuItem)
+ var id = node.getAttribute && node.getAttribute("widgetId"),
+ widget = id && registry.byId(id);
+ if(widget && !(by == "mouse" && widget.get("disabled"))){
+ newStack.unshift(id);
+ }
+ node=node.parentNode;
+ }
+ }
+ }catch(e){ /* squelch */ }
+
+ this._setStack(newStack, by);
+ },
+
+ _onFocusNode: function(/*DomNode*/ node){
+ // summary:
+ // Callback when node is focused
+
+ if(!node){
+ return;
+ }
+
+ if(node.nodeType == 9){
+ // Ignore focus events on the document itself. This is here so that
+ // (for example) clicking the up/down arrows of a spinner
+ // (which don't get focus) won't cause that widget to blur. (FF issue)
+ return;
+ }
+
+ this._onTouchNode(node);
+
+ if(node == this.curNode){ return; }
+ this.set("curNode", node);
+ },
+
+ _setStack: function(/*String[]*/ newStack, /*String*/ by){
+ // summary:
+ // The stack of active widgets has changed. Send out appropriate events and records new stack.
+ // newStack:
+ // array of widget id's, starting from the top (outermost) widget
+ // by:
+ // "mouse" if the focus/touch was caused by a mouse down event
+
+ var oldStack = this.activeStack;
+ this.set("activeStack", newStack);
+
+ // compare old stack to new stack to see how many elements they have in common
+ for(var nCommon=0; nCommon<Math.min(oldStack.length, newStack.length); nCommon++){
+ if(oldStack[nCommon] != newStack[nCommon]){
+ break;
+ }
+ }
+
+ var widget;
+ // for all elements that have gone out of focus, set focused=false
+ for(var i=oldStack.length-1; i>=nCommon; i--){
+ widget = registry.byId(oldStack[i]);
+ if(widget){
+ widget._hasBeenBlurred = true; // TODO: used by form widgets, should be moved there
+ widget.set("focused", false);
+ if(widget._focusManager == this){
+ widget._onBlur(by);
+ }
+ this.emit("widget-blur", widget, by);
+ }
+ }
+
+ // for all element that have come into focus, set focused=true
+ for(i=nCommon; i<newStack.length; i++){
+ widget = registry.byId(newStack[i]);
+ if(widget){
+ widget.set("focused", true);
+ if(widget._focusManager == this){
+ widget._onFocus(by);
+ }
+ this.emit("widget-focus", widget, by);
+ }
+ }
+ },
+
+ focus: function(node){
+ // summary:
+ // Focus the specified node, suppressing errors if they occur
+ if(node){
+ try{ node.focus(); }catch(e){/*quiet*/}
+ }
+ }
+ });
+
+ var singleton = new FocusManager();
+
+ // register top window and all the iframes it contains
+ ready(function(){
+ var handle = singleton.registerWin(win.doc.parentWindow || win.doc.defaultView);
+ if(has("ie")){
+ unload.addOnWindowUnload(function(){
+ handle.remove();
+ handle = null;
+ })
+ }
+ });
+
+ // Setup dijit.focus as a pointer to the singleton but also (for backwards compatibility)
+ // as a function to set focus.
+ dijit.focus = function(node){
+ singleton.focus(node); // indirection here allows dijit/_base/focus.js to override behavior
+ };
+ for(var attr in singleton){
+ if(!/^_/.test(attr)){
+ dijit.focus[attr] = typeof singleton[attr] == "function" ? lang.hitch(singleton, attr) : singleton[attr];
+ }
+ }
+ singleton.watch(function(attr, oldVal, newVal){
+ dijit.focus[attr] = newVal;
+ });
+
+ return singleton;
+});
+
+},
+'dojox/grid/util':function(){
+define("dojox/grid/util", [
+ "../main",
+ "dojo/_base/lang",
+ "dojo/dom"
+], function(dojox, lang, dom){
+
+// summary: grid utility library
+ var dgu = lang.getObject("grid.util", true, dojox);
+
+ dgu.na = '...';
+ dgu.rowIndexTag = "gridRowIndex";
+ dgu.gridViewTag = "gridView";
+
+
+ dgu.fire = function(ob, ev, args){
+ var fn = ob && ev && ob[ev];
+ return fn && (args ? fn.apply(ob, args) : ob[ev]());
+ };
+
+ dgu.setStyleHeightPx = function(inElement, inHeight){
+ if(inHeight >= 0){
+ var s = inElement.style;
+ var v = inHeight + 'px';
+ if(inElement && s['height'] != v){
+ s['height'] = v;
+ }
+ }
+ };
+
+ dgu.mouseEvents = [ 'mouseover', 'mouseout', /*'mousemove',*/ 'mousedown', 'mouseup', 'click', 'dblclick', 'contextmenu' ];
+
+ dgu.keyEvents = [ 'keyup', 'keydown', 'keypress' ];
+
+ dgu.funnelEvents = function(inNode, inObject, inMethod, inEvents){
+ var evts = (inEvents ? inEvents : dgu.mouseEvents.concat(dgu.keyEvents));
+ for (var i=0, l=evts.length; i<l; i++){
+ inObject.connect(inNode, 'on' + evts[i], inMethod);
+ }
+ };
+
+ dgu.removeNode = function(inNode){
+ inNode = dom.byId(inNode);
+ inNode && inNode.parentNode && inNode.parentNode.removeChild(inNode);
+ return inNode;
+ };
+
+ dgu.arrayCompare = function(inA, inB){
+ for(var i=0,l=inA.length; i<l; i++){
+ if(inA[i] != inB[i]){return false;}
+ }
+ return (inA.length == inB.length);
+ };
+
+ dgu.arrayInsert = function(inArray, inIndex, inValue){
+ if(inArray.length <= inIndex){
+ inArray[inIndex] = inValue;
+ }else{
+ inArray.splice(inIndex, 0, inValue);
+ }
+ };
+
+ dgu.arrayRemove = function(inArray, inIndex){
+ inArray.splice(inIndex, 1);
+ };
+
+ dgu.arraySwap = function(inArray, inI, inJ){
+ var cache = inArray[inI];
+ inArray[inI] = inArray[inJ];
+ inArray[inJ] = cache;
+ };
+
+ return dojox.grid.util;
+
+});
+},
+'url:dijit/templates/MenuItem.html':"<tr class=\"dijitReset dijitMenuItem\" data-dojo-attach-point=\"focusNode\" role=\"menuitem\" tabIndex=\"-1\"\n\t\tdata-dojo-attach-event=\"onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick\">\n\t<td class=\"dijitReset dijitMenuItemIconCell\" role=\"presentation\">\n\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitIcon dijitMenuItemIcon\" data-dojo-attach-point=\"iconNode\"/>\n\t</td>\n\t<td class=\"dijitReset dijitMenuItemLabel\" colspan=\"2\" data-dojo-attach-point=\"containerNode\"></td>\n\t<td class=\"dijitReset dijitMenuItemAccelKey\" style=\"display: none\" data-dojo-attach-point=\"accelKeyNode\"></td>\n\t<td class=\"dijitReset dijitMenuArrowCell\" role=\"presentation\">\n\t\t<div data-dojo-attach-point=\"arrowWrapper\" style=\"visibility: hidden\">\n\t\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitMenuExpand\"/>\n\t\t\t<span class=\"dijitMenuExpandA11y\">+</span>\n\t\t</div>\n\t</td>\n</tr>\n",
+'dijit/main':function(){
+define("dijit/main", [
+ "dojo/_base/kernel"
+], function(dojo){
+ // module:
+ // dijit
+ // summary:
+ // The dijit package main module
+
+ return dojo.dijit;
+});
+
+},
+'dojo/date/stamp':function(){
+define(["../_base/kernel", "../_base/lang", "../_base/array"], function(dojo, lang, array) {
+ // module:
+ // dojo/date/stamp
+ // summary:
+ // TODOC
+
+lang.getObject("date.stamp", true, dojo);
+
+// Methods to convert dates to or from a wire (string) format using well-known conventions
+
+dojo.date.stamp.fromISOString = function(/*String*/formattedString, /*Number?*/defaultTime){
+ // summary:
+ // Returns a Date object given a string formatted according to a subset of the ISO-8601 standard.
+ //
+ // description:
+ // Accepts a string formatted according to a profile of ISO8601 as defined by
+ // [RFC3339](http://www.ietf.org/rfc/rfc3339.txt), except that partial input is allowed.
+ // Can also process dates as specified [by the W3C](http://www.w3.org/TR/NOTE-datetime)
+ // The following combinations are valid:
+ //
+ // * dates only
+ // | * yyyy
+ // | * yyyy-MM
+ // | * yyyy-MM-dd
+ // * times only, with an optional time zone appended
+ // | * THH:mm
+ // | * THH:mm:ss
+ // | * THH:mm:ss.SSS
+ // * and "datetimes" which could be any combination of the above
+ //
+ // timezones may be specified as Z (for UTC) or +/- followed by a time expression HH:mm
+ // Assumes the local time zone if not specified. Does not validate. Improperly formatted
+ // input may return null. Arguments which are out of bounds will be handled
+ // by the Date constructor (e.g. January 32nd typically gets resolved to February 1st)
+ // Only years between 100 and 9999 are supported.
+ //
+ // formattedString:
+ // A string such as 2005-06-30T08:05:00-07:00 or 2005-06-30 or T08:05:00
+ //
+ // defaultTime:
+ // Used for defaults for fields omitted in the formattedString.
+ // Uses 1970-01-01T00:00:00.0Z by default.
+
+ if(!dojo.date.stamp._isoRegExp){
+ dojo.date.stamp._isoRegExp =
+//TODO: could be more restrictive and check for 00-59, etc.
+ /^(?:(\d{4})(?:-(\d{2})(?:-(\d{2}))?)?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(.\d+)?)?((?:[+-](\d{2}):(\d{2}))|Z)?)?$/;
+ }
+
+ var match = dojo.date.stamp._isoRegExp.exec(formattedString),
+ result = null;
+
+ if(match){
+ match.shift();
+ if(match[1]){match[1]--;} // Javascript Date months are 0-based
+ if(match[6]){match[6] *= 1000;} // Javascript Date expects fractional seconds as milliseconds
+
+ if(defaultTime){
+ // mix in defaultTime. Relatively expensive, so use || operators for the fast path of defaultTime === 0
+ defaultTime = new Date(defaultTime);
+ array.forEach(array.map(["FullYear", "Month", "Date", "Hours", "Minutes", "Seconds", "Milliseconds"], function(prop){
+ return defaultTime["get" + prop]();
+ }), function(value, index){
+ match[index] = match[index] || value;
+ });
+ }
+ result = new Date(match[0]||1970, match[1]||0, match[2]||1, match[3]||0, match[4]||0, match[5]||0, match[6]||0); //TODO: UTC defaults
+ if(match[0] < 100){
+ result.setFullYear(match[0] || 1970);
+ }
+
+ var offset = 0,
+ zoneSign = match[7] && match[7].charAt(0);
+ if(zoneSign != 'Z'){
+ offset = ((match[8] || 0) * 60) + (Number(match[9]) || 0);
+ if(zoneSign != '-'){ offset *= -1; }
+ }
+ if(zoneSign){
+ offset -= result.getTimezoneOffset();
+ }
+ if(offset){
+ result.setTime(result.getTime() + offset * 60000);
+ }
+ }
+
+ return result; // Date or null
+};
+
+/*=====
+ dojo.date.stamp.__Options = function(){
+ // selector: String
+ // "date" or "time" for partial formatting of the Date object.
+ // Both date and time will be formatted by default.
+ // zulu: Boolean
+ // if true, UTC/GMT is used for a timezone
+ // milliseconds: Boolean
+ // if true, output milliseconds
+ this.selector = selector;
+ this.zulu = zulu;
+ this.milliseconds = milliseconds;
+ }
+=====*/
+
+dojo.date.stamp.toISOString = function(/*Date*/dateObject, /*dojo.date.stamp.__Options?*/options){
+ // summary:
+ // Format a Date object as a string according a subset of the ISO-8601 standard
+ //
+ // description:
+ // When options.selector is omitted, output follows [RFC3339](http://www.ietf.org/rfc/rfc3339.txt)
+ // The local time zone is included as an offset from GMT, except when selector=='time' (time without a date)
+ // Does not check bounds. Only years between 100 and 9999 are supported.
+ //
+ // dateObject:
+ // A Date object
+
+ var _ = function(n){ return (n < 10) ? "0" + n : n; };
+ options = options || {};
+ var formattedDate = [],
+ getter = options.zulu ? "getUTC" : "get",
+ date = "";
+ if(options.selector != "time"){
+ var year = dateObject[getter+"FullYear"]();
+ date = ["0000".substr((year+"").length)+year, _(dateObject[getter+"Month"]()+1), _(dateObject[getter+"Date"]())].join('-');
+ }
+ formattedDate.push(date);
+ if(options.selector != "date"){
+ var time = [_(dateObject[getter+"Hours"]()), _(dateObject[getter+"Minutes"]()), _(dateObject[getter+"Seconds"]())].join(':');
+ var millis = dateObject[getter+"Milliseconds"]();
+ if(options.milliseconds){
+ time += "."+ (millis < 100 ? "0" : "") + _(millis);
+ }
+ if(options.zulu){
+ time += "Z";
+ }else if(options.selector != "time"){
+ var timezoneOffset = dateObject.getTimezoneOffset();
+ var absOffset = Math.abs(timezoneOffset);
+ time += (timezoneOffset > 0 ? "-" : "+") +
+ _(Math.floor(absOffset/60)) + ":" + _(absOffset%60);
+ }
+ formattedDate.push(time);
+ }
+ return formattedDate.join('T'); // String
+};
+
+return dojo.date.stamp;
+});
+
+},
+'url:dojox/grid/resources/View.html':"<div class=\"dojoxGridView\" role=\"presentation\">\n\t<div class=\"dojoxGridHeader\" dojoAttachPoint=\"headerNode\" role=\"presentation\">\n\t\t<div dojoAttachPoint=\"headerNodeContainer\" style=\"width:9000em\" role=\"presentation\">\n\t\t\t<div dojoAttachPoint=\"headerContentNode\" role=\"row\"></div>\n\t\t</div>\n\t</div>\n\t<input type=\"checkbox\" class=\"dojoxGridHiddenFocus\" dojoAttachPoint=\"hiddenFocusNode\" role=\"presentation\" />\n\t<input type=\"checkbox\" class=\"dojoxGridHiddenFocus\" role=\"presentation\" />\n\t<div class=\"dojoxGridScrollbox\" dojoAttachPoint=\"scrollboxNode\" role=\"presentation\">\n\t\t<div class=\"dojoxGridContent\" dojoAttachPoint=\"contentNode\" hidefocus=\"hidefocus\" role=\"presentation\"></div>\n\t</div>\n</div>\n",
+'dojox/grid/_FocusManager':function(){
+define("dojox/grid/_FocusManager", [
+ "dojo/_base/array",
+ "dojo/_base/lang",
+ "dojo/_base/declare",
+ "dojo/_base/connect",
+ "dojo/_base/event",
+ "dojo/_base/sniff",
+ "dojo/query",
+ "./util",
+ "dojo/_base/html"
+], function(array, lang, declare, connect, event, has, query, util, html){
+
+// focus management
+return declare("dojox.grid._FocusManager", null, {
+ // summary:
+ // Controls grid cell focus. Owned by grid and used internally for focusing.
+ // Note: grid cell actually receives keyboard input only when cell is being edited.
+ constructor: function(inGrid){
+ this.grid = inGrid;
+ this.cell = null;
+ this.rowIndex = -1;
+ this._connects = [];
+ this._headerConnects = [];
+ this.headerMenu = this.grid.headerMenu;
+ this._connects.push(connect.connect(this.grid.domNode, "onfocus", this, "doFocus"));
+ this._connects.push(connect.connect(this.grid.domNode, "onblur", this, "doBlur"));
+ this._connects.push(connect.connect(this.grid.domNode, "mousedown", this, "_mouseDown"));
+ this._connects.push(connect.connect(this.grid.domNode, "mouseup", this, "_mouseUp"));
+ this._connects.push(connect.connect(this.grid.domNode, "oncontextmenu", this, "doContextMenu"));
+ this._connects.push(connect.connect(this.grid.lastFocusNode, "onfocus", this, "doLastNodeFocus"));
+ this._connects.push(connect.connect(this.grid.lastFocusNode, "onblur", this, "doLastNodeBlur"));
+ this._connects.push(connect.connect(this.grid,"_onFetchComplete", this, "_delayedCellFocus"));
+ this._connects.push(connect.connect(this.grid,"postrender", this, "_delayedHeaderFocus"));
+ },
+ destroy: function(){
+ array.forEach(this._connects, connect.disconnect);
+ array.forEach(this._headerConnects, connect.disconnect);
+ delete this.grid;
+ delete this.cell;
+ },
+ _colHeadNode: null,
+ _colHeadFocusIdx: null,
+ _contextMenuBindNode: null,
+ tabbingOut: false,
+ focusClass: "dojoxGridCellFocus",
+ focusView: null,
+ initFocusView: function(){
+ this.focusView = this.grid.views.getFirstScrollingView() || this.focusView || this.grid.views.views[0];
+ this._initColumnHeaders();
+ },
+ isFocusCell: function(inCell, inRowIndex){
+ // summary:
+ // states if the given cell is focused
+ // inCell: object
+ // grid cell object
+ // inRowIndex: int
+ // grid row index
+ // returns:
+ // true of the given grid cell is focused
+ return (this.cell == inCell) && (this.rowIndex == inRowIndex);
+ },
+ isLastFocusCell: function(){
+ if(this.cell){
+ return (this.rowIndex == this.grid.rowCount-1) && (this.cell.index == this.grid.layout.cellCount-1);
+ }
+ return false;
+ },
+ isFirstFocusCell: function(){
+ if(this.cell){
+ return (this.rowIndex === 0) && (this.cell.index === 0);
+ }
+ return false;
+ },
+ isNoFocusCell: function(){
+ return (this.rowIndex < 0) || !this.cell;
+ },
+ isNavHeader: function(){
+ // summary:
+ // states whether currently navigating among column headers.
+ // returns:
+ // true if focus is on a column header; false otherwise.
+ return (!!this._colHeadNode);
+ },
+ getHeaderIndex: function(){
+ // summary:
+ // if one of the column headers currently has focus, return its index.
+ // returns:
+ // index of the focused column header, or -1 if none have focus.
+ if(this._colHeadNode){
+ return array.indexOf(this._findHeaderCells(), this._colHeadNode);
+ }else{
+ return -1;
+ }
+ },
+ _focusifyCellNode: function(inBork){
+ var n = this.cell && this.cell.getNode(this.rowIndex);
+ if(n){
+ html.toggleClass(n, this.focusClass, inBork);
+ if(inBork){
+ var sl = this.scrollIntoView();
+ try{
+ if(!this.grid.edit.isEditing()){
+ util.fire(n, "focus");
+ if(sl){ this.cell.view.scrollboxNode.scrollLeft = sl; }
+ }
+ }catch(e){}
+ }
+ }
+ },
+ _delayedCellFocus: function(){
+ if(this.isNavHeader()||!this.grid.focused){
+ return;
+ }
+ var n = this.cell && this.cell.getNode(this.rowIndex);
+ if(n){
+ try{
+ if(!this.grid.edit.isEditing()){
+ html.toggleClass(n, this.focusClass, true);
+ if(this._colHeadNode){
+ this.blurHeader();
+ }
+ util.fire(n, "focus");
+ }
+ }
+ catch(e){}
+ }
+ },
+ _delayedHeaderFocus: function(){
+ if(this.isNavHeader()){
+ this.focusHeader();
+ this.grid.domNode.focus();
+ }
+ },
+ _initColumnHeaders: function(){
+ array.forEach(this._headerConnects, connect.disconnect);
+ this._headerConnects = [];
+ var headers = this._findHeaderCells();
+ for(var i = 0; i < headers.length; i++){
+ this._headerConnects.push(connect.connect(headers[i], "onfocus", this, "doColHeaderFocus"));
+ this._headerConnects.push(connect.connect(headers[i], "onblur", this, "doColHeaderBlur"));
+ }
+ },
+ _findHeaderCells: function(){
+ // This should be a one liner:
+ // query("th[tabindex=-1]", this.grid.viewsHeaderNode);
+ // But there is a bug in query() for IE -- see trac #7037.
+ var allHeads = query("th", this.grid.viewsHeaderNode);
+ var headers = [];
+ for (var i = 0; i < allHeads.length; i++){
+ var aHead = allHeads[i];
+ var hasTabIdx = html.hasAttr(aHead, "tabIndex");
+ var tabindex = html.attr(aHead, "tabIndex");
+ if (hasTabIdx && tabindex < 0) {
+ headers.push(aHead);
+ }
+ }
+ return headers;
+ },
+ _setActiveColHeader: function(/*Node*/colHeaderNode, /*Integer*/colFocusIdx, /*Integer*/ prevColFocusIdx){
+ //console.log("setActiveColHeader() - colHeaderNode:colFocusIdx:prevColFocusIdx = " + colHeaderNode + ":" + colFocusIdx + ":" + prevColFocusIdx);
+ this.grid.domNode.setAttribute("aria-activedescendant",colHeaderNode.id);
+ if (prevColFocusIdx != null && prevColFocusIdx >= 0 && prevColFocusIdx != colFocusIdx){
+ html.toggleClass(this._findHeaderCells()[prevColFocusIdx],this.focusClass,false);
+ }
+ html.toggleClass(colHeaderNode,this.focusClass, true);
+ this._colHeadNode = colHeaderNode;
+ this._colHeadFocusIdx = colFocusIdx;
+ this._scrollHeader(this._colHeadFocusIdx);
+ },
+ scrollIntoView: function(){
+ var info = (this.cell ? this._scrollInfo(this.cell) : null);
+ if(!info || !info.s){
+ return null;
+ }
+ var rt = this.grid.scroller.findScrollTop(this.rowIndex);
+ // place cell within horizontal view
+ if(info.n && info.sr){
+ if(info.n.offsetLeft + info.n.offsetWidth > info.sr.l + info.sr.w){
+ info.s.scrollLeft = info.n.offsetLeft + info.n.offsetWidth - info.sr.w;
+ }else if(info.n.offsetLeft < info.sr.l){
+ info.s.scrollLeft = info.n.offsetLeft;
+ }
+ }
+ // place cell within vertical view
+ if(info.r && info.sr){
+ if(rt + info.r.offsetHeight > info.sr.t + info.sr.h){
+ this.grid.setScrollTop(rt + info.r.offsetHeight - info.sr.h);
+ }else if(rt < info.sr.t){
+ this.grid.setScrollTop(rt);
+ }
+ }
+
+ return info.s.scrollLeft;
+ },
+ _scrollInfo: function(cell, domNode){
+ if(cell){
+ var cl = cell,
+ sbn = cl.view.scrollboxNode,
+ sbnr = {
+ w: sbn.clientWidth,
+ l: sbn.scrollLeft,
+ t: sbn.scrollTop,
+ h: sbn.clientHeight
+ },
+ rn = cl.view.getRowNode(this.rowIndex);
+ return {
+ c: cl,
+ s: sbn,
+ sr: sbnr,
+ n: (domNode ? domNode : cell.getNode(this.rowIndex)),
+ r: rn
+ };
+ }
+ return null;
+ },
+ _scrollHeader: function(currentIdx){
+ var info = null;
+ if(this._colHeadNode){
+ var cell = this.grid.getCell(currentIdx);
+ if(!cell){ return; }
+ info = this._scrollInfo(cell, cell.getNode(0));
+ }
+ if(info && info.s && info.sr && info.n){
+ // scroll horizontally as needed.
+ var scroll = info.sr.l + info.sr.w;
+ if(info.n.offsetLeft + info.n.offsetWidth > scroll){
+ info.s.scrollLeft = info.n.offsetLeft + info.n.offsetWidth - info.sr.w;
+ }else if(info.n.offsetLeft < info.sr.l){
+ info.s.scrollLeft = info.n.offsetLeft;
+ }else if(has("ie") <= 7 && cell && cell.view.headerNode){
+ // Trac 7158: scroll dojoxGridHeader for IE7 and lower
+ cell.view.headerNode.scrollLeft = info.s.scrollLeft;
+ }
+ }
+ },
+ _isHeaderHidden: function(){
+ // summary:
+ // determine if the grid headers are hidden
+ // relies on documented technique of setting .dojoxGridHeader { display:none; }
+ // returns: Boolean
+ // true if headers are hidden
+ // false if headers are not hidden
+
+ var curView = this.focusView;
+ if (!curView){
+ // find one so we can determine if headers are hidden
+ // there is no focusView after adding items to empty grid (test_data_grid_empty.html)
+ for (var i = 0, cView; (cView = this.grid.views.views[i]); i++) {
+ if(cView.headerNode ){
+ curView=cView;
+ break;
+ }
+ }
+ }
+ return (curView && html.getComputedStyle(curView.headerNode).display == "none");
+ },
+ colSizeAdjust: function (e, colIdx, delta){ // adjust the column specified by colIdx by the specified delta px
+ var headers = this._findHeaderCells();
+ var view = this.focusView;
+ if (!view) {
+ for (var i = 0, cView; (cView = this.grid.views.views[i]); i++) {
+ // find first view with a tableMap in order to work with empty grid
+ if(cView.header.tableMap.map ){
+ view=cView;
+ break;
+ }
+ }
+ }
+ var curHeader = headers[colIdx];
+ if (!view || (colIdx == headers.length-1 && colIdx === 0)){
+ return; // can't adjust single col. grid
+ }
+ view.content.baseDecorateEvent(e);
+ // need to adjust event with header cell info since focus is no longer on header cell
+ e.cellNode = curHeader; //this.findCellTarget(e.target, e.rowNode);
+ e.cellIndex = view.content.getCellNodeIndex(e.cellNode);
+ e.cell = (e.cellIndex >= 0 ? this.grid.getCell(e.cellIndex) : null);
+ if (view.header.canResize(e)){
+ var deltaObj = {
+ l: delta
+ };
+ var drag = view.header.colResizeSetup(e,false);
+ view.header.doResizeColumn(drag, null, deltaObj);
+ view.update();
+ }
+ },
+ styleRow: function(inRow){
+ return;
+ },
+ setFocusIndex: function(inRowIndex, inCellIndex){
+ // summary:
+ // focuses the given grid cell
+ // inRowIndex: int
+ // grid row index
+ // inCellIndex: int
+ // grid cell index
+ this.setFocusCell(this.grid.getCell(inCellIndex), inRowIndex);
+ },
+ setFocusCell: function(inCell, inRowIndex){
+ // summary:
+ // focuses the given grid cell
+ // inCell: object
+ // grid cell object
+ // inRowIndex: int
+ // grid row index
+ if(inCell && !this.isFocusCell(inCell, inRowIndex)){
+ this.tabbingOut = false;
+ if (this._colHeadNode){
+ this.blurHeader();
+ }
+ this._colHeadNode = this._colHeadFocusIdx = null;
+ this.focusGridView();
+ this._focusifyCellNode(false);
+ this.cell = inCell;
+ this.rowIndex = inRowIndex;
+ this._focusifyCellNode(true);
+ }
+ // even if this cell isFocusCell, the document focus may need to be rejiggered
+ // call opera on delay to prevent keypress from altering focus
+ if(has("opera")){
+ setTimeout(lang.hitch(this.grid, 'onCellFocus', this.cell, this.rowIndex), 1);
+ }else{
+ this.grid.onCellFocus(this.cell, this.rowIndex);
+ }
+ },
+ next: function(){
+ // summary:
+ // focus next grid cell
+ if(this.cell){
+ var row=this.rowIndex, col=this.cell.index+1, cc=this.grid.layout.cellCount-1, rc=this.grid.rowCount-1;
+ if(col > cc){
+ col = 0;
+ row++;
+ }
+ if(row > rc){
+ col = cc;
+ row = rc;
+ }
+ if(this.grid.edit.isEditing()){ //when editing, only navigate to editable cells
+ var nextCell = this.grid.getCell(col);
+ if (!this.isLastFocusCell() && (!nextCell.editable ||
+ this.grid.canEdit && !this.grid.canEdit(nextCell, row))){
+ this.cell=nextCell;
+ this.rowIndex=row;
+ this.next();
+ return;
+ }
+ }
+ this.setFocusIndex(row, col);
+ }
+ },
+ previous: function(){
+ // summary:
+ // focus previous grid cell
+ if(this.cell){
+ var row=(this.rowIndex || 0), col=(this.cell.index || 0) - 1;
+ if(col < 0){
+ col = this.grid.layout.cellCount-1;
+ row--;
+ }
+ if(row < 0){
+ row = 0;
+ col = 0;
+ }
+ if(this.grid.edit.isEditing()){ //when editing, only navigate to editable cells
+ var prevCell = this.grid.getCell(col);
+ if (!this.isFirstFocusCell() && !prevCell.editable){
+ this.cell=prevCell;
+ this.rowIndex=row;
+ this.previous();
+ return;
+ }
+ }
+ this.setFocusIndex(row, col);
+ }
+ },
+ move: function(inRowDelta, inColDelta) {
+ // summary:
+ // focus grid cell or simulate focus to column header based on position relative to current focus
+ // inRowDelta: int
+ // vertical distance from current focus
+ // inColDelta: int
+ // horizontal distance from current focus
+
+ var colDir = inColDelta < 0 ? -1 : 1;
+ // Handle column headers.
+ if(this.isNavHeader()){
+ var headers = this._findHeaderCells();
+ var savedIdx = currentIdx = array.indexOf(headers, this._colHeadNode);
+ currentIdx += inColDelta;
+ while(currentIdx >=0 && currentIdx < headers.length && headers[currentIdx].style.display == "none"){
+ // skip over hidden column headers
+ currentIdx += colDir;
+ }
+ if((currentIdx >= 0) && (currentIdx < headers.length)){
+ this._setActiveColHeader(headers[currentIdx],currentIdx, savedIdx);
+ }
+ }else{
+ if(this.cell){
+ // Handle grid proper.
+ var sc = this.grid.scroller,
+ r = this.rowIndex,
+ rc = this.grid.rowCount-1,
+ row = Math.min(rc, Math.max(0, r+inRowDelta));
+ if(inRowDelta){
+ if(inRowDelta>0){
+ if(row > sc.getLastPageRow(sc.page)){
+ //need to load additional data, let scroller do that
+ this.grid.setScrollTop(this.grid.scrollTop+sc.findScrollTop(row)-sc.findScrollTop(r));
+ }
+ }else if(inRowDelta<0){
+ if(row <= sc.getPageRow(sc.page)){
+ //need to load additional data, let scroller do that
+ this.grid.setScrollTop(this.grid.scrollTop-sc.findScrollTop(r)-sc.findScrollTop(row));
+ }
+ }
+ }
+ var cc = this.grid.layout.cellCount-1,
+ i = this.cell.index,
+ col = Math.min(cc, Math.max(0, i+inColDelta));
+ var cell = this.grid.getCell(col);
+ while(col>=0 && col < cc && cell && cell.hidden === true){
+ // skip hidden cells
+ col += colDir;
+ cell = this.grid.getCell(col);
+ }
+ if (!cell || cell.hidden === true){
+ // don't change col if would move to hidden
+ col = i;
+ }
+ //skip hidden row|cell
+ var n = cell.getNode(row);
+ if(!n && inRowDelta){
+ if((row + inRowDelta) >= 0 && (row + inRowDelta) <= rc){
+ this.move(inRowDelta > 0 ? ++inRowDelta : --inRowDelta, inColDelta);
+ }
+ return;
+ }else if((!n || html.style(n, "display") === "none") && inColDelta){
+ if((col + inRowDelta) >= 0 && (col + inRowDelta) <= cc){
+ this.move(inRowDelta, inColDelta > 0 ? ++inColDelta : --inColDelta);
+ }
+ return;
+ }
+ this.setFocusIndex(row, col);
+ if(inRowDelta){
+ this.grid.updateRow(r);
+ }
+ }
+ }
+ },
+ previousKey: function(e){
+ if(this.grid.edit.isEditing()){
+ event.stop(e);
+ this.previous();
+ }else if(!this.isNavHeader() && !this._isHeaderHidden()) {
+ this.grid.domNode.focus(); // will call doFocus and set focus into header.
+ event.stop(e);
+ }else{
+ this.tabOut(this.grid.domNode);
+ if (this._colHeadFocusIdx != null) { // clear grid header focus
+ html.toggleClass(this._findHeaderCells()[this._colHeadFocusIdx], this.focusClass, false);
+ this._colHeadFocusIdx = null;
+ }
+ this._focusifyCellNode(false);
+ }
+ },
+ nextKey: function(e) {
+ var isEmpty = (this.grid.rowCount === 0);
+ if(e.target === this.grid.domNode && this._colHeadFocusIdx == null){
+ this.focusHeader();
+ event.stop(e);
+ }else if(this.isNavHeader()){
+ // if tabbing from col header, then go to grid proper.
+ this.blurHeader();
+ if(!this.findAndFocusGridCell()){
+ this.tabOut(this.grid.lastFocusNode);
+ }
+ this._colHeadNode = this._colHeadFocusIdx= null;
+ }else if(this.grid.edit.isEditing()){
+ event.stop(e);
+ this.next();
+ }else{
+ this.tabOut(this.grid.lastFocusNode);
+ }
+ },
+ tabOut: function(inFocusNode){
+ this.tabbingOut = true;
+ inFocusNode.focus();
+ },
+ focusGridView: function(){
+ util.fire(this.focusView, "focus");
+ },
+ focusGrid: function(inSkipFocusCell){
+ this.focusGridView();
+ this._focusifyCellNode(true);
+ },
+ findAndFocusGridCell: function(){
+ // summary:
+ // find the first focusable grid cell
+ // returns: Boolean
+ // true if focus was set to a cell
+ // false if no cell found to set focus onto
+
+ var didFocus = true;
+ var isEmpty = (this.grid.rowCount === 0); // If grid is empty this.grid.rowCount == 0
+ if (this.isNoFocusCell() && !isEmpty){
+ var cellIdx = 0;
+ var cell = this.grid.getCell(cellIdx);
+ if (cell.hidden) {
+ // if first cell isn't visible, use _colHeadFocusIdx
+ // could also use a while loop to find first visible cell - not sure that is worth it
+ cellIdx = this.isNavHeader() ? this._colHeadFocusIdx : 0;
+ }
+ this.setFocusIndex(0, cellIdx);
+ }
+ else if (this.cell && !isEmpty){
+ if (this.focusView && !this.focusView.rowNodes[this.rowIndex]){
+ // if rowNode for current index is undefined (likely as a result of a sort and because of #7304)
+ // scroll to that row
+ this.grid.scrollToRow(this.rowIndex);
+ }
+ this.focusGrid();
+ }else {
+ didFocus = false;
+ }
+ this._colHeadNode = this._colHeadFocusIdx= null;
+ return didFocus;
+ },
+ focusHeader: function(){
+ var headerNodes = this._findHeaderCells();
+ var saveColHeadFocusIdx = this._colHeadFocusIdx;
+ if (this._isHeaderHidden()){
+ // grid header is hidden, focus a cell
+ this.findAndFocusGridCell();
+ }
+ else if (!this._colHeadFocusIdx) {
+ if (this.isNoFocusCell()) {
+ this._colHeadFocusIdx = 0;
+ }
+ else {
+ this._colHeadFocusIdx = this.cell.index;
+ }
+ }
+ this._colHeadNode = headerNodes[this._colHeadFocusIdx];
+ while(this._colHeadNode && this._colHeadFocusIdx >=0 && this._colHeadFocusIdx < headerNodes.length &&
+ this._colHeadNode.style.display == "none"){
+ // skip over hidden column headers
+ this._colHeadFocusIdx++;
+ this._colHeadNode = headerNodes[this._colHeadFocusIdx];
+ }
+ if(this._colHeadNode && this._colHeadNode.style.display != "none"){
+ // Column header cells know longer receive actual focus. So, for keyboard invocation of
+ // contextMenu to work, the contextMenu must be bound to the grid.domNode rather than the viewsHeaderNode.
+ // unbind the contextmenu from the viewsHeaderNode and to the grid when header cells are active. Reset
+ // the binding back to the viewsHeaderNode when header cells are no longer acive (in blurHeader) #10483
+ if (this.headerMenu && this._contextMenuBindNode != this.grid.domNode){
+ this.headerMenu.unBindDomNode(this.grid.viewsHeaderNode);
+ this.headerMenu.bindDomNode(this.grid.domNode);
+ this._contextMenuBindNode = this.grid.domNode;
+ }
+ this._setActiveColHeader(this._colHeadNode, this._colHeadFocusIdx, saveColHeadFocusIdx);
+ this._scrollHeader(this._colHeadFocusIdx);
+ this._focusifyCellNode(false);
+ }else {
+ // all col head nodes are hidden - focus the grid
+ this.findAndFocusGridCell();
+ }
+ },
+ blurHeader: function(){
+ html.removeClass(this._colHeadNode, this.focusClass);
+ html.removeAttr(this.grid.domNode,"aria-activedescendant");
+ // reset contextMenu onto viewsHeaderNode so right mouse on header will invoke (see focusHeader)
+ if (this.headerMenu && this._contextMenuBindNode == this.grid.domNode) {
+ var viewsHeader = this.grid.viewsHeaderNode;
+ this.headerMenu.unBindDomNode(this.grid.domNode);
+ this.headerMenu.bindDomNode(viewsHeader);
+ this._contextMenuBindNode = viewsHeader;
+ }
+ },
+ doFocus: function(e){
+ // trap focus only for grid dom node
+ if(e && e.target != e.currentTarget){
+ event.stop(e);
+ return;
+ }
+ // don't change focus if clicking on scroller bar
+ if(this._clickFocus){
+ return;
+ }
+ // do not focus for scrolling if grid is about to blur
+ if(!this.tabbingOut){
+ this.focusHeader();
+ }
+ this.tabbingOut = false;
+ event.stop(e);
+ },
+ doBlur: function(e){
+ event.stop(e); // FF2
+ },
+ doContextMenu: function(e){
+ //stop contextMenu event if no header Menu to prevent default/browser contextMenu
+ if (!this.headerMenu){
+ event.stop(e);
+ }
+ },
+ doLastNodeFocus: function(e){
+ if (this.tabbingOut){
+ this._focusifyCellNode(false);
+ }else if(this.grid.rowCount >0){
+ if (this.isNoFocusCell()){
+ this.setFocusIndex(0,0);
+ }
+ this._focusifyCellNode(true);
+ }else {
+ this.focusHeader();
+ }
+ this.tabbingOut = false;
+ event.stop(e); // FF2
+ },
+ doLastNodeBlur: function(e){
+ event.stop(e); // FF2
+ },
+ doColHeaderFocus: function(e){
+ this._setActiveColHeader(e.target,html.attr(e.target, "idx"),this._colHeadFocusIdx);
+ this._scrollHeader(this.getHeaderIndex());
+ event.stop(e);
+ },
+ doColHeaderBlur: function(e){
+ html.toggleClass(e.target, this.focusClass, false);
+ },
+ _mouseDown: function(e){
+ // a flag indicating grid is being focused by clicking
+ this._clickFocus = dojo.some(this.grid.views.views, function(v){
+ return v.scrollboxNode === e.target;
+ });
+ },
+ _mouseUp: function(e){
+ this._clickFocus = false;
+ }
+});
+});
+},
+'dijit/MenuItem':function(){
+require({cache:{
+'url:dijit/templates/MenuItem.html':"<tr class=\"dijitReset dijitMenuItem\" data-dojo-attach-point=\"focusNode\" role=\"menuitem\" tabIndex=\"-1\"\n\t\tdata-dojo-attach-event=\"onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick\">\n\t<td class=\"dijitReset dijitMenuItemIconCell\" role=\"presentation\">\n\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitIcon dijitMenuItemIcon\" data-dojo-attach-point=\"iconNode\"/>\n\t</td>\n\t<td class=\"dijitReset dijitMenuItemLabel\" colspan=\"2\" data-dojo-attach-point=\"containerNode\"></td>\n\t<td class=\"dijitReset dijitMenuItemAccelKey\" style=\"display: none\" data-dojo-attach-point=\"accelKeyNode\"></td>\n\t<td class=\"dijitReset dijitMenuArrowCell\" role=\"presentation\">\n\t\t<div data-dojo-attach-point=\"arrowWrapper\" style=\"visibility: hidden\">\n\t\t\t<img src=\"${_blankGif}\" alt=\"\" class=\"dijitMenuExpand\"/>\n\t\t\t<span class=\"dijitMenuExpandA11y\">+</span>\n\t\t</div>\n\t</td>\n</tr>\n"}});
+define("dijit/MenuItem", [
+ "dojo/_base/declare", // declare
+ "dojo/dom", // dom.setSelectable
+ "dojo/dom-attr", // domAttr.set
+ "dojo/dom-class", // domClass.toggle
+ "dojo/_base/event", // event.stop
+ "dojo/_base/kernel", // kernel.deprecated
+ "dojo/_base/sniff", // has("ie")
+ "./_Widget",
+ "./_TemplatedMixin",
+ "./_Contained",
+ "./_CssStateMixin",
+ "dojo/text!./templates/MenuItem.html"
+], function(declare, dom, domAttr, domClass, event, kernel, has,
+ _Widget, _TemplatedMixin, _Contained, _CssStateMixin, template){
+
+/*=====
+ var _Widget = dijit._Widget;
+ var _TemplatedMixin = dijit._TemplatedMixin;
+ var _Contained = dijit._Contained;
+ var _CssStateMixin = dijit._CssStateMixin;
+=====*/
+
+ // module:
+ // dijit/MenuItem
+ // summary:
+ // A line item in a Menu Widget
+
+
+ return declare("dijit.MenuItem",
+ [_Widget, _TemplatedMixin, _Contained, _CssStateMixin],
+ {
+ // summary:
+ // A line item in a Menu Widget
+
+ // Make 3 columns
+ // icon, label, and expand arrow (BiDi-dependent) indicating sub-menu
+ templateString: template,
+
+ baseClass: "dijitMenuItem",
+
+ // label: String
+ // Menu text
+ label: '',
+ _setLabelAttr: { node: "containerNode", type: "innerHTML" },
+
+ // iconClass: String
+ // Class to apply to DOMNode to make it display an icon.
+ iconClass: "dijitNoIcon",
+ _setIconClassAttr: { node: "iconNode", type: "class" },
+
+ // accelKey: String
+ // Text for the accelerator (shortcut) key combination.
+ // Note that although Menu can display accelerator keys there
+ // is no infrastructure to actually catch and execute these
+ // accelerators.
+ accelKey: "",
+
+ // disabled: Boolean
+ // If true, the menu item is disabled.
+ // If false, the menu item is enabled.
+ disabled: false,
+
+ _fillContent: function(/*DomNode*/ source){
+ // If button label is specified as srcNodeRef.innerHTML rather than
+ // this.params.label, handle it here.
+ if(source && !("label" in this.params)){
+ this.set('label', source.innerHTML);
+ }
+ },
+
+ buildRendering: function(){
+ this.inherited(arguments);
+ var label = this.id+"_text";
+ domAttr.set(this.containerNode, "id", label);
+ if(this.accelKeyNode){
+ domAttr.set(this.accelKeyNode, "id", this.id + "_accel");
+ label += " " + this.id + "_accel";
+ }
+ this.domNode.setAttribute("aria-labelledby", label);
+ dom.setSelectable(this.domNode, false);
+ },
+
+ _onHover: function(){
+ // summary:
+ // Handler when mouse is moved onto menu item
+ // tags:
+ // protected
+ this.getParent().onItemHover(this);
+ },
+
+ _onUnhover: function(){
+ // summary:
+ // Handler when mouse is moved off of menu item,
+ // possibly to a child menu, or maybe to a sibling
+ // menuitem or somewhere else entirely.
+ // tags:
+ // protected
+
+ // if we are unhovering the currently selected item
+ // then unselect it
+ this.getParent().onItemUnhover(this);
+
+ // When menu is hidden (collapsed) due to clicking a MenuItem and having it execute,
+ // FF and IE don't generate an onmouseout event for the MenuItem.
+ // So, help out _CssStateMixin in this case.
+ this._set("hovering", false);
+ },
+
+ _onClick: function(evt){
+ // summary:
+ // Internal handler for click events on MenuItem.
+ // tags:
+ // private
+ this.getParent().onItemClick(this, evt);
+ event.stop(evt);
+ },
+
+ onClick: function(/*Event*/){
+ // summary:
+ // User defined function to handle clicks
+ // tags:
+ // callback
+ },
+
+ focus: function(){
+ // summary:
+ // Focus on this MenuItem
+ try{
+ if(has("ie") == 8){
+ // needed for IE8 which won't scroll TR tags into view on focus yet calling scrollIntoView creates flicker (#10275)
+ this.containerNode.focus();
+ }
+ this.focusNode.focus();
+ }catch(e){
+ // this throws on IE (at least) in some scenarios
+ }
+ },
+
+ _onFocus: function(){
+ // summary:
+ // This is called by the focus manager when focus
+ // goes to this MenuItem or a child menu.
+ // tags:
+ // protected
+ this._setSelected(true);
+ this.getParent()._onItemFocus(this);
+
+ this.inherited(arguments);
+ },
+
+ _setSelected: function(selected){
+ // summary:
+ // Indicate that this node is the currently selected one
+ // tags:
+ // private
+
+ /***
+ * TODO: remove this method and calls to it, when _onBlur() is working for MenuItem.
+ * Currently _onBlur() gets called when focus is moved from the MenuItem to a child menu.
+ * That's not supposed to happen, but the problem is:
+ * In order to allow dijit.popup's getTopPopup() to work,a sub menu's popupParent
+ * points to the parent Menu, bypassing the parent MenuItem... thus the
+ * MenuItem is not in the chain of active widgets and gets a premature call to
+ * _onBlur()
+ */
+
+ domClass.toggle(this.domNode, "dijitMenuItemSelected", selected);
+ },
+
+ setLabel: function(/*String*/ content){
+ // summary:
+ // Deprecated. Use set('label', ...) instead.
+ // tags:
+ // deprecated
+ kernel.deprecated("dijit.MenuItem.setLabel() is deprecated. Use set('label', ...) instead.", "", "2.0");
+ this.set("label", content);
+ },
+
+ setDisabled: function(/*Boolean*/ disabled){
+ // summary:
+ // Deprecated. Use set('disabled', bool) instead.
+ // tags:
+ // deprecated
+ kernel.deprecated("dijit.Menu.setDisabled() is deprecated. Use set('disabled', bool) instead.", "", "2.0");
+ this.set('disabled', disabled);
+ },
+ _setDisabledAttr: function(/*Boolean*/ value){
+ // summary:
+ // Hook for attr('disabled', ...) to work.
+ // Enable or disable this menu item.
+
+ this.focusNode.setAttribute('aria-disabled', value ? 'true' : 'false');
+ this._set("disabled", value);
+ },
+ _setAccelKeyAttr: function(/*String*/ value){
+ // summary:
+ // Hook for attr('accelKey', ...) to work.
+ // Set accelKey on this menu item.
+
+ this.accelKeyNode.style.display=value?"":"none";
+ this.accelKeyNode.innerHTML=value;
+ //have to use colSpan to make it work in IE
+ domAttr.set(this.containerNode,'colSpan',value?"1":"2");
+
+ this._set("accelKey", value);
+ }
+ });
+});
+
+},
+'dijit/_TemplatedMixin':function(){
+define("dijit/_TemplatedMixin", [
+ "dojo/_base/lang", // lang.getObject
+ "dojo/touch",
+ "./_WidgetBase",
+ "dojo/string", // string.substitute string.trim
+ "dojo/cache", // dojo.cache
+ "dojo/_base/array", // array.forEach
+ "dojo/_base/declare", // declare
+ "dojo/dom-construct", // domConstruct.destroy, domConstruct.toDom
+ "dojo/_base/sniff", // has("ie")
+ "dojo/_base/unload", // unload.addOnWindowUnload
+ "dojo/_base/window" // win.doc
+], function(lang, touch, _WidgetBase, string, cache, array, declare, domConstruct, has, unload, win) {
+
+/*=====
+ var _WidgetBase = dijit._WidgetBase;
+=====*/
+
+ // module:
+ // dijit/_TemplatedMixin
+ // summary:
+ // Mixin for widgets that are instantiated from a template
+
+ var _TemplatedMixin = declare("dijit._TemplatedMixin", null, {
+ // summary:
+ // Mixin for widgets that are instantiated from a template
+
+ // templateString: [protected] String
+ // A string that represents the widget template.
+ // Use in conjunction with dojo.cache() to load from a file.
+ templateString: null,
+
+ // templatePath: [protected deprecated] String
+ // Path to template (HTML file) for this widget relative to dojo.baseUrl.
+ // Deprecated: use templateString with require([... "dojo/text!..."], ...) instead
+ templatePath: null,
+
+ // skipNodeCache: [protected] Boolean
+ // If using a cached widget template nodes poses issues for a
+ // particular widget class, it can set this property to ensure
+ // that its template is always re-built from a string
+ _skipNodeCache: false,
+
+ // _earlyTemplatedStartup: Boolean
+ // A fallback to preserve the 1.0 - 1.3 behavior of children in
+ // templates having their startup called before the parent widget
+ // fires postCreate. Defaults to 'false', causing child widgets to
+ // have their .startup() called immediately before a parent widget
+ // .startup(), but always after the parent .postCreate(). Set to
+ // 'true' to re-enable to previous, arguably broken, behavior.
+ _earlyTemplatedStartup: false,
+
+/*=====
+ // _attachPoints: [private] String[]
+ // List of widget attribute names associated with data-dojo-attach-point=... in the
+ // template, ex: ["containerNode", "labelNode"]
+ _attachPoints: [],
+ =====*/
+
+/*=====
+ // _attachEvents: [private] Handle[]
+ // List of connections associated with data-dojo-attach-event=... in the
+ // template
+ _attachEvents: [],
+ =====*/
+
+ constructor: function(){
+ this._attachPoints = [];
+ this._attachEvents = [];
+ },
+
+ _stringRepl: function(tmpl){
+ // summary:
+ // Does substitution of ${foo} type properties in template string
+ // tags:
+ // private
+ var className = this.declaredClass, _this = this;
+ // Cache contains a string because we need to do property replacement
+ // do the property replacement
+ return string.substitute(tmpl, this, function(value, key){
+ if(key.charAt(0) == '!'){ value = lang.getObject(key.substr(1), false, _this); }
+ if(typeof value == "undefined"){ throw new Error(className+" template:"+key); } // a debugging aide
+ if(value == null){ return ""; }
+
+ // Substitution keys beginning with ! will skip the transform step,
+ // in case a user wishes to insert unescaped markup, e.g. ${!foo}
+ return key.charAt(0) == "!" ? value :
+ // Safer substitution, see heading "Attribute values" in
+ // http://www.w3.org/TR/REC-html40/appendix/notes.html#h-B.3.2
+ value.toString().replace(/"/g,"&quot;"); //TODO: add &amp? use encodeXML method?
+ }, this);
+ },
+
+ buildRendering: function(){
+ // summary:
+ // Construct the UI for this widget from a template, setting this.domNode.
+ // tags:
+ // protected
+
+ if(!this.templateString){
+ this.templateString = cache(this.templatePath, {sanitize: true});
+ }
+
+ // Lookup cached version of template, and download to cache if it
+ // isn't there already. Returns either a DomNode or a string, depending on
+ // whether or not the template contains ${foo} replacement parameters.
+ var cached = _TemplatedMixin.getCachedTemplate(this.templateString, this._skipNodeCache);
+
+ var node;
+ if(lang.isString(cached)){
+ node = domConstruct.toDom(this._stringRepl(cached));
+ if(node.nodeType != 1){
+ // Flag common problems such as templates with multiple top level nodes (nodeType == 11)
+ throw new Error("Invalid template: " + cached);
+ }
+ }else{
+ // if it's a node, all we have to do is clone it
+ node = cached.cloneNode(true);
+ }
+
+ this.domNode = node;
+
+ // Call down to _Widget.buildRendering() to get base classes assigned
+ // TODO: change the baseClass assignment to _setBaseClassAttr
+ this.inherited(arguments);
+
+ // recurse through the node, looking for, and attaching to, our
+ // attachment points and events, which should be defined on the template node.
+ this._attachTemplateNodes(node, function(n,p){ return n.getAttribute(p); });
+
+ this._beforeFillContent(); // hook for _WidgetsInTemplateMixin
+
+ this._fillContent(this.srcNodeRef);
+ },
+
+ _beforeFillContent: function(){
+ },
+
+ _fillContent: function(/*DomNode*/ source){
+ // summary:
+ // Relocate source contents to templated container node.
+ // this.containerNode must be able to receive children, or exceptions will be thrown.
+ // tags:
+ // protected
+ var dest = this.containerNode;
+ if(source && dest){
+ while(source.hasChildNodes()){
+ dest.appendChild(source.firstChild);
+ }
+ }
+ },
+
+ _attachTemplateNodes: function(rootNode, getAttrFunc){
+ // summary:
+ // Iterate through the template and attach functions and nodes accordingly.
+ // Alternately, if rootNode is an array of widgets, then will process data-dojo-attach-point
+ // etc. for those widgets.
+ // description:
+ // Map widget properties and functions to the handlers specified in
+ // the dom node and it's descendants. This function iterates over all
+ // nodes and looks for these properties:
+ // * dojoAttachPoint/data-dojo-attach-point
+ // * dojoAttachEvent/data-dojo-attach-event
+ // rootNode: DomNode|Widget[]
+ // the node to search for properties. All children will be searched.
+ // getAttrFunc: Function
+ // a function which will be used to obtain property for a given
+ // DomNode/Widget
+ // tags:
+ // private
+
+ var nodes = lang.isArray(rootNode) ? rootNode : (rootNode.all || rootNode.getElementsByTagName("*"));
+ var x = lang.isArray(rootNode) ? 0 : -1;
+ for(; x<nodes.length; x++){
+ var baseNode = (x == -1) ? rootNode : nodes[x];
+ if(this.widgetsInTemplate && (getAttrFunc(baseNode, "dojoType") || getAttrFunc(baseNode, "data-dojo-type"))){
+ continue;
+ }
+ // Process data-dojo-attach-point
+ var attachPoint = getAttrFunc(baseNode, "dojoAttachPoint") || getAttrFunc(baseNode, "data-dojo-attach-point");
+ if(attachPoint){
+ var point, points = attachPoint.split(/\s*,\s*/);
+ while((point = points.shift())){
+ if(lang.isArray(this[point])){
+ this[point].push(baseNode);
+ }else{
+ this[point]=baseNode;
+ }
+ this._attachPoints.push(point);
+ }
+ }
+
+ // Process data-dojo-attach-event
+ var attachEvent = getAttrFunc(baseNode, "dojoAttachEvent") || getAttrFunc(baseNode, "data-dojo-attach-event");
+ if(attachEvent){
+ // NOTE: we want to support attributes that have the form
+ // "domEvent: nativeEvent; ..."
+ var event, events = attachEvent.split(/\s*,\s*/);
+ var trim = lang.trim;
+ while((event = events.shift())){
+ if(event){
+ var thisFunc = null;
+ if(event.indexOf(":") != -1){
+ // oh, if only JS had tuple assignment
+ var funcNameArr = event.split(":");
+ event = trim(funcNameArr[0]);
+ thisFunc = trim(funcNameArr[1]);
+ }else{
+ event = trim(event);
+ }
+ if(!thisFunc){
+ thisFunc = event;
+ }
+ // Map "press", "move" and "release" to keys.touch, keys.move, keys.release
+ this._attachEvents.push(this.connect(baseNode, touch[event] || event, thisFunc));
+ }
+ }
+ }
+ }
+ },
+
+ destroyRendering: function(){
+ // Delete all attach points to prevent IE6 memory leaks.
+ array.forEach(this._attachPoints, function(point){
+ delete this[point];
+ }, this);
+ this._attachPoints = [];
+
+ // And same for event handlers
+ array.forEach(this._attachEvents, this.disconnect, this);
+ this._attachEvents = [];
+
+ this.inherited(arguments);
+ }
+ });
+
+ // key is templateString; object is either string or DOM tree
+ _TemplatedMixin._templateCache = {};
+
+ _TemplatedMixin.getCachedTemplate = function(templateString, alwaysUseString){
+ // summary:
+ // Static method to get a template based on the templatePath or
+ // templateString key
+ // templateString: String
+ // The template
+ // alwaysUseString: Boolean
+ // Don't cache the DOM tree for this template, even if it doesn't have any variables
+ // returns: Mixed
+ // Either string (if there are ${} variables that need to be replaced) or just
+ // a DOM tree (if the node can be cloned directly)
+
+ // is it already cached?
+ var tmplts = _TemplatedMixin._templateCache;
+ var key = templateString;
+ var cached = tmplts[key];
+ if(cached){
+ try{
+ // if the cached value is an innerHTML string (no ownerDocument) or a DOM tree created within the current document, then use the current cached value
+ if(!cached.ownerDocument || cached.ownerDocument == win.doc){
+ // string or node of the same document
+ return cached;
+ }
+ }catch(e){ /* squelch */ } // IE can throw an exception if cached.ownerDocument was reloaded
+ domConstruct.destroy(cached);
+ }
+
+ templateString = string.trim(templateString);
+
+ if(alwaysUseString || templateString.match(/\$\{([^\}]+)\}/g)){
+ // there are variables in the template so all we can do is cache the string
+ return (tmplts[key] = templateString); //String
+ }else{
+ // there are no variables in the template so we can cache the DOM tree
+ var node = domConstruct.toDom(templateString);
+ if(node.nodeType != 1){
+ throw new Error("Invalid template: " + templateString);
+ }
+ return (tmplts[key] = node); //Node
+ }
+ };
+
+ if(has("ie")){
+ unload.addOnWindowUnload(function(){
+ var cache = _TemplatedMixin._templateCache;
+ for(var key in cache){
+ var value = cache[key];
+ if(typeof value == "object"){ // value is either a string or a DOM node template
+ domConstruct.destroy(value);
+ }
+ delete cache[key];
+ }
+ });
+ }
+
+ // These arguments can be specified for widgets which are used in templates.
+ // Since any widget can be specified as sub widgets in template, mix it
+ // into the base widget class. (This is a hack, but it's effective.)
+ lang.extend(_WidgetBase,{
+ dojoAttachEvent: "",
+ dojoAttachPoint: ""
+ });
+
+ return _TemplatedMixin;
+});
+
+},
+'dojox/grid/_SelectionPreserver':function(){
+define("dojox/grid/_SelectionPreserver", [
+ "dojo/_base/declare",
+ "dojo/_base/connect",
+ "dojo/_base/lang",
+ "dojo/_base/array"
+], function(declare, connect, lang, array){
+
+return declare("dojox.grid._SelectionPreserver", null, {
+ // summary:
+ // Preserve selections across various user actions.
+ //
+ // description:
+ // When this feature is turned on, Grid will try to preserve selections across actions, e.g. sorting, filtering etc.
+ //
+ // Precondition - Identifier(id) is required for store since id is the only way for differentiating row items.
+ // Known issue - The preserved selections might be inaccurate if some unloaded rows are previously selected by range(e.g.SHIFT + click)
+ //
+ // example:
+ // | //To turn on this - please set 'keepSelection' attribute to true
+ // | <div dojoType="dojox.grid.DataGrid" keepSelection = true .../>
+ // | <div dojoType="dojox.grid.TreeGrid" keepSelection = true .../>
+ // | <div dojoType="dojox.grid.LazyTreeGrid" keepSelection = true .../>
+
+ constructor: function(selection){
+ this.selection = selection;
+ var grid = this.grid = selection.grid;
+ this.reset();
+ this._connects = [
+ connect.connect(grid, '_setStore', this, 'reset'),
+ connect.connect(grid, '_addItem', this, '_reSelectById'),
+ connect.connect(selection, 'addToSelection', lang.hitch(this, '_selectById', true)),
+ connect.connect(selection, 'deselect', lang.hitch(this, '_selectById', false)),
+ connect.connect(selection, 'deselectAll', this, 'reset')
+ ];
+ },
+ destroy: function(){
+ this.reset();
+ array.forEach(this._connects, connect.disconnect);
+ delete this._connects;
+ },
+ reset: function(){
+ this._selectedById = {};
+ },
+ _reSelectById: function(item, index){
+ // summary:
+ // When some rows is fetched, determine whether it should be selected.
+ if(item && this.grid._hasIdentity){
+ this.selection.selected[index] = this._selectedById[this.grid.store.getIdentity(item)];
+ }
+ },
+ _selectById: function(toSelect, inItemOrIndex){
+ // summary:
+ // Record selected rows by ID.
+ if(this.selection.mode == 'none' || !this.grid._hasIdentity){ return; }
+ var item = inItemOrIndex, g = this.grid;
+ if(typeof inItemOrIndex == "number" || typeof inItemOrIndex == "string"){
+ var entry = g._by_idx[inItemOrIndex];
+ item = entry && entry.item;
+ }
+ if(item){
+ this._selectedById[g.store.getIdentity(item)] = !!toSelect;
+ }
+ return item;
+ }
+});
+});
+},
+'dojo/window':function(){
+define(["./_base/lang", "./_base/sniff", "./_base/window", "./dom", "./dom-geometry", "./dom-style"],
+ function(lang, has, baseWindow, dom, geom, style) {
+
+// module:
+// dojo/window
+// summary:
+// TODOC
+
+var window = lang.getObject("dojo.window", true);
+
+/*=====
+dojo.window = {
+ // summary:
+ // TODO
+};
+window = dojo.window;
+=====*/
+
+window.getBox = function(){
+ // summary:
+ // Returns the dimensions and scroll position of the viewable area of a browser window
+
+ var
+ scrollRoot = (baseWindow.doc.compatMode == 'BackCompat') ? baseWindow.body() : baseWindow.doc.documentElement,
+ // get scroll position
+ scroll = geom.docScroll(), // scrollRoot.scrollTop/Left should work
+ w, h;
+
+ if(has("touch")){ // if(scrollbars not supported)
+ var uiWindow = baseWindow.doc.parentWindow || baseWindow.doc.defaultView; // use UI window, not dojo.global window. baseWindow.doc.parentWindow probably not needed since it's not defined for webkit
+ // on mobile, scrollRoot.clientHeight <= uiWindow.innerHeight <= scrollRoot.offsetHeight, return uiWindow.innerHeight
+ w = uiWindow.innerWidth || scrollRoot.clientWidth; // || scrollRoot.clientXXX probably never evaluated
+ h = uiWindow.innerHeight || scrollRoot.clientHeight;
+ }else{
+ // on desktops, scrollRoot.clientHeight <= scrollRoot.offsetHeight <= uiWindow.innerHeight, return scrollRoot.clientHeight
+ // uiWindow.innerWidth/Height includes the scrollbar and cannot be used
+ w = scrollRoot.clientWidth;
+ h = scrollRoot.clientHeight;
+ }
+ return {
+ l: scroll.x,
+ t: scroll.y,
+ w: w,
+ h: h
+ };
+};
+
+window.get = function(doc){
+ // summary:
+ // Get window object associated with document doc
+
+ // In some IE versions (at least 6.0), document.parentWindow does not return a
+ // reference to the real window object (maybe a copy), so we must fix it as well
+ // We use IE specific execScript to attach the real window reference to
+ // document._parentWindow for later use
+ if(has("ie") && window !== document.parentWindow){
+ /*
+ In IE 6, only the variable "window" can be used to connect events (others
+ may be only copies).
+ */
+ doc.parentWindow.execScript("document._parentWindow = window;", "Javascript");
+ //to prevent memory leak, unset it after use
+ //another possibility is to add an onUnload handler which seems overkill to me (liucougar)
+ var win = doc._parentWindow;
+ doc._parentWindow = null;
+ return win; // Window
+ }
+
+ return doc.parentWindow || doc.defaultView; // Window
+};
+
+window.scrollIntoView = function(/*DomNode*/ node, /*Object?*/ pos){
+ // summary:
+ // Scroll the passed node into view, if it is not already.
+
+ // don't rely on node.scrollIntoView working just because the function is there
+
+ try{ // catch unexpected/unrecreatable errors (#7808) since we can recover using a semi-acceptable native method
+ node = dom.byId(node);
+ var doc = node.ownerDocument || baseWindow.doc,
+ body = doc.body || baseWindow.body(),
+ html = doc.documentElement || body.parentNode,
+ isIE = has("ie"), isWK = has("webkit");
+ // if an untested browser, then use the native method
+ if((!(has("mozilla") || isIE || isWK || has("opera")) || node == body || node == html) && (typeof node.scrollIntoView != "undefined")){
+ node.scrollIntoView(false); // short-circuit to native if possible
+ return;
+ }
+ var backCompat = doc.compatMode == 'BackCompat',
+ clientAreaRoot = (isIE >= 9 && node.ownerDocument.parentWindow.frameElement)
+ ? ((html.clientHeight > 0 && html.clientWidth > 0 && (body.clientHeight == 0 || body.clientWidth == 0 || body.clientHeight > html.clientHeight || body.clientWidth > html.clientWidth)) ? html : body)
+ : (backCompat ? body : html),
+ scrollRoot = isWK ? body : clientAreaRoot,
+ rootWidth = clientAreaRoot.clientWidth,
+ rootHeight = clientAreaRoot.clientHeight,
+ rtl = !geom.isBodyLtr(),
+ nodePos = pos || geom.position(node),
+ el = node.parentNode,
+ isFixed = function(el){
+ return ((isIE <= 6 || (isIE && backCompat))? false : (style.get(el, 'position').toLowerCase() == "fixed"));
+ };
+ if(isFixed(node)){ return; } // nothing to do
+
+ while(el){
+ if(el == body){ el = scrollRoot; }
+ var elPos = geom.position(el),
+ fixedPos = isFixed(el);
+
+ if(el == scrollRoot){
+ elPos.w = rootWidth; elPos.h = rootHeight;
+ if(scrollRoot == html && isIE && rtl){ elPos.x += scrollRoot.offsetWidth-elPos.w; } // IE workaround where scrollbar causes negative x
+ if(elPos.x < 0 || !isIE){ elPos.x = 0; } // IE can have values > 0
+ if(elPos.y < 0 || !isIE){ elPos.y = 0; }
+ }else{
+ var pb = geom.getPadBorderExtents(el);
+ elPos.w -= pb.w; elPos.h -= pb.h; elPos.x += pb.l; elPos.y += pb.t;
+ var clientSize = el.clientWidth,
+ scrollBarSize = elPos.w - clientSize;
+ if(clientSize > 0 && scrollBarSize > 0){
+ elPos.w = clientSize;
+ elPos.x += (rtl && (isIE || el.clientLeft > pb.l/*Chrome*/)) ? scrollBarSize : 0;
+ }
+ clientSize = el.clientHeight;
+ scrollBarSize = elPos.h - clientSize;
+ if(clientSize > 0 && scrollBarSize > 0){
+ elPos.h = clientSize;
+ }
+ }
+ if(fixedPos){ // bounded by viewport, not parents
+ if(elPos.y < 0){
+ elPos.h += elPos.y; elPos.y = 0;
+ }
+ if(elPos.x < 0){
+ elPos.w += elPos.x; elPos.x = 0;
+ }
+ if(elPos.y + elPos.h > rootHeight){
+ elPos.h = rootHeight - elPos.y;
+ }
+ if(elPos.x + elPos.w > rootWidth){
+ elPos.w = rootWidth - elPos.x;
+ }
+ }
+ // calculate overflow in all 4 directions
+ var l = nodePos.x - elPos.x, // beyond left: < 0
+ t = nodePos.y - Math.max(elPos.y, 0), // beyond top: < 0
+ r = l + nodePos.w - elPos.w, // beyond right: > 0
+ bot = t + nodePos.h - elPos.h; // beyond bottom: > 0
+ if(r * l > 0){
+ var s = Math[l < 0? "max" : "min"](l, r);
+ if(rtl && ((isIE == 8 && !backCompat) || isIE >= 9)){ s = -s; }
+ nodePos.x += el.scrollLeft;
+ el.scrollLeft += s;
+ nodePos.x -= el.scrollLeft;
+ }
+ if(bot * t > 0){
+ nodePos.y += el.scrollTop;
+ el.scrollTop += Math[t < 0? "max" : "min"](t, bot);
+ nodePos.y -= el.scrollTop;
+ }
+ el = (el != scrollRoot) && !fixedPos && el.parentNode;
+ }
+ }catch(error){
+ console.error('scrollIntoView: ' + error);
+ node.scrollIntoView(false);
+ }
+};
+
+return window;
+});
+
+},
+'dojox/grid/_Builder':function(){
+define("dojox/grid/_Builder", [
+ "../main",
+ "dojo/_base/array",
+ "dojo/_base/lang",
+ "dojo/_base/window",
+ "dojo/_base/event",
+ "dojo/_base/sniff",
+ "dojo/_base/connect",
+ "dojo/dnd/Moveable",
+ "dojox/html/metrics",
+ "./util",
+ "dojo/_base/html"
+], function(dojox, array, lang, win, event, has, connect, Moveable, metrics, util, html){
+
+ var dg = dojox.grid;
+
+ var getTdIndex = function(td){
+ return td.cellIndex >=0 ? td.cellIndex : array.indexOf(td.parentNode.cells, td);
+ };
+
+ var getTrIndex = function(tr){
+ return tr.rowIndex >=0 ? tr.rowIndex : array.indexOf(tr.parentNode.childNodes, tr);
+ };
+
+ var getTr = function(rowOwner, index){
+ return rowOwner && ((rowOwner.rows||0)[index] || rowOwner.childNodes[index]);
+ };
+
+ var findTable = function(node){
+ for(var n=node; n && n.tagName!='TABLE'; n=n.parentNode){}
+ return n;
+ };
+
+ var ascendDom = function(inNode, inWhile){
+ for(var n=inNode; n && inWhile(n); n=n.parentNode){}
+ return n;
+ };
+
+ var makeNotTagName = function(inTagName){
+ var name = inTagName.toUpperCase();
+ return function(node){ return node.tagName != name; };
+ };
+
+ var rowIndexTag = util.rowIndexTag;
+ var gridViewTag = util.gridViewTag;
+
+ // base class for generating markup for the views
+ var _Builder = dg._Builder = lang.extend(function(view){
+ if(view){
+ this.view = view;
+ this.grid = view.grid;
+ }
+ },{
+ view: null,
+ // boilerplate HTML
+ _table: '<table class="dojoxGridRowTable" border="0" cellspacing="0" cellpadding="0" role="presentation"',
+
+ // Returns the table variable as an array - and with the view width, if specified
+ getTableArray: function(){
+ var html = [this._table];
+ if(this.view.viewWidth){
+ html.push([' style="width:', this.view.viewWidth, ';"'].join(''));
+ }
+ html.push('>');
+ return html;
+ },
+
+ // generate starting tags for a cell
+ generateCellMarkup: function(inCell, inMoreStyles, inMoreClasses, isHeader){
+ var result = [], html;
+ if(isHeader){
+ var sortInfo = inCell.index != inCell.grid.getSortIndex() ? "" : inCell.grid.sortInfo > 0 ? 'aria-sort="ascending"' : 'aria-sort="descending"';
+ if (!inCell.id){
+ inCell.id = this.grid.id + "Hdr" + inCell.index;
+ }
+ // column headers are not editable, mark as aria-readonly=true
+ html = ['<th tabIndex="-1" aria-readonly="true" role="columnheader"', sortInfo, 'id="', inCell.id, '"'];
+ }else{
+ // cells inherit grid aria-readonly property; default value for aria-readonly is false(grid is editable)
+ // if grid is editable (had any editable cells), mark non editable cells as aria-readonly=true
+ // if no editable cells, grid's aria-readonly value will have been set to true and cells will inherit
+ var editInfo = this.grid.editable && !inCell.editable ? 'aria-readonly="true"' : "";
+ html = ['<td tabIndex="-1" role="gridcell"', editInfo];
+ }
+ if(inCell.colSpan){
+ html.push(' colspan="', inCell.colSpan, '"');
+ }
+ if(inCell.rowSpan){
+ html.push(' rowspan="', inCell.rowSpan, '"');
+ }
+ html.push(' class="dojoxGridCell ');
+ if(inCell.classes){
+ html.push(inCell.classes, ' ');
+ }
+ if(inMoreClasses){
+ html.push(inMoreClasses, ' ');
+ }
+ // result[0] => td opener, style
+ result.push(html.join(''));
+ // SLOT: result[1] => td classes
+ result.push('');
+ html = ['" idx="', inCell.index, '" style="'];
+ if(inMoreStyles && inMoreStyles[inMoreStyles.length-1] != ';'){
+ inMoreStyles += ';';
+ }
+ html.push(inCell.styles, inMoreStyles||'', inCell.hidden?'display:none;':'');
+ if(inCell.unitWidth){
+ html.push('width:', inCell.unitWidth, ';');
+ }
+ // result[2] => markup
+ result.push(html.join(''));
+ // SLOT: result[3] => td style
+ result.push('');
+ html = [ '"' ];
+ if(inCell.attrs){
+ html.push(" ", inCell.attrs);
+ }
+ html.push('>');
+ // result[4] => td postfix
+ result.push(html.join(''));
+ // SLOT: result[5] => content
+ result.push('');
+ // result[6] => td closes
+ result.push(isHeader?'</th>':'</td>');
+ return result; // Array
+ },
+
+ // cell finding
+ isCellNode: function(inNode){
+ return Boolean(inNode && inNode!=win.doc && html.attr(inNode, "idx"));
+ },
+
+ getCellNodeIndex: function(inCellNode){
+ return inCellNode ? Number(html.attr(inCellNode, "idx")) : -1;
+ },
+
+ getCellNode: function(inRowNode, inCellIndex){
+ for(var i=0, row; ((row = getTr(inRowNode.firstChild, i)) && row.cells); i++){
+ for(var j=0, cell; (cell = row.cells[j]); j++){
+ if(this.getCellNodeIndex(cell) == inCellIndex){
+ return cell;
+ }
+ }
+ }
+ return null;
+ },
+
+ findCellTarget: function(inSourceNode, inTopNode){
+ var n = inSourceNode;
+ while(n && (!this.isCellNode(n) || (n.offsetParent && gridViewTag in n.offsetParent.parentNode && n.offsetParent.parentNode[gridViewTag] != this.view.id)) && (n!=inTopNode)){
+ n = n.parentNode;
+ }
+ return n!=inTopNode ? n : null;
+ },
+
+ // event decoration
+ baseDecorateEvent: function(e){
+ e.dispatch = 'do' + e.type;
+ e.grid = this.grid;
+ e.sourceView = this.view;
+ e.cellNode = this.findCellTarget(e.target, e.rowNode);
+ e.cellIndex = this.getCellNodeIndex(e.cellNode);
+ e.cell = (e.cellIndex >= 0 ? this.grid.getCell(e.cellIndex) : null);
+ },
+
+ // event dispatch
+ findTarget: function(inSource, inTag){
+ var n = inSource;
+ while(n && (n!=this.domNode) && (!(inTag in n) || (gridViewTag in n && n[gridViewTag] != this.view.id))){
+ n = n.parentNode;
+ }
+ return (n != this.domNode) ? n : null;
+ },
+
+ findRowTarget: function(inSource){
+ return this.findTarget(inSource, rowIndexTag);
+ },
+
+ isIntraNodeEvent: function(e){
+ try{
+ return (e.cellNode && e.relatedTarget && html.isDescendant(e.relatedTarget, e.cellNode));
+ }catch(x){
+ // e.relatedTarget has permission problem in FF if it's an input: https://bugzilla.mozilla.org/show_bug.cgi?id=208427
+ return false;
+ }
+ },
+
+ isIntraRowEvent: function(e){
+ try{
+ var row = e.relatedTarget && this.findRowTarget(e.relatedTarget);
+ return !row && (e.rowIndex==-1) || row && (e.rowIndex==row.gridRowIndex);
+ }catch(x){
+ // e.relatedTarget on INPUT has permission problem in FF: https://bugzilla.mozilla.org/show_bug.cgi?id=208427
+ return false;
+ }
+ },
+
+ dispatchEvent: function(e){
+ if(e.dispatch in this){
+ return this[e.dispatch](e);
+ }
+ return false;
+ },
+
+ // dispatched event handlers
+ domouseover: function(e){
+ if(e.cellNode && (e.cellNode!=this.lastOverCellNode)){
+ this.lastOverCellNode = e.cellNode;
+ this.grid.onMouseOver(e);
+ }
+ this.grid.onMouseOverRow(e);
+ },
+
+ domouseout: function(e){
+ if(e.cellNode && (e.cellNode==this.lastOverCellNode) && !this.isIntraNodeEvent(e, this.lastOverCellNode)){
+ this.lastOverCellNode = null;
+ this.grid.onMouseOut(e);
+ if(!this.isIntraRowEvent(e)){
+ this.grid.onMouseOutRow(e);
+ }
+ }
+ },
+
+ domousedown: function(e){
+ if (e.cellNode)
+ this.grid.onMouseDown(e);
+ this.grid.onMouseDownRow(e);
+ }
+ });
+
+ // Produces html for grid data content. Owned by grid and used internally
+ // for rendering data. Override to implement custom rendering.
+ var _ContentBuilder = dg._ContentBuilder = lang.extend(function(view){
+ _Builder.call(this, view);
+ },_Builder.prototype,{
+ update: function(){
+ this.prepareHtml();
+ },
+
+ // cache html for rendering data rows
+ prepareHtml: function(){
+ var defaultGet=this.grid.get, cells=this.view.structure.cells;
+ for(var j=0, row; (row=cells[j]); j++){
+ for(var i=0, cell; (cell=row[i]); i++){
+ cell.get = cell.get || (cell.value == undefined) && defaultGet;
+ cell.markup = this.generateCellMarkup(cell, cell.cellStyles, cell.cellClasses, false);
+ if (!this.grid.editable && cell.editable){
+ this.grid.editable = true;
+ }
+ }
+ }
+ },
+
+ // time critical: generate html using cache and data source
+ generateHtml: function(inDataIndex, inRowIndex){
+ var
+ html = this.getTableArray(),
+ v = this.view,
+ cells = v.structure.cells,
+ item = this.grid.getItem(inRowIndex);
+
+ util.fire(this.view, "onBeforeRow", [inRowIndex, cells]);
+ for(var j=0, row; (row=cells[j]); j++){
+ if(row.hidden || row.header){
+ continue;
+ }
+ html.push(!row.invisible ? '<tr>' : '<tr class="dojoxGridInvisible">');
+ for(var i=0, cell, m, cc, cs; (cell=row[i]); i++){
+ m = cell.markup; cc = cell.customClasses = []; cs = cell.customStyles = [];
+ // content (format can fill in cc and cs as side-effects)
+ m[5] = cell.format(inRowIndex, item);
+ if(has("ie") < 8 && (m[5] === null || m[5] === '' || /^\s+$/.test(m[5]))){
+ //fix IE 6/7 quirks - border style not effective for empty td
+ m[5] = '&nbsp;'
+ }
+ // classes
+ m[1] = cc.join(' ');
+ // styles
+ m[3] = cs.join(';');
+ // in-place concat
+ html.push.apply(html, m);
+ }
+ html.push('</tr>');
+ }
+ html.push('</table>');
+ return html.join(''); // String
+ },
+
+ decorateEvent: function(e){
+ e.rowNode = this.findRowTarget(e.target);
+ if(!e.rowNode){return false;}
+ e.rowIndex = e.rowNode[rowIndexTag];
+ this.baseDecorateEvent(e);
+ e.cell = this.grid.getCell(e.cellIndex);
+ return true; // Boolean
+ }
+ });
+
+ // Produces html for grid header content. Owned by grid and used internally
+ // for rendering data. Override to implement custom rendering.
+ var _HeaderBuilder = dg._HeaderBuilder = lang.extend(function(view){
+ this.moveable = null;
+ _Builder.call(this, view);
+ },_Builder.prototype,{
+ _skipBogusClicks: false,
+ overResizeWidth: 4,
+ minColWidth: 1,
+
+ update: function(){
+ if(this.tableMap){
+ this.tableMap.mapRows(this.view.structure.cells);
+ }else{
+ this.tableMap = new dg._TableMap(this.view.structure.cells);
+ }
+ },
+
+ generateHtml: function(inGetValue, inValue){
+ var html = this.getTableArray(), cells = this.view.structure.cells;
+
+ util.fire(this.view, "onBeforeRow", [-1, cells]);
+ for(var j=0, row; (row=cells[j]); j++){
+ if(row.hidden){
+ continue;
+ }
+ html.push(!row.invisible ? '<tr>' : '<tr class="dojoxGridInvisible">');
+ for(var i=0, cell, markup; (cell=row[i]); i++){
+ cell.customClasses = [];
+ cell.customStyles = [];
+ if(this.view.simpleStructure){
+ if(cell.draggable){
+ if(cell.headerClasses){
+ if(cell.headerClasses.indexOf('dojoDndItem') == -1){
+ cell.headerClasses += ' dojoDndItem';
+ }
+ }else{
+ cell.headerClasses = 'dojoDndItem';
+ }
+ }
+ if(cell.attrs){
+ if(cell.attrs.indexOf("dndType='gridColumn_") == -1){
+ cell.attrs += " dndType='gridColumn_" + this.grid.id + "'";
+ }
+ }else{
+ cell.attrs = "dndType='gridColumn_" + this.grid.id + "'";
+ }
+ }
+ markup = this.generateCellMarkup(cell, cell.headerStyles, cell.headerClasses, true);
+ // content
+ markup[5] = (inValue != undefined ? inValue : inGetValue(cell));
+ // styles
+ markup[3] = cell.customStyles.join(';');
+ // classes
+ markup[1] = cell.customClasses.join(' '); //(cell.customClasses ? ' ' + cell.customClasses : '');
+ html.push(markup.join(''));
+ }
+ html.push('</tr>');
+ }
+ html.push('</table>');
+ return html.join('');
+ },
+
+ // event helpers
+ getCellX: function(e){
+ var n, x = e.layerX;
+ if(has("mozilla") || has("ie") >= 9){
+ n = ascendDom(e.target, makeNotTagName("th"));
+ x -= (n && n.offsetLeft) || 0;
+ var t = e.sourceView.getScrollbarWidth();
+ if(!this.grid.isLeftToRight()/*&& e.sourceView.headerNode.scrollLeft < t*/){
+ //fix #11253
+ table = ascendDom(n,makeNotTagName("table"));
+ x -= (table && table.offsetLeft) || 0;
+ }
+ //x -= getProp(ascendDom(e.target, mkNotTagName("td")), "offsetLeft") || 0;
+ }
+ n = ascendDom(e.target, function(){
+ if(!n || n == e.cellNode){
+ return false;
+ }
+ // Mozilla 1.8 (FF 1.5) has a bug that makes offsetLeft = -parent border width
+ // when parent has border, overflow: hidden, and is positioned
+ // handle this problem here ... not a general solution!
+ x += (n.offsetLeft < 0 ? 0 : n.offsetLeft);
+ return true;
+ });
+ return x;
+ },
+
+ // event decoration
+ decorateEvent: function(e){
+ this.baseDecorateEvent(e);
+ e.rowIndex = -1;
+ e.cellX = this.getCellX(e);
+ return true;
+ },
+
+ // event handlers
+ // resizing
+ prepareResize: function(e, mod){
+ do{
+ var i = e.cellIndex;
+ e.cellNode = (i ? e.cellNode.parentNode.cells[i+mod] : null);
+ e.cellIndex = (e.cellNode ? this.getCellNodeIndex(e.cellNode) : -1);
+ }while(e.cellNode && e.cellNode.style.display == "none");
+ return Boolean(e.cellNode);
+ },
+
+ canResize: function(e){
+ if(!e.cellNode || e.cellNode.colSpan > 1){
+ return false;
+ }
+ var cell = this.grid.getCell(e.cellIndex);
+ return !cell.noresize && cell.canResize();
+ },
+
+ overLeftResizeArea: function(e){
+ // We are never over a resize area if we are in the process of moving
+ if(html.hasClass(win.body(), "dojoDndMove")){
+ return false;
+ }
+ //Bugfix for crazy IE problem (#8807). IE returns position information for the icon and text arrow divs
+ //as if they were still on the left instead of returning the position they were 'float: right' to.
+ //So, the resize check ends up checking the wrong adjacent cell. This checks to see if the hover was over
+ //the image or text nodes, then just ignored them/treat them not in scale range.
+ if(has("ie")){
+ var tN = e.target;
+ if(html.hasClass(tN, "dojoxGridArrowButtonNode") ||
+ html.hasClass(tN, "dojoxGridArrowButtonChar") ||
+ html.hasClass(tN, "dojoxGridColCaption")){
+ return false;
+ }
+ }
+
+ if(this.grid.isLeftToRight()){
+ return (e.cellIndex>0) && (e.cellX > 0 && e.cellX < this.overResizeWidth) && this.prepareResize(e, -1);
+ }
+ var t = e.cellNode && (e.cellX > 0 && e.cellX < this.overResizeWidth);
+ return t;
+ },
+
+ overRightResizeArea: function(e){
+ // We are never over a resize area if we are in the process of moving
+ if(html.hasClass(win.body(), "dojoDndMove")){
+ return false;
+ }
+ //Bugfix for crazy IE problem (#8807). IE returns position information for the icon and text arrow divs
+ //as if they were still on the left instead of returning the position they were 'float: right' to.
+ //So, the resize check ends up checking the wrong adjacent cell. This checks to see if the hover was over
+ //the image or text nodes, then just ignored them/treat them not in scale range.
+ if(has("ie")){
+ var tN = e.target;
+ if(html.hasClass(tN, "dojoxGridArrowButtonNode") ||
+ html.hasClass(tN, "dojoxGridArrowButtonChar") ||
+ html.hasClass(tN, "dojoxGridColCaption")){
+ return false;
+ }
+ }
+
+ if(this.grid.isLeftToRight()){
+ return e.cellNode && (e.cellX >= e.cellNode.offsetWidth - this.overResizeWidth);
+ }
+ return (e.cellIndex>0) && (e.cellX >= e.cellNode.offsetWidth - this.overResizeWidth) && this.prepareResize(e, -1);
+ },
+
+ domousemove: function(e){
+ //console.log(e.cellIndex, e.cellX, e.cellNode.offsetWidth);
+ if(!this.moveable){
+ var c = (this.overRightResizeArea(e) ? 'dojoxGridColResize' : (this.overLeftResizeArea(e) ? 'dojoxGridColResize' : ''));
+ if(c && !this.canResize(e)){
+ c = 'dojoxGridColNoResize';
+ }
+ html.toggleClass(e.sourceView.headerNode, "dojoxGridColNoResize", (c == "dojoxGridColNoResize"));
+ html.toggleClass(e.sourceView.headerNode, "dojoxGridColResize", (c == "dojoxGridColResize"));
+ if(c){
+ event.stop(e);
+ }
+ }
+ },
+
+ domousedown: function(e){
+ if(!this.moveable){
+ if((this.overRightResizeArea(e) || this.overLeftResizeArea(e)) && this.canResize(e)){
+ this.beginColumnResize(e);
+ }else{
+ this.grid.onMouseDown(e);
+ this.grid.onMouseOverRow(e);
+ }
+ //else{
+ // this.beginMoveColumn(e);
+ //}
+ }
+ },
+
+ doclick: function(e) {
+ if(this._skipBogusClicks){
+ event.stop(e);
+ return true;
+ }
+ return false;
+ },
+
+ // column resizing
+ colResizeSetup: function(/*Event Object*/e, /*boolean*/ isMouse ){
+ //Set up the drag object for column resizing
+ // Called with mouse event in case of drag and drop,
+ // Also called from keyboard shift-arrow event when focus is on a header
+ var headContentBox = html.contentBox(e.sourceView.headerNode);
+
+ if(isMouse){ //IE draws line even with no mouse down so separate from keyboard
+ this.lineDiv = document.createElement('div');
+
+ var vw = html.position(e.sourceView.headerNode, true);
+ var bodyContentBox = html.contentBox(e.sourceView.domNode);
+ //fix #11340
+ var l = e.pageX;
+ if(!this.grid.isLeftToRight() && has("ie") < 8){
+ l -= metrics.getScrollbar().w;
+ }
+ html.style(this.lineDiv, {
+ top: vw.y + "px",
+ left: l + "px",
+ height: (bodyContentBox.h + headContentBox.h) + "px"
+ });
+ html.addClass(this.lineDiv, "dojoxGridResizeColLine");
+ this.lineDiv._origLeft = l;
+ win.body().appendChild(this.lineDiv);
+ }
+ var spanners = [], nodes = this.tableMap.findOverlappingNodes(e.cellNode);
+ for(var i=0, cell; (cell=nodes[i]); i++){
+ spanners.push({ node: cell, index: this.getCellNodeIndex(cell), width: cell.offsetWidth });
+ //console.log("spanner: " + this.getCellNodeIndex(cell));
+ }
+
+ var view = e.sourceView;
+ var adj = this.grid.isLeftToRight() ? 1 : -1;
+ var views = e.grid.views.views;
+ var followers = [];
+ for(var j=view.idx+adj, cView; (cView=views[j]); j=j+adj){
+ followers.push({ node: cView.headerNode, left: window.parseInt(cView.headerNode.style.left) });
+ }
+ var table = view.headerContentNode.firstChild;
+ var drag = {
+ scrollLeft: e.sourceView.headerNode.scrollLeft,
+ view: view,
+ node: e.cellNode,
+ index: e.cellIndex,
+ w: html.contentBox(e.cellNode).w,
+ vw: headContentBox.w,
+ table: table,
+ tw: html.contentBox(table).w,
+ spanners: spanners,
+ followers: followers
+ };
+ return drag;
+ },
+ beginColumnResize: function(e){
+ this.moverDiv = document.createElement("div");
+ html.style(this.moverDiv,{position: "absolute", left:0}); // to make DnD work with dir=rtl
+ win.body().appendChild(this.moverDiv);
+ html.addClass(this.grid.domNode, "dojoxGridColumnResizing");
+ var m = (this.moveable = new Moveable(this.moverDiv));
+
+ var drag = this.colResizeSetup(e,true);
+
+ m.onMove = lang.hitch(this, "doResizeColumn", drag);
+
+ connect.connect(m, "onMoveStop", lang.hitch(this, function(){
+ this.endResizeColumn(drag);
+ if(drag.node.releaseCapture){
+ drag.node.releaseCapture();
+ }
+ this.moveable.destroy();
+ delete this.moveable;
+ this.moveable = null;
+ html.removeClass(this.grid.domNode, "dojoxGridColumnResizing");
+ }));
+
+ if(e.cellNode.setCapture){
+ e.cellNode.setCapture();
+ }
+ m.onMouseDown(e);
+ },
+
+ doResizeColumn: function(inDrag, mover, leftTop){
+ var changeX = leftTop.l;
+ var data = {
+ deltaX: changeX,
+ w: inDrag.w + (this.grid.isLeftToRight() ? changeX : -changeX),//fix #11341
+ vw: inDrag.vw + changeX,
+ tw: inDrag.tw + changeX
+ };
+
+ this.dragRecord = {inDrag: inDrag, mover: mover, leftTop:leftTop};
+
+ if(data.w >= this.minColWidth){
+ if (!mover) { // we are using keyboard do immediate resize
+ this.doResizeNow(inDrag, data);
+ }
+ else{
+ html.style(this.lineDiv, "left", (this.lineDiv._origLeft + data.deltaX) + "px");
+ }
+ }
+ },
+
+ endResizeColumn: function(inDrag){
+ if(this.dragRecord){
+ var leftTop = this.dragRecord.leftTop;
+ var changeX = this.grid.isLeftToRight() ? leftTop.l : -leftTop.l;
+ // Make sure we are not under our minimum
+ // http://bugs.dojotoolkit.org/ticket/9390
+ changeX += Math.max(inDrag.w + changeX, this.minColWidth) - (inDrag.w + changeX);
+ if(has("webkit") && inDrag.spanners.length){
+ // Webkit needs the pad border extents back in
+ changeX += html._getPadBorderExtents(inDrag.spanners[0].node).w;
+ }
+ var data = {
+ deltaX: changeX,
+ w: inDrag.w + changeX,
+ vw: inDrag.vw + changeX,
+ tw: inDrag.tw + changeX
+ };
+ // Only resize the columns when the drag has finished
+ this.doResizeNow(inDrag, data);
+ delete this.dragRecord;
+ }
+
+ html.destroy(this.lineDiv);
+ html.destroy(this.moverDiv);
+ html.destroy(this.moverDiv);
+ delete this.moverDiv;
+ this._skipBogusClicks = true;
+ inDrag.view.update();
+ this._skipBogusClicks = false;
+ this.grid.onResizeColumn(inDrag.index);
+ },
+ doResizeNow: function(inDrag, data){
+ inDrag.view.convertColPctToFixed();
+ if(inDrag.view.flexCells && !inDrag.view.testFlexCells()){
+ var t = findTable(inDrag.node);
+ if(t){
+ (t.style.width = '');
+ }
+ }
+ var i, s, sw, f, fl;
+ for(i=0; (s=inDrag.spanners[i]); i++){
+ sw = s.width + data.deltaX;
+ if(sw > 0){
+ s.node.style.width = sw + 'px';
+ inDrag.view.setColWidth(s.index, sw);
+ }
+ }
+ if(this.grid.isLeftToRight() || !has("ie")){//fix #11339
+ for(i=0; (f=inDrag.followers[i]); i++){
+ fl = f.left + data.deltaX;
+ f.node.style.left = fl + 'px';
+ }
+ }
+ inDrag.node.style.width = data.w + 'px';
+ inDrag.view.setColWidth(inDrag.index, data.w);
+ inDrag.view.headerNode.style.width = data.vw + 'px';
+ inDrag.view.setColumnsWidth(data.tw);
+ if(!this.grid.isLeftToRight()){
+ inDrag.view.headerNode.scrollLeft = inDrag.scrollLeft + data.deltaX;
+ }
+ }
+ });
+
+ // Maps an html table into a structure parsable for information about cell row and col spanning.
+ // Used by HeaderBuilder.
+ dg._TableMap = lang.extend(function(rows){
+ this.mapRows(rows);
+ },{
+ map: null,
+
+ mapRows: function(inRows){
+ // summary: Map table topography
+
+ //console.log('mapRows');
+ // # of rows
+ var rowCount = inRows.length;
+ if(!rowCount){
+ return;
+ }
+ // map which columns and rows fill which cells
+ this.map = [];
+ var row;
+ for(var k=0; (row=inRows[k]); k++){
+ this.map[k] = [];
+ }
+ for(var j=0; (row=inRows[j]); j++){
+ for(var i=0, x=0, cell, colSpan, rowSpan; (cell=row[i]); i++){
+ while(this.map[j][x]){x++;}
+ this.map[j][x] = { c: i, r: j };
+ rowSpan = cell.rowSpan || 1;
+ colSpan = cell.colSpan || 1;
+ for(var y=0; y<rowSpan; y++){
+ for(var s=0; s<colSpan; s++){
+ this.map[j+y][x+s] = this.map[j][x];
+ }
+ }
+ x += colSpan;
+ }
+ }
+ //this.dumMap();
+ },
+
+ dumpMap: function(){
+ for(var j=0, row, h=''; (row=this.map[j]); j++,h=''){
+ for(var i=0, cell; (cell=row[i]); i++){
+ h += cell.r + ',' + cell.c + ' ';
+ }
+ }
+ },
+
+ getMapCoords: function(inRow, inCol){
+ // summary: Find node's map coords by it's structure coords
+ for(var j=0, row; (row=this.map[j]); j++){
+ for(var i=0, cell; (cell=row[i]); i++){
+ if(cell.c==inCol && cell.r == inRow){
+ return { j: j, i: i };
+ }
+ //else{console.log(inRow, inCol, ' : ', i, j, " : ", cell.r, cell.c); };
+ }
+ }
+ return { j: -1, i: -1 };
+ },
+
+ getNode: function(inTable, inRow, inCol){
+ // summary: Find a node in inNode's table with the given structure coords
+ var row = inTable && inTable.rows[inRow];
+ return row && row.cells[inCol];
+ },
+
+ _findOverlappingNodes: function(inTable, inRow, inCol){
+ var nodes = [];
+ var m = this.getMapCoords(inRow, inCol);
+ //console.log("node j: %d, i: %d", m.j, m.i);
+ for(var j=0, row; (row=this.map[j]); j++){
+ if(j == m.j){ continue; }
+ var rw = row[m.i];
+ //console.log("overlaps: r: %d, c: %d", rw.r, rw.c);
+ var n = (rw?this.getNode(inTable, rw.r, rw.c):null);
+ if(n){ nodes.push(n); }
+ }
+ //console.log(nodes);
+ return nodes;
+ },
+
+ findOverlappingNodes: function(inNode){
+ return this._findOverlappingNodes(findTable(inNode), getTrIndex(inNode.parentNode), getTdIndex(inNode));
+ }
+ });
+
+ return {
+ _Builder: _Builder,
+ _HeaderBuilder: _HeaderBuilder,
+ _ContentBuilder: _ContentBuilder
+ };
+});
+},
+'dojo/dnd/Source':function(){
+define(["../main", "./Selector", "./Manager"], function(dojo, Selector, Manager) {
+ // module:
+ // dojo/dnd/Source
+ // summary:
+ // TODOC
+
+/*=====
+Selector = dojo.dnd.Selector;
+=====*/
+
+/*
+ Container property:
+ "Horizontal"- if this is the horizontal container
+ Source states:
+ "" - normal state
+ "Moved" - this source is being moved
+ "Copied" - this source is being copied
+ Target states:
+ "" - normal state
+ "Disabled" - the target cannot accept an avatar
+ Target anchor state:
+ "" - item is not selected
+ "Before" - insert point is before the anchor
+ "After" - insert point is after the anchor
+*/
+
+/*=====
+dojo.dnd.__SourceArgs = function(){
+ // summary:
+ // a dict of parameters for DnD Source configuration. Note that any
+ // property on Source elements may be configured, but this is the
+ // short-list
+ // isSource: Boolean?
+ // can be used as a DnD source. Defaults to true.
+ // accept: Array?
+ // list of accepted types (text strings) for a target; defaults to
+ // ["text"]
+ // autoSync: Boolean
+ // if true refreshes the node list on every operation; false by default
+ // copyOnly: Boolean?
+ // copy items, if true, use a state of Ctrl key otherwise,
+ // see selfCopy and selfAccept for more details
+ // delay: Number
+ // the move delay in pixels before detecting a drag; 0 by default
+ // horizontal: Boolean?
+ // a horizontal container, if true, vertical otherwise or when omitted
+ // selfCopy: Boolean?
+ // copy items by default when dropping on itself,
+ // false by default, works only if copyOnly is true
+ // selfAccept: Boolean?
+ // accept its own items when copyOnly is true,
+ // true by default, works only if copyOnly is true
+ // withHandles: Boolean?
+ // allows dragging only by handles, false by default
+ // generateText: Boolean?
+ // generate text node for drag and drop, true by default
+ this.isSource = isSource;
+ this.accept = accept;
+ this.autoSync = autoSync;
+ this.copyOnly = copyOnly;
+ this.delay = delay;
+ this.horizontal = horizontal;
+ this.selfCopy = selfCopy;
+ this.selfAccept = selfAccept;
+ this.withHandles = withHandles;
+ this.generateText = true;
+}
+=====*/
+
+// For back-compat, remove in 2.0.
+if(!dojo.isAsync){
+ dojo.ready(0, function(){
+ var requires = ["dojo/dnd/AutoSource", "dojo/dnd/Target"];
+ require(requires); // use indirection so modules not rolled into a build
+ })
+}
+
+return dojo.declare("dojo.dnd.Source", Selector, {
+ // summary:
+ // a Source object, which can be used as a DnD source, or a DnD target
+
+ // object attributes (for markup)
+ isSource: true,
+ horizontal: false,
+ copyOnly: false,
+ selfCopy: false,
+ selfAccept: true,
+ skipForm: false,
+ withHandles: false,
+ autoSync: false,
+ delay: 0, // pixels
+ accept: ["text"],
+ generateText: true,
+
+ constructor: function(/*DOMNode|String*/node, /*dojo.dnd.__SourceArgs?*/params){
+ // summary:
+ // a constructor of the Source
+ // node:
+ // node or node's id to build the source on
+ // params:
+ // any property of this class may be configured via the params
+ // object which is mixed-in to the `dojo.dnd.Source` instance
+ dojo.mixin(this, dojo.mixin({}, params));
+ var type = this.accept;
+ if(type.length){
+ this.accept = {};
+ for(var i = 0; i < type.length; ++i){
+ this.accept[type[i]] = 1;
+ }
+ }
+ // class-specific variables
+ this.isDragging = false;
+ this.mouseDown = false;
+ this.targetAnchor = null;
+ this.targetBox = null;
+ this.before = true;
+ this._lastX = 0;
+ this._lastY = 0;
+ // states
+ this.sourceState = "";
+ if(this.isSource){
+ dojo.addClass(this.node, "dojoDndSource");
+ }
+ this.targetState = "";
+ if(this.accept){
+ dojo.addClass(this.node, "dojoDndTarget");
+ }
+ if(this.horizontal){
+ dojo.addClass(this.node, "dojoDndHorizontal");
+ }
+ // set up events
+ this.topics = [
+ dojo.subscribe("/dnd/source/over", this, "onDndSourceOver"),
+ dojo.subscribe("/dnd/start", this, "onDndStart"),
+ dojo.subscribe("/dnd/drop", this, "onDndDrop"),
+ dojo.subscribe("/dnd/cancel", this, "onDndCancel")
+ ];
+ },
+
+ // methods
+ checkAcceptance: function(source, nodes){
+ // summary:
+ // checks if the target can accept nodes from this source
+ // source: Object
+ // the source which provides items
+ // nodes: Array
+ // the list of transferred items
+ if(this == source){
+ return !this.copyOnly || this.selfAccept;
+ }
+ for(var i = 0; i < nodes.length; ++i){
+ var type = source.getItem(nodes[i].id).type;
+ // type instanceof Array
+ var flag = false;
+ for(var j = 0; j < type.length; ++j){
+ if(type[j] in this.accept){
+ flag = true;
+ break;
+ }
+ }
+ if(!flag){
+ return false; // Boolean
+ }
+ }
+ return true; // Boolean
+ },
+ copyState: function(keyPressed, self){
+ // summary:
+ // Returns true if we need to copy items, false to move.
+ // It is separated to be overwritten dynamically, if needed.
+ // keyPressed: Boolean
+ // the "copy" key was pressed
+ // self: Boolean?
+ // optional flag that means that we are about to drop on itself
+
+ if(keyPressed){ return true; }
+ if(arguments.length < 2){
+ self = this == Manager.manager().target;
+ }
+ if(self){
+ if(this.copyOnly){
+ return this.selfCopy;
+ }
+ }else{
+ return this.copyOnly;
+ }
+ return false; // Boolean
+ },
+ destroy: function(){
+ // summary:
+ // prepares the object to be garbage-collected
+ dojo.dnd.Source.superclass.destroy.call(this);
+ dojo.forEach(this.topics, dojo.unsubscribe);
+ this.targetAnchor = null;
+ },
+
+ // mouse event processors
+ onMouseMove: function(e){
+ // summary:
+ // event processor for onmousemove
+ // e: Event
+ // mouse event
+ if(this.isDragging && this.targetState == "Disabled"){ return; }
+ dojo.dnd.Source.superclass.onMouseMove.call(this, e);
+ var m = Manager.manager();
+ if(!this.isDragging){
+ if(this.mouseDown && this.isSource &&
+ (Math.abs(e.pageX - this._lastX) > this.delay || Math.abs(e.pageY - this._lastY) > this.delay)){
+ var nodes = this.getSelectedNodes();
+ if(nodes.length){
+ m.startDrag(this, nodes, this.copyState(dojo.isCopyKey(e), true));
+ }
+ }
+ }
+ if(this.isDragging){
+ // calculate before/after
+ var before = false;
+ if(this.current){
+ if(!this.targetBox || this.targetAnchor != this.current){
+ this.targetBox = dojo.position(this.current, true);
+ }
+ if(this.horizontal){
+ before = (e.pageX - this.targetBox.x) < (this.targetBox.w / 2);
+ }else{
+ before = (e.pageY - this.targetBox.y) < (this.targetBox.h / 2);
+ }
+ }
+ if(this.current != this.targetAnchor || before != this.before){
+ this._markTargetAnchor(before);
+ m.canDrop(!this.current || m.source != this || !(this.current.id in this.selection));
+ }
+ }
+ },
+ onMouseDown: function(e){
+ // summary:
+ // event processor for onmousedown
+ // e: Event
+ // mouse event
+ if(!this.mouseDown && this._legalMouseDown(e) && (!this.skipForm || !dojo.dnd.isFormElement(e))){
+ this.mouseDown = true;
+ this._lastX = e.pageX;
+ this._lastY = e.pageY;
+ dojo.dnd.Source.superclass.onMouseDown.call(this, e);
+ }
+ },
+ onMouseUp: function(e){
+ // summary:
+ // event processor for onmouseup
+ // e: Event
+ // mouse event
+ if(this.mouseDown){
+ this.mouseDown = false;
+ dojo.dnd.Source.superclass.onMouseUp.call(this, e);
+ }
+ },
+
+ // topic event processors
+ onDndSourceOver: function(source){
+ // summary:
+ // topic event processor for /dnd/source/over, called when detected a current source
+ // source: Object
+ // the source which has the mouse over it
+ if(this != source){
+ this.mouseDown = false;
+ if(this.targetAnchor){
+ this._unmarkTargetAnchor();
+ }
+ }else if(this.isDragging){
+ var m = Manager.manager();
+ m.canDrop(this.targetState != "Disabled" && (!this.current || m.source != this || !(this.current.id in this.selection)));
+ }
+ },
+ onDndStart: function(source, nodes, copy){
+ // summary:
+ // topic event processor for /dnd/start, called to initiate the DnD operation
+ // source: Object
+ // the source which provides items
+ // nodes: Array
+ // the list of transferred items
+ // copy: Boolean
+ // copy items, if true, move items otherwise
+ if(this.autoSync){ this.sync(); }
+ if(this.isSource){
+ this._changeState("Source", this == source ? (copy ? "Copied" : "Moved") : "");
+ }
+ var accepted = this.accept && this.checkAcceptance(source, nodes);
+ this._changeState("Target", accepted ? "" : "Disabled");
+ if(this == source){
+ Manager.manager().overSource(this);
+ }
+ this.isDragging = true;
+ },
+ onDndDrop: function(source, nodes, copy, target){
+ // summary:
+ // topic event processor for /dnd/drop, called to finish the DnD operation
+ // source: Object
+ // the source which provides items
+ // nodes: Array
+ // the list of transferred items
+ // copy: Boolean
+ // copy items, if true, move items otherwise
+ // target: Object
+ // the target which accepts items
+ if(this == target){
+ // this one is for us => move nodes!
+ this.onDrop(source, nodes, copy);
+ }
+ this.onDndCancel();
+ },
+ onDndCancel: function(){
+ // summary:
+ // topic event processor for /dnd/cancel, called to cancel the DnD operation
+ if(this.targetAnchor){
+ this._unmarkTargetAnchor();
+ this.targetAnchor = null;
+ }
+ this.before = true;
+ this.isDragging = false;
+ this.mouseDown = false;
+ this._changeState("Source", "");
+ this._changeState("Target", "");
+ },
+
+ // local events
+ onDrop: function(source, nodes, copy){
+ // summary:
+ // called only on the current target, when drop is performed
+ // source: Object
+ // the source which provides items
+ // nodes: Array
+ // the list of transferred items
+ // copy: Boolean
+ // copy items, if true, move items otherwise
+
+ if(this != source){
+ this.onDropExternal(source, nodes, copy);
+ }else{
+ this.onDropInternal(nodes, copy);
+ }
+ },
+ onDropExternal: function(source, nodes, copy){
+ // summary:
+ // called only on the current target, when drop is performed
+ // from an external source
+ // source: Object
+ // the source which provides items
+ // nodes: Array
+ // the list of transferred items
+ // copy: Boolean
+ // copy items, if true, move items otherwise
+
+ var oldCreator = this._normalizedCreator;
+ // transferring nodes from the source to the target
+ if(this.creator){
+ // use defined creator
+ this._normalizedCreator = function(node, hint){
+ return oldCreator.call(this, source.getItem(node.id).data, hint);
+ };
+ }else{
+ // we have no creator defined => move/clone nodes
+ if(copy){
+ // clone nodes
+ this._normalizedCreator = function(node, hint){
+ var t = source.getItem(node.id);
+ var n = node.cloneNode(true);
+ n.id = dojo.dnd.getUniqueId();
+ return {node: n, data: t.data, type: t.type};
+ };
+ }else{
+ // move nodes
+ this._normalizedCreator = function(node, hint){
+ var t = source.getItem(node.id);
+ source.delItem(node.id);
+ return {node: node, data: t.data, type: t.type};
+ };
+ }
+ }
+ this.selectNone();
+ if(!copy && !this.creator){
+ source.selectNone();
+ }
+ this.insertNodes(true, nodes, this.before, this.current);
+ if(!copy && this.creator){
+ source.deleteSelectedNodes();
+ }
+ this._normalizedCreator = oldCreator;
+ },
+ onDropInternal: function(nodes, copy){
+ // summary:
+ // called only on the current target, when drop is performed
+ // from the same target/source
+ // nodes: Array
+ // the list of transferred items
+ // copy: Boolean
+ // copy items, if true, move items otherwise
+
+ var oldCreator = this._normalizedCreator;
+ // transferring nodes within the single source
+ if(this.current && this.current.id in this.selection){
+ // do nothing
+ return;
+ }
+ if(copy){
+ if(this.creator){
+ // create new copies of data items
+ this._normalizedCreator = function(node, hint){
+ return oldCreator.call(this, this.getItem(node.id).data, hint);
+ };
+ }else{
+ // clone nodes
+ this._normalizedCreator = function(node, hint){
+ var t = this.getItem(node.id);
+ var n = node.cloneNode(true);
+ n.id = dojo.dnd.getUniqueId();
+ return {node: n, data: t.data, type: t.type};
+ };
+ }
+ }else{
+ // move nodes
+ if(!this.current){
+ // do nothing
+ return;
+ }
+ this._normalizedCreator = function(node, hint){
+ var t = this.getItem(node.id);
+ return {node: node, data: t.data, type: t.type};
+ };
+ }
+ this._removeSelection();
+ this.insertNodes(true, nodes, this.before, this.current);
+ this._normalizedCreator = oldCreator;
+ },
+ onDraggingOver: function(){
+ // summary:
+ // called during the active DnD operation, when items
+ // are dragged over this target, and it is not disabled
+ },
+ onDraggingOut: function(){
+ // summary:
+ // called during the active DnD operation, when items
+ // are dragged away from this target, and it is not disabled
+ },
+
+ // utilities
+ onOverEvent: function(){
+ // summary:
+ // this function is called once, when mouse is over our container
+ dojo.dnd.Source.superclass.onOverEvent.call(this);
+ Manager.manager().overSource(this);
+ if(this.isDragging && this.targetState != "Disabled"){
+ this.onDraggingOver();
+ }
+ },
+ onOutEvent: function(){
+ // summary:
+ // this function is called once, when mouse is out of our container
+ dojo.dnd.Source.superclass.onOutEvent.call(this);
+ Manager.manager().outSource(this);
+ if(this.isDragging && this.targetState != "Disabled"){
+ this.onDraggingOut();
+ }
+ },
+ _markTargetAnchor: function(before){
+ // summary:
+ // assigns a class to the current target anchor based on "before" status
+ // before: Boolean
+ // insert before, if true, after otherwise
+ if(this.current == this.targetAnchor && this.before == before){ return; }
+ if(this.targetAnchor){
+ this._removeItemClass(this.targetAnchor, this.before ? "Before" : "After");
+ }
+ this.targetAnchor = this.current;
+ this.targetBox = null;
+ this.before = before;
+ if(this.targetAnchor){
+ this._addItemClass(this.targetAnchor, this.before ? "Before" : "After");
+ }
+ },
+ _unmarkTargetAnchor: function(){
+ // summary:
+ // removes a class of the current target anchor based on "before" status
+ if(!this.targetAnchor){ return; }
+ this._removeItemClass(this.targetAnchor, this.before ? "Before" : "After");
+ this.targetAnchor = null;
+ this.targetBox = null;
+ this.before = true;
+ },
+ _markDndStatus: function(copy){
+ // summary:
+ // changes source's state based on "copy" status
+ this._changeState("Source", copy ? "Copied" : "Moved");
+ },
+ _legalMouseDown: function(e){
+ // summary:
+ // checks if user clicked on "approved" items
+ // e: Event
+ // mouse event
+
+ // accept only the left mouse button
+ if(!dojo.mouseButtons.isLeft(e)){ return false; }
+
+ if(!this.withHandles){ return true; }
+
+ // check for handles
+ for(var node = e.target; node && node !== this.node; node = node.parentNode){
+ if(dojo.hasClass(node, "dojoDndHandle")){ return true; }
+ if(dojo.hasClass(node, "dojoDndItem") || dojo.hasClass(node, "dojoDndIgnore")){ break; }
+ }
+ return false; // Boolean
+ }
+});
+
+});
+
+},
+'dojox/grid/cells/_base':function(){
+define("dojox/grid/cells/_base", [
+ "dojo/_base/kernel",
+ "dojo/_base/declare",
+ "dojo/_base/lang",
+ "dojo/_base/event",
+ "dojo/_base/connect",
+ "dojo/_base/array",
+ "dojo/_base/sniff",
+ "dojo/dom",
+ "dojo/dom-attr",
+ "dojo/dom-construct",
+ "dijit/_Widget",
+ "../util"
+], function(dojo, declare, lang, event, connect, array, has, dom, domAttr, domConstruct, _Widget, util){
+
+ var _DeferredTextWidget = declare("dojox.grid._DeferredTextWidget", _Widget, {
+ deferred: null,
+ _destroyOnRemove: true,
+ postCreate: function(){
+ if(this.deferred){
+ this.deferred.addBoth(lang.hitch(this, function(text){
+ if(this.domNode){
+ this.domNode.innerHTML = text;
+ }
+ }));
+ }
+ }
+ });
+
+ var focusSelectNode = function(inNode){
+ try{
+ util.fire(inNode, "focus");
+ util.fire(inNode, "select");
+ }catch(e){// IE sux bad
+ }
+ };
+
+ var whenIdle = function(/*inContext, inMethod, args ...*/){
+ setTimeout(lang.hitch.apply(dojo, arguments), 0);
+ };
+
+ var BaseCell = declare("dojox.grid.cells._Base", null, {
+ // summary:
+ // Respresents a grid cell and contains information about column options and methods
+ // for retrieving cell related information.
+ // Each column in a grid layout has a cell object and most events and many methods
+ // provide access to these objects.
+ styles: '',
+ classes: '',
+ editable: false,
+ alwaysEditing: false,
+ formatter: null,
+ defaultValue: '...',
+ value: null,
+ hidden: false,
+ noresize: false,
+ draggable: true,
+ //private
+ _valueProp: "value",
+ _formatPending: false,
+
+ constructor: function(inProps){
+ this._props = inProps || {};
+ lang.mixin(this, inProps);
+ if(this.draggable === undefined){
+ this.draggable = true;
+ }
+ },
+
+ _defaultFormat: function(inValue, callArgs){
+ var s = this.grid.formatterScope || this;
+ var f = this.formatter;
+ if(f && s && typeof f == "string"){
+ f = this.formatter = s[f];
+ }
+ var v = (inValue != this.defaultValue && f) ? f.apply(s, callArgs) : inValue;
+ if(typeof v == "undefined"){
+ return this.defaultValue;
+ }
+ if(v && v.addBoth){
+ // Check if it's a deferred
+ v = new _DeferredTextWidget({deferred: v},
+ domConstruct.create("span", {innerHTML: this.defaultValue}));
+ }
+ if(v && v.declaredClass && v.startup){
+ return "<div class='dojoxGridStubNode' linkWidget='" +
+ v.id +
+ "' cellIdx='" +
+ this.index +
+ "'>" +
+ this.defaultValue +
+ "</div>";
+ }
+ return v;
+ },
+
+ // data source
+ format: function(inRowIndex, inItem){
+ // summary:
+ // provides the html for a given grid cell.
+ // inRowIndex: int
+ // grid row index
+ // returns: html for a given grid cell
+ var f, i=this.grid.edit.info, d=this.get ? this.get(inRowIndex, inItem) : (this.value || this.defaultValue);
+ d = (d && d.replace && this.grid.escapeHTMLInData) ? d.replace(/&/g, '&amp;').replace(/</g, '&lt;') : d;
+ if(this.editable && (this.alwaysEditing || (i.rowIndex==inRowIndex && i.cell==this))){
+ return this.formatEditing(d, inRowIndex);
+ }else{
+ return this._defaultFormat(d, [d, inRowIndex, this]);
+ }
+ },
+ formatEditing: function(inDatum, inRowIndex){
+ // summary:
+ // formats the cell for editing
+ // inDatum: anything
+ // cell data to edit
+ // inRowIndex: int
+ // grid row index
+ // returns: string of html to place in grid cell
+ },
+ // utility
+ getNode: function(inRowIndex){
+ // summary:
+ // gets the dom node for a given grid cell.
+ // inRowIndex: int
+ // grid row index
+ // returns: dom node for a given grid cell
+ return this.view.getCellNode(inRowIndex, this.index);
+ },
+ getHeaderNode: function(){
+ return this.view.getHeaderCellNode(this.index);
+ },
+ getEditNode: function(inRowIndex){
+ return (this.getNode(inRowIndex) || 0).firstChild || 0;
+ },
+ canResize: function(){
+ var uw = this.unitWidth;
+ return uw && (uw!=='auto');
+ },
+ isFlex: function(){
+ var uw = this.unitWidth;
+ return uw && lang.isString(uw) && (uw=='auto' || uw.slice(-1)=='%');
+ },
+ // edit support
+ applyEdit: function(inValue, inRowIndex){
+ this.grid.edit.applyCellEdit(inValue, this, inRowIndex);
+ },
+ cancelEdit: function(inRowIndex){
+ this.grid.doCancelEdit(inRowIndex);
+ },
+ _onEditBlur: function(inRowIndex){
+ if(this.grid.edit.isEditCell(inRowIndex, this.index)){
+ //console.log('editor onblur', e);
+ this.grid.edit.apply();
+ }
+ },
+ registerOnBlur: function(inNode, inRowIndex){
+ if(this.commitOnBlur){
+ connect.connect(inNode, "onblur", function(e){
+ // hack: if editor still thinks this editor is current some ms after it blurs, assume we've focused away from grid
+ setTimeout(lang.hitch(this, "_onEditBlur", inRowIndex), 250);
+ });
+ }
+ },
+ //protected
+ needFormatNode: function(inDatum, inRowIndex){
+ this._formatPending = true;
+ whenIdle(this, "_formatNode", inDatum, inRowIndex);
+ },
+ cancelFormatNode: function(){
+ this._formatPending = false;
+ },
+ //private
+ _formatNode: function(inDatum, inRowIndex){
+ if(this._formatPending){
+ this._formatPending = false;
+ // make cell selectable
+ if(!has("ie")){
+ dom.setSelectable(this.grid.domNode, true);
+ }
+ this.formatNode(this.getEditNode(inRowIndex), inDatum, inRowIndex);
+ }
+ },
+ //protected
+ formatNode: function(inNode, inDatum, inRowIndex){
+ // summary:
+ // format the editing dom node. Use when editor is a widget.
+ // inNode: dom node
+ // dom node for the editor
+ // inDatum: anything
+ // cell data to edit
+ // inRowIndex: int
+ // grid row index
+ if(has("ie")){
+ // IE sux bad
+ whenIdle(this, "focus", inRowIndex, inNode);
+ }else{
+ this.focus(inRowIndex, inNode);
+ }
+ },
+ dispatchEvent: function(m, e){
+ if(m in this){
+ return this[m](e);
+ }
+ },
+ //public
+ getValue: function(inRowIndex){
+ // summary:
+ // returns value entered into editor
+ // inRowIndex: int
+ // grid row index
+ // returns:
+ // value of editor
+ return this.getEditNode(inRowIndex)[this._valueProp];
+ },
+ setValue: function(inRowIndex, inValue){
+ // summary:
+ // set the value of the grid editor
+ // inRowIndex: int
+ // grid row index
+ // inValue: anything
+ // value of editor
+ var n = this.getEditNode(inRowIndex);
+ if(n){
+ n[this._valueProp] = inValue;
+ }
+ },
+ focus: function(inRowIndex, inNode){
+ // summary:
+ // focus the grid editor
+ // inRowIndex: int
+ // grid row index
+ // inNode: dom node
+ // editor node
+ focusSelectNode(inNode || this.getEditNode(inRowIndex));
+ },
+ save: function(inRowIndex){
+ // summary:
+ // save editor state
+ // inRowIndex: int
+ // grid row index
+ this.value = this.value || this.getValue(inRowIndex);
+ //console.log("save", this.value, inCell.index, inRowIndex);
+ },
+ restore: function(inRowIndex){
+ // summary:
+ // restore editor state
+ // inRowIndex: int
+ // grid row index
+ this.setValue(inRowIndex, this.value);
+ //console.log("restore", this.value, inCell.index, inRowIndex);
+ },
+ //protected
+ _finish: function(inRowIndex){
+ // summary:
+ // called when editing is completed to clean up editor
+ // inRowIndex: int
+ // grid row index
+ dom.setSelectable(this.grid.domNode, false);
+ this.cancelFormatNode();
+ },
+ //public
+ apply: function(inRowIndex){
+ // summary:
+ // apply edit from cell editor
+ // inRowIndex: int
+ // grid row index
+ this.applyEdit(this.getValue(inRowIndex), inRowIndex);
+ this._finish(inRowIndex);
+ },
+ cancel: function(inRowIndex){
+ // summary:
+ // cancel cell edit
+ // inRowIndex: int
+ // grid row index
+ this.cancelEdit(inRowIndex);
+ this._finish(inRowIndex);
+ }
+ });
+ BaseCell.markupFactory = function(node, cellDef){
+ var formatter = lang.trim(domAttr.get(node, "formatter")||"");
+ if(formatter){
+ cellDef.formatter = lang.getObject(formatter)||formatter;
+ }
+ var get = lang.trim(domAttr.get(node, "get")||"");
+ if(get){
+ cellDef.get = lang.getObject(get);
+ }
+ var getBoolAttr = function(attr, cell, cellAttr){
+ var value = lang.trim(domAttr.get(node, attr)||"");
+ if(value){ cell[cellAttr||attr] = !(value.toLowerCase()=="false"); }
+ };
+ getBoolAttr("sortDesc", cellDef);
+ getBoolAttr("editable", cellDef);
+ getBoolAttr("alwaysEditing", cellDef);
+ getBoolAttr("noresize", cellDef);
+ getBoolAttr("draggable", cellDef);
+
+ var value = lang.trim(domAttr.get(node, "loadingText")||domAttr.get(node, "defaultValue")||"");
+ if(value){
+ cellDef.defaultValue = value;
+ }
+
+ var getStrAttr = function(attr, cell, cellAttr){
+ var value = lang.trim(domAttr.get(node, attr)||"")||undefined;
+ if(value){ cell[cellAttr||attr] = value; }
+ };
+ getStrAttr("styles", cellDef);
+ getStrAttr("headerStyles", cellDef);
+ getStrAttr("cellStyles", cellDef);
+ getStrAttr("classes", cellDef);
+ getStrAttr("headerClasses", cellDef);
+ getStrAttr("cellClasses", cellDef);
+ };
+
+ var Cell = declare("dojox.grid.cells.Cell", BaseCell, {
+ // summary
+ // grid cell that provides a standard text input box upon editing
+ constructor: function(){
+ this.keyFilter = this.keyFilter;
+ },
+ // keyFilter: RegExp
+ // optional regex for disallowing keypresses
+ keyFilter: null,
+ formatEditing: function(inDatum, inRowIndex){
+ this.needFormatNode(inDatum, inRowIndex);
+ return '<input class="dojoxGridInput" type="text" value="' + inDatum + '">';
+ },
+ formatNode: function(inNode, inDatum, inRowIndex){
+ this.inherited(arguments);
+ // FIXME: feels too specific for this interface
+ this.registerOnBlur(inNode, inRowIndex);
+ },
+ doKey: function(e){
+ if(this.keyFilter){
+ var key = String.fromCharCode(e.charCode);
+ if(key.search(this.keyFilter) == -1){
+ event.stop(e);
+ }
+ }
+ },
+ _finish: function(inRowIndex){
+ this.inherited(arguments);
+ var n = this.getEditNode(inRowIndex);
+ try{
+ util.fire(n, "blur");
+ }catch(e){}
+ }
+ });
+ Cell.markupFactory = function(node, cellDef){
+ BaseCell.markupFactory(node, cellDef);
+ var keyFilter = lang.trim(domAttr.get(node, "keyFilter")||"");
+ if(keyFilter){
+ cellDef.keyFilter = new RegExp(keyFilter);
+ }
+ };
+
+ var RowIndex = declare("dojox.grid.cells.RowIndex", Cell, {
+ name: 'Row',
+
+ postscript: function(){
+ this.editable = false;
+ },
+ get: function(inRowIndex){
+ return inRowIndex + 1;
+ }
+ });
+ RowIndex.markupFactory = function(node, cellDef){
+ Cell.markupFactory(node, cellDef);
+ };
+
+ var Select = declare("dojox.grid.cells.Select", Cell, {
+ // summary:
+ // grid cell that provides a standard select for editing
+
+ // options: Array
+ // text of each item
+ options: null,
+
+ // values: Array
+ // value for each item
+ values: null,
+
+ // returnIndex: Integer
+ // editor returns only the index of the selected option and not the value
+ returnIndex: -1,
+
+ constructor: function(inCell){
+ this.values = this.values || this.options;
+ },
+ formatEditing: function(inDatum, inRowIndex){
+ this.needFormatNode(inDatum, inRowIndex);
+ var h = [ '<select class="dojoxGridSelect">' ];
+ for (var i=0, o, v; ((o=this.options[i]) !== undefined)&&((v=this.values[i]) !== undefined); i++){
+ v = v.replace ? v.replace(/&/g, '&amp;').replace(/</g, '&lt;') : v;
+ o = o.replace ? o.replace(/&/g, '&amp;').replace(/</g, '&lt;') : o;
+ h.push("<option", (inDatum==v ? ' selected' : ''), ' value="' + v + '"', ">", o, "</option>");
+ }
+ h.push('</select>');
+ return h.join('');
+ },
+ _defaultFormat: function(inValue, callArgs){
+ var v = this.inherited(arguments);
+ // when 'values' and 'options' both provided and there is no cutomized formatter,
+ // then we use 'options' as label in order to be consistent
+ if(!this.formatter && this.values && this.options){
+ var i = array.indexOf(this.values, v);
+ if(i >= 0){
+ v = this.options[i];
+ }
+ }
+ return v;
+ },
+ getValue: function(inRowIndex){
+ var n = this.getEditNode(inRowIndex);
+ if(n){
+ var i = n.selectedIndex, o = n.options[i];
+ return this.returnIndex > -1 ? i : o.value || o.innerHTML;
+ }
+ }
+ });
+ Select.markupFactory = function(node, cell){
+ Cell.markupFactory(node, cell);
+ var options = lang.trim(domAttr.get(node, "options")||"");
+ if(options){
+ var o = options.split(',');
+ if(o[0] != options){
+ cell.options = o;
+ }
+ }
+ var values = lang.trim(domAttr.get(node, "values")||"");
+ if(values){
+ var v = values.split(',');
+ if(v[0] != values){
+ cell.values = v;
+ }
+ }
+ };
+
+ var AlwaysEdit = declare("dojox.grid.cells.AlwaysEdit", Cell, {
+ // summary:
+ // grid cell that is always in an editable state, regardless of grid editing state
+ alwaysEditing: true,
+ _formatNode: function(inDatum, inRowIndex){
+ this.formatNode(this.getEditNode(inRowIndex), inDatum, inRowIndex);
+ },
+ applyStaticValue: function(inRowIndex){
+ var e = this.grid.edit;
+ e.applyCellEdit(this.getValue(inRowIndex), this, inRowIndex);
+ e.start(this, inRowIndex, true);
+ }
+ });
+ AlwaysEdit.markupFactory = function(node, cell){
+ Cell.markupFactory(node, cell);
+ };
+
+ var Bool = declare("dojox.grid.cells.Bool", AlwaysEdit, {
+ // summary:
+ // grid cell that provides a standard checkbox that is always on for editing
+ _valueProp: "checked",
+ formatEditing: function(inDatum, inRowIndex){
+ return '<input class="dojoxGridInput" type="checkbox"' + (inDatum ? ' checked="checked"' : '') + ' style="width: auto" />';
+ },
+ doclick: function(e){
+ if(e.target.tagName == 'INPUT'){
+ this.applyStaticValue(e.rowIndex);
+ }
+ }
+ });
+ Bool.markupFactory = function(node, cell){
+ AlwaysEdit.markupFactory(node, cell);
+ };
+
+ return BaseCell;
+
+});
+},
+'dijit/_WidgetBase':function(){
+define("dijit/_WidgetBase", [
+ "require", // require.toUrl
+ "dojo/_base/array", // array.forEach array.map
+ "dojo/aspect",
+ "dojo/_base/config", // config.blankGif
+ "dojo/_base/connect", // connect.connect
+ "dojo/_base/declare", // declare
+ "dojo/dom", // dom.byId
+ "dojo/dom-attr", // domAttr.set domAttr.remove
+ "dojo/dom-class", // domClass.add domClass.replace
+ "dojo/dom-construct", // domConstruct.create domConstruct.destroy domConstruct.place
+ "dojo/dom-geometry", // isBodyLtr
+ "dojo/dom-style", // domStyle.set, domStyle.get
+ "dojo/_base/kernel",
+ "dojo/_base/lang", // mixin(), isArray(), etc.
+ "dojo/on",
+ "dojo/ready",
+ "dojo/Stateful", // Stateful
+ "dojo/topic",
+ "dojo/_base/window", // win.doc.createTextNode
+ "./registry" // registry.getUniqueId(), registry.findWidgets()
+], function(require, array, aspect, config, connect, declare,
+ dom, domAttr, domClass, domConstruct, domGeometry, domStyle, kernel,
+ lang, on, ready, Stateful, topic, win, registry){
+
+/*=====
+var Stateful = dojo.Stateful;
+=====*/
+
+// module:
+// dijit/_WidgetBase
+// summary:
+// Future base class for all Dijit widgets.
+
+// For back-compat, remove in 2.0.
+if(!kernel.isAsync){
+ ready(0, function(){
+ var requires = ["dijit/_base/manager"];
+ require(requires); // use indirection so modules not rolled into a build
+ });
+}
+
+// Nested hash listing attributes for each tag, all strings in lowercase.
+// ex: {"div": {"style": true, "tabindex" true}, "form": { ...
+var tagAttrs = {};
+function getAttrs(obj){
+ var ret = {};
+ for(var attr in obj){
+ ret[attr.toLowerCase()] = true;
+ }
+ return ret;
+}
+
+function nonEmptyAttrToDom(attr){
+ // summary:
+ // Returns a setter function that copies the attribute to this.domNode,
+ // or removes the attribute from this.domNode, depending on whether the
+ // value is defined or not.
+ return function(val){
+ domAttr[val ? "set" : "remove"](this.domNode, attr, val);
+ this._set(attr, val);
+ };
+}
+
+return declare("dijit._WidgetBase", Stateful, {
+ // summary:
+ // Future base class for all Dijit widgets.
+ // description:
+ // Future base class for all Dijit widgets.
+ // _Widget extends this class adding support for various features needed by desktop.
+ //
+ // Provides stubs for widget lifecycle methods for subclasses to extend, like postMixInProperties(), buildRendering(),
+ // postCreate(), startup(), and destroy(), and also public API methods like set(), get(), and watch().
+ //
+ // Widgets can provide custom setters/getters for widget attributes, which are called automatically by set(name, value).
+ // For an attribute XXX, define methods _setXXXAttr() and/or _getXXXAttr().
+ //
+ // _setXXXAttr can also be a string/hash/array mapping from a widget attribute XXX to the widget's DOMNodes:
+ //
+ // - DOM node attribute
+ // | _setFocusAttr: {node: "focusNode", type: "attribute"}
+ // | _setFocusAttr: "focusNode" (shorthand)
+ // | _setFocusAttr: "" (shorthand, maps to this.domNode)
+ // Maps this.focus to this.focusNode.focus, or (last example) this.domNode.focus
+ //
+ // - DOM node innerHTML
+ // | _setTitleAttr: { node: "titleNode", type: "innerHTML" }
+ // Maps this.title to this.titleNode.innerHTML
+ //
+ // - DOM node innerText
+ // | _setTitleAttr: { node: "titleNode", type: "innerText" }
+ // Maps this.title to this.titleNode.innerText
+ //
+ // - DOM node CSS class
+ // | _setMyClassAttr: { node: "domNode", type: "class" }
+ // Maps this.myClass to this.domNode.className
+ //
+ // If the value of _setXXXAttr is an array, then each element in the array matches one of the
+ // formats of the above list.
+ //
+ // If the custom setter is null, no action is performed other than saving the new value
+ // in the widget (in this).
+ //
+ // If no custom setter is defined for an attribute, then it will be copied
+ // to this.focusNode (if the widget defines a focusNode), or this.domNode otherwise.
+ // That's only done though for attributes that match DOMNode attributes (title,
+ // alt, aria-labelledby, etc.)
+
+ // id: [const] String
+ // A unique, opaque ID string that can be assigned by users or by the
+ // system. If the developer passes an ID which is known not to be
+ // unique, the specified ID is ignored and the system-generated ID is
+ // used instead.
+ id: "",
+ _setIdAttr: "domNode", // to copy to this.domNode even for auto-generated id's
+
+ // lang: [const] String
+ // Rarely used. Overrides the default Dojo locale used to render this widget,
+ // as defined by the [HTML LANG](http://www.w3.org/TR/html401/struct/dirlang.html#adef-lang) attribute.
+ // Value must be among the list of locales specified during by the Dojo bootstrap,
+ // formatted according to [RFC 3066](http://www.ietf.org/rfc/rfc3066.txt) (like en-us).
+ lang: "",
+ // set on domNode even when there's a focus node. but don't set lang="", since that's invalid.
+ _setLangAttr: nonEmptyAttrToDom("lang"),
+
+ // dir: [const] String
+ // Bi-directional support, as defined by the [HTML DIR](http://www.w3.org/TR/html401/struct/dirlang.html#adef-dir)
+ // attribute. Either left-to-right "ltr" or right-to-left "rtl". If undefined, widgets renders in page's
+ // default direction.
+ dir: "",
+ // set on domNode even when there's a focus node. but don't set dir="", since that's invalid.
+ _setDirAttr: nonEmptyAttrToDom("dir"), // to set on domNode even when there's a focus node
+
+ // textDir: String
+ // Bi-directional support, the main variable which is responsible for the direction of the text.
+ // The text direction can be different than the GUI direction by using this parameter in creation
+ // of a widget.
+ // Allowed values:
+ // 1. "ltr"
+ // 2. "rtl"
+ // 3. "auto" - contextual the direction of a text defined by first strong letter.
+ // By default is as the page direction.
+ textDir: "",
+
+ // class: String
+ // HTML class attribute
+ "class": "",
+ _setClassAttr: { node: "domNode", type: "class" },
+
+ // style: String||Object
+ // HTML style attributes as cssText string or name/value hash
+ style: "",
+
+ // title: String
+ // HTML title attribute.
+ //
+ // For form widgets this specifies a tooltip to display when hovering over
+ // the widget (just like the native HTML title attribute).
+ //
+ // For TitlePane or for when this widget is a child of a TabContainer, AccordionContainer,
+ // etc., it's used to specify the tab label, accordion pane title, etc.
+ title: "",
+
+ // tooltip: String
+ // When this widget's title attribute is used to for a tab label, accordion pane title, etc.,
+ // this specifies the tooltip to appear when the mouse is hovered over that text.
+ tooltip: "",
+
+ // baseClass: [protected] String
+ // Root CSS class of the widget (ex: dijitTextBox), used to construct CSS classes to indicate
+ // widget state.
+ baseClass: "",
+
+ // srcNodeRef: [readonly] DomNode
+ // pointer to original DOM node
+ srcNodeRef: null,
+
+ // domNode: [readonly] DomNode
+ // This is our visible representation of the widget! Other DOM
+ // Nodes may by assigned to other properties, usually through the
+ // template system's data-dojo-attach-point syntax, but the domNode
+ // property is the canonical "top level" node in widget UI.
+ domNode: null,
+
+ // containerNode: [readonly] DomNode
+ // Designates where children of the source DOM node will be placed.
+ // "Children" in this case refers to both DOM nodes and widgets.
+ // For example, for myWidget:
+ //
+ // | <div data-dojo-type=myWidget>
+ // | <b> here's a plain DOM node
+ // | <span data-dojo-type=subWidget>and a widget</span>
+ // | <i> and another plain DOM node </i>
+ // | </div>
+ //
+ // containerNode would point to:
+ //
+ // | <b> here's a plain DOM node
+ // | <span data-dojo-type=subWidget>and a widget</span>
+ // | <i> and another plain DOM node </i>
+ //
+ // In templated widgets, "containerNode" is set via a
+ // data-dojo-attach-point assignment.
+ //
+ // containerNode must be defined for any widget that accepts innerHTML
+ // (like ContentPane or BorderContainer or even Button), and conversely
+ // is null for widgets that don't, like TextBox.
+ containerNode: null,
+
+/*=====
+ // _started: Boolean
+ // startup() has completed.
+ _started: false,
+=====*/
+
+ // attributeMap: [protected] Object
+ // Deprecated. Instead of attributeMap, widget should have a _setXXXAttr attribute
+ // for each XXX attribute to be mapped to the DOM.
+ //
+ // attributeMap sets up a "binding" between attributes (aka properties)
+ // of the widget and the widget's DOM.
+ // Changes to widget attributes listed in attributeMap will be
+ // reflected into the DOM.
+ //
+ // For example, calling set('title', 'hello')
+ // on a TitlePane will automatically cause the TitlePane's DOM to update
+ // with the new title.
+ //
+ // attributeMap is a hash where the key is an attribute of the widget,
+ // and the value reflects a binding to a:
+ //
+ // - DOM node attribute
+ // | focus: {node: "focusNode", type: "attribute"}
+ // Maps this.focus to this.focusNode.focus
+ //
+ // - DOM node innerHTML
+ // | title: { node: "titleNode", type: "innerHTML" }
+ // Maps this.title to this.titleNode.innerHTML
+ //
+ // - DOM node innerText
+ // | title: { node: "titleNode", type: "innerText" }
+ // Maps this.title to this.titleNode.innerText
+ //
+ // - DOM node CSS class
+ // | myClass: { node: "domNode", type: "class" }
+ // Maps this.myClass to this.domNode.className
+ //
+ // If the value is an array, then each element in the array matches one of the
+ // formats of the above list.
+ //
+ // There are also some shorthands for backwards compatibility:
+ // - string --> { node: string, type: "attribute" }, for example:
+ // | "focusNode" ---> { node: "focusNode", type: "attribute" }
+ // - "" --> { node: "domNode", type: "attribute" }
+ attributeMap: {},
+
+ // _blankGif: [protected] String
+ // Path to a blank 1x1 image.
+ // Used by <img> nodes in templates that really get their image via CSS background-image.
+ _blankGif: config.blankGif || require.toUrl("dojo/resources/blank.gif"),
+
+ //////////// INITIALIZATION METHODS ///////////////////////////////////////
+
+ postscript: function(/*Object?*/params, /*DomNode|String*/srcNodeRef){
+ // summary:
+ // Kicks off widget instantiation. See create() for details.
+ // tags:
+ // private
+ this.create(params, srcNodeRef);
+ },
+
+ create: function(/*Object?*/params, /*DomNode|String?*/srcNodeRef){
+ // summary:
+ // Kick off the life-cycle of a widget
+ // params:
+ // Hash of initialization parameters for widget, including
+ // scalar values (like title, duration etc.) and functions,
+ // typically callbacks like onClick.
+ // srcNodeRef:
+ // If a srcNodeRef (DOM node) is specified:
+ // - use srcNodeRef.innerHTML as my contents
+ // - if this is a behavioral widget then apply behavior
+ // to that srcNodeRef
+ // - otherwise, replace srcNodeRef with my generated DOM
+ // tree
+ // description:
+ // Create calls a number of widget methods (postMixInProperties, buildRendering, postCreate,
+ // etc.), some of which of you'll want to override. See http://dojotoolkit.org/reference-guide/dijit/_WidgetBase.html
+ // for a discussion of the widget creation lifecycle.
+ //
+ // Of course, adventurous developers could override create entirely, but this should
+ // only be done as a last resort.
+ // tags:
+ // private
+
+ // store pointer to original DOM tree
+ this.srcNodeRef = dom.byId(srcNodeRef);
+
+ // For garbage collection. An array of listener handles returned by this.connect() / this.subscribe()
+ this._connects = [];
+
+ // For widgets internal to this widget, invisible to calling code
+ this._supportingWidgets = [];
+
+ // this is here for back-compat, remove in 2.0 (but check NodeList-instantiate.html test)
+ if(this.srcNodeRef && (typeof this.srcNodeRef.id == "string")){ this.id = this.srcNodeRef.id; }
+
+ // mix in our passed parameters
+ if(params){
+ this.params = params;
+ lang.mixin(this, params);
+ }
+ this.postMixInProperties();
+
+ // generate an id for the widget if one wasn't specified
+ // (be sure to do this before buildRendering() because that function might
+ // expect the id to be there.)
+ if(!this.id){
+ this.id = registry.getUniqueId(this.declaredClass.replace(/\./g,"_"));
+ }
+ registry.add(this);
+
+ this.buildRendering();
+
+ if(this.domNode){
+ // Copy attributes listed in attributeMap into the [newly created] DOM for the widget.
+ // Also calls custom setters for all attributes with custom setters.
+ this._applyAttributes();
+
+ // If srcNodeRef was specified, then swap out original srcNode for this widget's DOM tree.
+ // For 2.0, move this after postCreate(). postCreate() shouldn't depend on the
+ // widget being attached to the DOM since it isn't when a widget is created programmatically like
+ // new MyWidget({}). See #11635.
+ var source = this.srcNodeRef;
+ if(source && source.parentNode && this.domNode !== source){
+ source.parentNode.replaceChild(this.domNode, source);
+ }
+ }
+
+ if(this.domNode){
+ // Note: for 2.0 may want to rename widgetId to dojo._scopeName + "_widgetId",
+ // assuming that dojo._scopeName even exists in 2.0
+ this.domNode.setAttribute("widgetId", this.id);
+ }
+ this.postCreate();
+
+ // If srcNodeRef has been processed and removed from the DOM (e.g. TemplatedWidget) then delete it to allow GC.
+ if(this.srcNodeRef && !this.srcNodeRef.parentNode){
+ delete this.srcNodeRef;
+ }
+
+ this._created = true;
+ },
+
+ _applyAttributes: function(){
+ // summary:
+ // Step during widget creation to copy widget attributes to the
+ // DOM according to attributeMap and _setXXXAttr objects, and also to call
+ // custom _setXXXAttr() methods.
+ //
+ // Skips over blank/false attribute values, unless they were explicitly specified
+ // as parameters to the widget, since those are the default anyway,
+ // and setting tabIndex="" is different than not setting tabIndex at all.
+ //
+ // For backwards-compatibility reasons attributeMap overrides _setXXXAttr when
+ // _setXXXAttr is a hash/string/array, but _setXXXAttr as a functions override attributeMap.
+ // tags:
+ // private
+
+ // Get list of attributes where this.set(name, value) will do something beyond
+ // setting this[name] = value. Specifically, attributes that have:
+ // - associated _setXXXAttr() method/hash/string/array
+ // - entries in attributeMap.
+ var ctor = this.constructor,
+ list = ctor._setterAttrs;
+ if(!list){
+ list = (ctor._setterAttrs = []);
+ for(var attr in this.attributeMap){
+ list.push(attr);
+ }
+
+ var proto = ctor.prototype;
+ for(var fxName in proto){
+ if(fxName in this.attributeMap){ continue; }
+ var setterName = "_set" + fxName.replace(/^[a-z]|-[a-zA-Z]/g, function(c){ return c.charAt(c.length-1).toUpperCase(); }) + "Attr";
+ if(setterName in proto){
+ list.push(fxName);
+ }
+ }
+ }
+
+ // Call this.set() for each attribute that was either specified as parameter to constructor,
+ // or was found above and has a default non-null value. For correlated attributes like value and displayedValue, the one
+ // specified as a parameter should take precedence, so apply attributes in this.params last.
+ // Particularly important for new DateTextBox({displayedValue: ...}) since DateTextBox's default value is
+ // NaN and thus is not ignored like a default value of "".
+ array.forEach(list, function(attr){
+ if(this.params && attr in this.params){
+ // skip this one, do it below
+ }else if(this[attr]){
+ this.set(attr, this[attr]);
+ }
+ }, this);
+ for(var param in this.params){
+ this.set(param, this[param]);
+ }
+ },
+
+ postMixInProperties: function(){
+ // summary:
+ // Called after the parameters to the widget have been read-in,
+ // but before the widget template is instantiated. Especially
+ // useful to set properties that are referenced in the widget
+ // template.
+ // tags:
+ // protected
+ },
+
+ buildRendering: function(){
+ // summary:
+ // Construct the UI for this widget, setting this.domNode.
+ // Most widgets will mixin `dijit._TemplatedMixin`, which implements this method.
+ // tags:
+ // protected
+
+ if(!this.domNode){
+ // Create root node if it wasn't created by _Templated
+ this.domNode = this.srcNodeRef || domConstruct.create('div');
+ }
+
+ // baseClass is a single class name or occasionally a space-separated list of names.
+ // Add those classes to the DOMNode. If RTL mode then also add with Rtl suffix.
+ // TODO: make baseClass custom setter
+ if(this.baseClass){
+ var classes = this.baseClass.split(" ");
+ if(!this.isLeftToRight()){
+ classes = classes.concat( array.map(classes, function(name){ return name+"Rtl"; }));
+ }
+ domClass.add(this.domNode, classes);
+ }
+ },
+
+ postCreate: function(){
+ // summary:
+ // Processing after the DOM fragment is created
+ // description:
+ // Called after the DOM fragment has been created, but not necessarily
+ // added to the document. Do not include any operations which rely on
+ // node dimensions or placement.
+ // tags:
+ // protected
+ },
+
+ startup: function(){
+ // summary:
+ // Processing after the DOM fragment is added to the document
+ // description:
+ // Called after a widget and its children have been created and added to the page,
+ // and all related widgets have finished their create() cycle, up through postCreate().
+ // This is useful for composite widgets that need to control or layout sub-widgets.
+ // Many layout widgets can use this as a wiring phase.
+ if(this._started){ return; }
+ this._started = true;
+ array.forEach(this.getChildren(), function(obj){
+ if(!obj._started && !obj._destroyed && lang.isFunction(obj.startup)){
+ obj.startup();
+ obj._started = true;
+ }
+ });
+ },
+
+ //////////// DESTROY FUNCTIONS ////////////////////////////////
+
+ destroyRecursive: function(/*Boolean?*/ preserveDom){
+ // summary:
+ // Destroy this widget and its descendants
+ // description:
+ // This is the generic "destructor" function that all widget users
+ // should call to cleanly discard with a widget. Once a widget is
+ // destroyed, it is removed from the manager object.
+ // preserveDom:
+ // If true, this method will leave the original DOM structure
+ // alone of descendant Widgets. Note: This will NOT work with
+ // dijit._Templated widgets.
+
+ this._beingDestroyed = true;
+ this.destroyDescendants(preserveDom);
+ this.destroy(preserveDom);
+ },
+
+ destroy: function(/*Boolean*/ preserveDom){
+ // summary:
+ // Destroy this widget, but not its descendants.
+ // This method will, however, destroy internal widgets such as those used within a template.
+ // preserveDom: Boolean
+ // If true, this method will leave the original DOM structure alone.
+ // Note: This will not yet work with _Templated widgets
+
+ this._beingDestroyed = true;
+ this.uninitialize();
+
+ // remove this.connect() and this.subscribe() listeners
+ var c;
+ while(c = this._connects.pop()){
+ c.remove();
+ }
+
+ // destroy widgets created as part of template, etc.
+ var w;
+ while(w = this._supportingWidgets.pop()){
+ if(w.destroyRecursive){
+ w.destroyRecursive();
+ }else if(w.destroy){
+ w.destroy();
+ }
+ }
+
+ this.destroyRendering(preserveDom);
+ registry.remove(this.id);
+ this._destroyed = true;
+ },
+
+ destroyRendering: function(/*Boolean?*/ preserveDom){
+ // summary:
+ // Destroys the DOM nodes associated with this widget
+ // preserveDom:
+ // If true, this method will leave the original DOM structure alone
+ // during tear-down. Note: this will not work with _Templated
+ // widgets yet.
+ // tags:
+ // protected
+
+ if(this.bgIframe){
+ this.bgIframe.destroy(preserveDom);
+ delete this.bgIframe;
+ }
+
+ if(this.domNode){
+ if(preserveDom){
+ domAttr.remove(this.domNode, "widgetId");
+ }else{
+ domConstruct.destroy(this.domNode);
+ }
+ delete this.domNode;
+ }
+
+ if(this.srcNodeRef){
+ if(!preserveDom){
+ domConstruct.destroy(this.srcNodeRef);
+ }
+ delete this.srcNodeRef;
+ }
+ },
+
+ destroyDescendants: function(/*Boolean?*/ preserveDom){
+ // summary:
+ // Recursively destroy the children of this widget and their
+ // descendants.
+ // preserveDom:
+ // If true, the preserveDom attribute is passed to all descendant
+ // widget's .destroy() method. Not for use with _Templated
+ // widgets.
+
+ // get all direct descendants and destroy them recursively
+ array.forEach(this.getChildren(), function(widget){
+ if(widget.destroyRecursive){
+ widget.destroyRecursive(preserveDom);
+ }
+ });
+ },
+
+ uninitialize: function(){
+ // summary:
+ // Stub function. Override to implement custom widget tear-down
+ // behavior.
+ // tags:
+ // protected
+ return false;
+ },
+
+ ////////////////// GET/SET, CUSTOM SETTERS, ETC. ///////////////////
+
+ _setStyleAttr: function(/*String||Object*/ value){
+ // summary:
+ // Sets the style attribute of the widget according to value,
+ // which is either a hash like {height: "5px", width: "3px"}
+ // or a plain string
+ // description:
+ // Determines which node to set the style on based on style setting
+ // in attributeMap.
+ // tags:
+ // protected
+
+ var mapNode = this.domNode;
+
+ // Note: technically we should revert any style setting made in a previous call
+ // to his method, but that's difficult to keep track of.
+
+ if(lang.isObject(value)){
+ domStyle.set(mapNode, value);
+ }else{
+ if(mapNode.style.cssText){
+ mapNode.style.cssText += "; " + value;
+ }else{
+ mapNode.style.cssText = value;
+ }
+ }
+
+ this._set("style", value);
+ },
+
+ _attrToDom: function(/*String*/ attr, /*String*/ value, /*Object?*/ commands){
+ // summary:
+ // Reflect a widget attribute (title, tabIndex, duration etc.) to
+ // the widget DOM, as specified by commands parameter.
+ // If commands isn't specified then it's looked up from attributeMap.
+ // Note some attributes like "type"
+ // cannot be processed this way as they are not mutable.
+ //
+ // tags:
+ // private
+
+ commands = arguments.length >= 3 ? commands : this.attributeMap[attr];
+
+ array.forEach(lang.isArray(commands) ? commands : [commands], function(command){
+
+ // Get target node and what we are doing to that node
+ var mapNode = this[command.node || command || "domNode"]; // DOM node
+ var type = command.type || "attribute"; // class, innerHTML, innerText, or attribute
+
+ switch(type){
+ case "attribute":
+ if(lang.isFunction(value)){ // functions execute in the context of the widget
+ value = lang.hitch(this, value);
+ }
+
+ // Get the name of the DOM node attribute; usually it's the same
+ // as the name of the attribute in the widget (attr), but can be overridden.
+ // Also maps handler names to lowercase, like onSubmit --> onsubmit
+ var attrName = command.attribute ? command.attribute :
+ (/^on[A-Z][a-zA-Z]*$/.test(attr) ? attr.toLowerCase() : attr);
+
+ domAttr.set(mapNode, attrName, value);
+ break;
+ case "innerText":
+ mapNode.innerHTML = "";
+ mapNode.appendChild(win.doc.createTextNode(value));
+ break;
+ case "innerHTML":
+ mapNode.innerHTML = value;
+ break;
+ case "class":
+ domClass.replace(mapNode, value, this[attr]);
+ break;
+ }
+ }, this);
+ },
+
+ get: function(name){
+ // summary:
+ // Get a property from a widget.
+ // name:
+ // The property to get.
+ // description:
+ // Get a named property from a widget. The property may
+ // potentially be retrieved via a getter method. If no getter is defined, this
+ // just retrieves the object's property.
+ //
+ // For example, if the widget has properties `foo` and `bar`
+ // and a method named `_getFooAttr()`, calling:
+ // `myWidget.get("foo")` would be equivalent to calling
+ // `widget._getFooAttr()` and `myWidget.get("bar")`
+ // would be equivalent to the expression
+ // `widget.bar2`
+ var names = this._getAttrNames(name);
+ return this[names.g] ? this[names.g]() : this[name];
+ },
+
+ set: function(name, value){
+ // summary:
+ // Set a property on a widget
+ // name:
+ // The property to set.
+ // value:
+ // The value to set in the property.
+ // description:
+ // Sets named properties on a widget which may potentially be handled by a
+ // setter in the widget.
+ //
+ // For example, if the widget has properties `foo` and `bar`
+ // and a method named `_setFooAttr()`, calling
+ // `myWidget.set("foo", "Howdy!")` would be equivalent to calling
+ // `widget._setFooAttr("Howdy!")` and `myWidget.set("bar", 3)`
+ // would be equivalent to the statement `widget.bar = 3;`
+ //
+ // set() may also be called with a hash of name/value pairs, ex:
+ //
+ // | myWidget.set({
+ // | foo: "Howdy",
+ // | bar: 3
+ // | });
+ //
+ // This is equivalent to calling `set(foo, "Howdy")` and `set(bar, 3)`
+
+ if(typeof name === "object"){
+ for(var x in name){
+ this.set(x, name[x]);
+ }
+ return this;
+ }
+ var names = this._getAttrNames(name),
+ setter = this[names.s];
+ if(lang.isFunction(setter)){
+ // use the explicit setter
+ var result = setter.apply(this, Array.prototype.slice.call(arguments, 1));
+ }else{
+ // Mapping from widget attribute to DOMNode attribute/value/etc.
+ // Map according to:
+ // 1. attributeMap setting, if one exists (TODO: attributeMap deprecated, remove in 2.0)
+ // 2. _setFooAttr: {...} type attribute in the widget (if one exists)
+ // 3. apply to focusNode or domNode if standard attribute name, excluding funcs like onClick.
+ // Checks if an attribute is a "standard attribute" by whether the DOMNode JS object has a similar
+ // attribute name (ex: accept-charset attribute matches jsObject.acceptCharset).
+ // Note also that Tree.focusNode() is a function not a DOMNode, so test for that.
+ var defaultNode = this.focusNode && !lang.isFunction(this.focusNode) ? "focusNode" : "domNode",
+ tag = this[defaultNode].tagName,
+ attrsForTag = tagAttrs[tag] || (tagAttrs[tag] = getAttrs(this[defaultNode])),
+ map = name in this.attributeMap ? this.attributeMap[name] :
+ names.s in this ? this[names.s] :
+ ((names.l in attrsForTag && typeof value != "function") ||
+ /^aria-|^data-|^role$/.test(name)) ? defaultNode : null;
+ if(map != null){
+ this._attrToDom(name, value, map);
+ }
+ this._set(name, value);
+ }
+ return result || this;
+ },
+
+ _attrPairNames: {}, // shared between all widgets
+ _getAttrNames: function(name){
+ // summary:
+ // Helper function for get() and set().
+ // Caches attribute name values so we don't do the string ops every time.
+ // tags:
+ // private
+
+ var apn = this._attrPairNames;
+ if(apn[name]){ return apn[name]; }
+ var uc = name.replace(/^[a-z]|-[a-zA-Z]/g, function(c){ return c.charAt(c.length-1).toUpperCase(); });
+ return (apn[name] = {
+ n: name+"Node",
+ s: "_set"+uc+"Attr", // converts dashes to camel case, ex: accept-charset --> _setAcceptCharsetAttr
+ g: "_get"+uc+"Attr",
+ l: uc.toLowerCase() // lowercase name w/out dashes, ex: acceptcharset
+ });
+ },
+
+ _set: function(/*String*/ name, /*anything*/ value){
+ // summary:
+ // Helper function to set new value for specified attribute, and call handlers
+ // registered with watch() if the value has changed.
+ var oldValue = this[name];
+ this[name] = value;
+ if(this._watchCallbacks && this._created && value !== oldValue){
+ this._watchCallbacks(name, oldValue, value);
+ }
+ },
+
+ on: function(/*String*/ type, /*Function*/ func){
+ // summary:
+ // Call specified function when event occurs, ex: myWidget.on("click", function(){ ... }).
+ // description:
+ // Call specified function when event `type` occurs, ex: `myWidget.on("click", function(){ ... })`.
+ // Note that the function is not run in any particular scope, so if (for example) you want it to run in the
+ // widget's scope you must do `myWidget.on("click", lang.hitch(myWidget, func))`.
+
+ return aspect.after(this, this._onMap(type), func, true);
+ },
+
+ _onMap: function(/*String*/ type){
+ // summary:
+ // Maps on() type parameter (ex: "mousemove") to method name (ex: "onMouseMove")
+ var ctor = this.constructor, map = ctor._onMap;
+ if(!map){
+ map = (ctor._onMap = {});
+ for(var attr in ctor.prototype){
+ if(/^on/.test(attr)){
+ map[attr.replace(/^on/, "").toLowerCase()] = attr;
+ }
+ }
+ }
+ return map[type.toLowerCase()]; // String
+ },
+
+ toString: function(){
+ // summary:
+ // Returns a string that represents the widget
+ // description:
+ // When a widget is cast to a string, this method will be used to generate the
+ // output. Currently, it does not implement any sort of reversible
+ // serialization.
+ return '[Widget ' + this.declaredClass + ', ' + (this.id || 'NO ID') + ']'; // String
+ },
+
+ getChildren: function(){
+ // summary:
+ // Returns all the widgets contained by this, i.e., all widgets underneath this.containerNode.
+ // Does not return nested widgets, nor widgets that are part of this widget's template.
+ return this.containerNode ? registry.findWidgets(this.containerNode) : []; // dijit._Widget[]
+ },
+
+ getParent: function(){
+ // summary:
+ // Returns the parent widget of this widget
+ return registry.getEnclosingWidget(this.domNode.parentNode);
+ },
+
+ connect: function(
+ /*Object|null*/ obj,
+ /*String|Function*/ event,
+ /*String|Function*/ method){
+ // summary:
+ // Connects specified obj/event to specified method of this object
+ // and registers for disconnect() on widget destroy.
+ // description:
+ // Provide widget-specific analog to dojo.connect, except with the
+ // implicit use of this widget as the target object.
+ // Events connected with `this.connect` are disconnected upon
+ // destruction.
+ // returns:
+ // A handle that can be passed to `disconnect` in order to disconnect before
+ // the widget is destroyed.
+ // example:
+ // | var btn = new dijit.form.Button();
+ // | // when foo.bar() is called, call the listener we're going to
+ // | // provide in the scope of btn
+ // | btn.connect(foo, "bar", function(){
+ // | console.debug(this.toString());
+ // | });
+ // tags:
+ // protected
+
+ var handle = connect.connect(obj, event, this, method);
+ this._connects.push(handle);
+ return handle; // _Widget.Handle
+ },
+
+ disconnect: function(handle){
+ // summary:
+ // Disconnects handle created by `connect`.
+ // Also removes handle from this widget's list of connects.
+ // tags:
+ // protected
+ var i = array.indexOf(this._connects, handle);
+ if(i != -1){
+ handle.remove();
+ this._connects.splice(i, 1);
+ }
+ },
+
+ subscribe: function(t, method){
+ // summary:
+ // Subscribes to the specified topic and calls the specified method
+ // of this object and registers for unsubscribe() on widget destroy.
+ // description:
+ // Provide widget-specific analog to dojo.subscribe, except with the
+ // implicit use of this widget as the target object.
+ // t: String
+ // The topic
+ // method: Function
+ // The callback
+ // example:
+ // | var btn = new dijit.form.Button();
+ // | // when /my/topic is published, this button changes its label to
+ // | // be the parameter of the topic.
+ // | btn.subscribe("/my/topic", function(v){
+ // | this.set("label", v);
+ // | });
+ // tags:
+ // protected
+ var handle = topic.subscribe(t, lang.hitch(this, method));
+ this._connects.push(handle);
+ return handle; // _Widget.Handle
+ },
+
+ unsubscribe: function(/*Object*/ handle){
+ // summary:
+ // Unsubscribes handle created by this.subscribe.
+ // Also removes handle from this widget's list of subscriptions
+ // tags:
+ // protected
+ this.disconnect(handle);
+ },
+
+ isLeftToRight: function(){
+ // summary:
+ // Return this widget's explicit or implicit orientation (true for LTR, false for RTL)
+ // tags:
+ // protected
+ return this.dir ? (this.dir == "ltr") : domGeometry.isBodyLtr(); //Boolean
+ },
+
+ isFocusable: function(){
+ // summary:
+ // Return true if this widget can currently be focused
+ // and false if not
+ return this.focus && (domStyle.get(this.domNode, "display") != "none");
+ },
+
+ placeAt: function(/* String|DomNode|_Widget */reference, /* String?|Int? */position){
+ // summary:
+ // Place this widget's domNode reference somewhere in the DOM based
+ // on standard domConstruct.place conventions, or passing a Widget reference that
+ // contains and addChild member.
+ //
+ // description:
+ // A convenience function provided in all _Widgets, providing a simple
+ // shorthand mechanism to put an existing (or newly created) Widget
+ // somewhere in the dom, and allow chaining.
+ //
+ // reference:
+ // The String id of a domNode, a domNode reference, or a reference to a Widget possessing
+ // an addChild method.
+ //
+ // position:
+ // If passed a string or domNode reference, the position argument
+ // accepts a string just as domConstruct.place does, one of: "first", "last",
+ // "before", or "after".
+ //
+ // If passed a _Widget reference, and that widget reference has an ".addChild" method,
+ // it will be called passing this widget instance into that method, supplying the optional
+ // position index passed.
+ //
+ // returns:
+ // dijit._Widget
+ // Provides a useful return of the newly created dijit._Widget instance so you
+ // can "chain" this function by instantiating, placing, then saving the return value
+ // to a variable.
+ //
+ // example:
+ // | // create a Button with no srcNodeRef, and place it in the body:
+ // | var button = new dijit.form.Button({ label:"click" }).placeAt(win.body());
+ // | // now, 'button' is still the widget reference to the newly created button
+ // | button.on("click", function(e){ console.log('click'); }));
+ //
+ // example:
+ // | // create a button out of a node with id="src" and append it to id="wrapper":
+ // | var button = new dijit.form.Button({},"src").placeAt("wrapper");
+ //
+ // example:
+ // | // place a new button as the first element of some div
+ // | var button = new dijit.form.Button({ label:"click" }).placeAt("wrapper","first");
+ //
+ // example:
+ // | // create a contentpane and add it to a TabContainer
+ // | var tc = dijit.byId("myTabs");
+ // | new dijit.layout.ContentPane({ href:"foo.html", title:"Wow!" }).placeAt(tc)
+
+ if(reference.declaredClass && reference.addChild){
+ reference.addChild(this, position);
+ }else{
+ domConstruct.place(this.domNode, reference, position);
+ }
+ return this;
+ },
+
+ getTextDir: function(/*String*/ text,/*String*/ originalDir){
+ // summary:
+ // Return direction of the text.
+ // The function overridden in the _BidiSupport module,
+ // its main purpose is to calculate the direction of the
+ // text, if was defined by the programmer through textDir.
+ // tags:
+ // protected.
+ return originalDir;
+ },
+
+ applyTextDir: function(/*===== element, text =====*/){
+ // summary:
+ // The function overridden in the _BidiSupport module,
+ // originally used for setting element.dir according to this.textDir.
+ // In this case does nothing.
+ // element: DOMNode
+ // text: String
+ // tags:
+ // protected.
+ }
+});
+
+});
+
+},
+'dojo/dnd/Moveable':function(){
+define(["../main", "../Evented", "../touch", "./Mover"], function(dojo, Evented, touch) {
+ // module:
+ // dojo/dnd/Moveable
+ // summary:
+ // TODOC
+
+
+/*=====
+dojo.declare("dojo.dnd.__MoveableArgs", [], {
+ // handle: Node||String
+ // A node (or node's id), which is used as a mouse handle.
+ // If omitted, the node itself is used as a handle.
+ handle: null,
+
+ // delay: Number
+ // delay move by this number of pixels
+ delay: 0,
+
+ // skip: Boolean
+ // skip move of form elements
+ skip: false,
+
+ // mover: Object
+ // a constructor of custom Mover
+ mover: dojo.dnd.Mover
+});
+=====*/
+
+dojo.declare("dojo.dnd.Moveable", [Evented], {
+ // object attributes (for markup)
+ handle: "",
+ delay: 0,
+ skip: false,
+
+ constructor: function(node, params){
+ // summary:
+ // an object, which makes a node moveable
+ // node: Node
+ // a node (or node's id) to be moved
+ // params: dojo.dnd.__MoveableArgs?
+ // optional parameters
+ this.node = dojo.byId(node);
+ if(!params){ params = {}; }
+ this.handle = params.handle ? dojo.byId(params.handle) : null;
+ if(!this.handle){ this.handle = this.node; }
+ this.delay = params.delay > 0 ? params.delay : 0;
+ this.skip = params.skip;
+ this.mover = params.mover ? params.mover : dojo.dnd.Mover;
+ this.events = [
+ dojo.connect(this.handle, touch.press, this, "onMouseDown"),
+ // cancel text selection and text dragging
+ dojo.connect(this.handle, "ondragstart", this, "onSelectStart"),
+ dojo.connect(this.handle, "onselectstart", this, "onSelectStart")
+ ];
+ },
+
+ // markup methods
+ markupFactory: function(params, node, ctor){
+ return new ctor(node, params);
+ },
+
+ // methods
+ destroy: function(){
+ // summary:
+ // stops watching for possible move, deletes all references, so the object can be garbage-collected
+ dojo.forEach(this.events, dojo.disconnect);
+ this.events = this.node = this.handle = null;
+ },
+
+ // mouse event processors
+ onMouseDown: function(e){
+ // summary:
+ // event processor for onmousedown/ontouchstart, creates a Mover for the node
+ // e: Event
+ // mouse/touch event
+ if(this.skip && dojo.dnd.isFormElement(e)){ return; }
+ if(this.delay){
+ this.events.push(
+ dojo.connect(this.handle, touch.move, this, "onMouseMove"),
+ dojo.connect(this.handle, touch.release, this, "onMouseUp")
+ );
+ this._lastX = e.pageX;
+ this._lastY = e.pageY;
+ }else{
+ this.onDragDetected(e);
+ }
+ dojo.stopEvent(e);
+ },
+ onMouseMove: function(e){
+ // summary:
+ // event processor for onmousemove/ontouchmove, used only for delayed drags
+ // e: Event
+ // mouse/touch event
+ if(Math.abs(e.pageX - this._lastX) > this.delay || Math.abs(e.pageY - this._lastY) > this.delay){
+ this.onMouseUp(e);
+ this.onDragDetected(e);
+ }
+ dojo.stopEvent(e);
+ },
+ onMouseUp: function(e){
+ // summary:
+ // event processor for onmouseup, used only for delayed drags
+ // e: Event
+ // mouse event
+ for(var i = 0; i < 2; ++i){
+ dojo.disconnect(this.events.pop());
+ }
+ dojo.stopEvent(e);
+ },
+ onSelectStart: function(e){
+ // summary:
+ // event processor for onselectevent and ondragevent
+ // e: Event
+ // mouse event
+ if(!this.skip || !dojo.dnd.isFormElement(e)){
+ dojo.stopEvent(e);
+ }
+ },
+
+ // local events
+ onDragDetected: function(/* Event */ e){
+ // summary:
+ // called when the drag is detected;
+ // responsible for creation of the mover
+ new this.mover(this.node, e, this);
+ },
+ onMoveStart: function(/* dojo.dnd.Mover */ mover){
+ // summary:
+ // called before every move operation
+ dojo.publish("/dnd/move/start", [mover]);
+ dojo.addClass(dojo.body(), "dojoMove");
+ dojo.addClass(this.node, "dojoMoveItem");
+ },
+ onMoveStop: function(/* dojo.dnd.Mover */ mover){
+ // summary:
+ // called after every move operation
+ dojo.publish("/dnd/move/stop", [mover]);
+ dojo.removeClass(dojo.body(), "dojoMove");
+ dojo.removeClass(this.node, "dojoMoveItem");
+ },
+ onFirstMove: function(/* dojo.dnd.Mover */ mover, /* Event */ e){
+ // summary:
+ // called during the very first move notification;
+ // can be used to initialize coordinates, can be overwritten.
+
+ // default implementation does nothing
+ },
+ onMove: function(/* dojo.dnd.Mover */ mover, /* Object */ leftTop, /* Event */ e){
+ // summary:
+ // called during every move notification;
+ // should actually move the node; can be overwritten.
+ this.onMoving(mover, leftTop);
+ var s = mover.node.style;
+ s.left = leftTop.l + "px";
+ s.top = leftTop.t + "px";
+ this.onMoved(mover, leftTop);
+ },
+ onMoving: function(/* dojo.dnd.Mover */ mover, /* Object */ leftTop){
+ // summary:
+ // called before every incremental move; can be overwritten.
+
+ // default implementation does nothing
+ },
+ onMoved: function(/* dojo.dnd.Mover */ mover, /* Object */ leftTop){
+ // summary:
+ // called after every incremental move; can be overwritten.
+
+ // default implementation does nothing
+ }
+});
+
+return dojo.dnd.Moveable;
+});
+
+}}});
+
+require(["dojo/i18n"], function(i18n){
+i18n._preloadLocalizations("dojox/grid/nls/DataGrid", ["nl-nl","en-us","da","fi-fi","pt-pt","hu","sk","sl","pl","ca","sv","zh-tw","ar","en-gb","he-il","de-de","ko-kr","ja-jp","nb","ru","es-es","th","cs","it-it","pt-br","fr-fr","el","tr","zh-cn"]);
+});
+define("dojox/grid/DataGrid", [
+ "../main",
+ "dojo/_base/array",
+ "dojo/_base/lang",
+ "dojo/_base/json",
+ "dojo/_base/sniff",
+ "dojo/_base/declare",
+ "./_Grid",
+ "./DataSelection",
+ "dojo/_base/html"
+], function(dojox, array, lang, json, has, declare, _Grid, DataSelection, html){
+
+/*=====
+declare("dojox.grid.__DataCellDef", dojox.grid.__CellDef, {
+ constructor: function(){
+ // field: String?
+ // The attribute to read from the dojo.data item for the row.
+ // fields: String[]?
+ // An array of fields to grab the values of and pass as an array to the grid
+ // get: Function?
+ // function(rowIndex, item?){} rowIndex is of type Integer, item is of type
+ // Object. This function will be called when a cell requests data. Returns
+ // the unformatted data for the cell.
+ }
+});
+=====*/
+
+/*=====
+declare("dojox.grid.__DataViewDef", dojox.grid.__ViewDef, {
+ constructor: function(){
+ // cells: dojox.grid.__DataCellDef[]|Array[dojox.grid.__DataCellDef[]]?
+ // The structure of the cells within this grid.
+ // defaultCell: dojox.grid.__DataCellDef?
+ // A cell definition with default values for all cells in this view. If
+ // a property is defined in a cell definition in the "cells" array and
+ // this property, the cell definition's property will override this
+ // property's property.
+ }
+});
+=====*/
+
+var DataGrid = declare("dojox.grid.DataGrid", _Grid, {
+ store: null,
+ query: null,
+ queryOptions: null,
+ fetchText: '...',
+ sortFields: null,
+
+ // updateDelay: int
+ // Time, in milliseconds, to delay updates automatically so that multiple
+ // calls to onSet/onNew/onDelete don't keep rerendering the grid. Set
+ // to 0 to immediately cause updates. A higher value will result in
+ // better performance at the expense of responsiveness of the grid.
+ updateDelay: 1,
+
+/*=====
+ // structure: dojox.grid.__DataViewDef|dojox.grid.__DataViewDef[]|dojox.grid.__DataCellDef[]|Array[dojox.grid.__DataCellDef[]]
+ // View layout defintion.
+ structure: '',
+=====*/
+
+ // You can specify items instead of a query, if you like. They do not need
+ // to be loaded - but the must be items in the store
+ items: null,
+
+ _store_connects: null,
+ _by_idty: null,
+ _by_idx: null,
+ _cache: null,
+ _pages: null,
+ _pending_requests: null,
+ _bop: -1,
+ _eop: -1,
+ _requests: 0,
+ rowCount: 0,
+
+ _isLoaded: false,
+ _isLoading: false,
+
+ //keepSelection: Boolean
+ // Whether keep selection after sort, filter etc.
+ keepSelection: false,
+
+ postCreate: function(){
+ this._pages = [];
+ this._store_connects = [];
+ this._by_idty = {};
+ this._by_idx = [];
+ this._cache = [];
+ this._pending_requests = {};
+
+ this._setStore(this.store);
+ this.inherited(arguments);
+ },
+
+ destroy: function(){
+ this.selection.destroy();
+ this.inherited(arguments);
+ },
+
+ createSelection: function(){
+ this.selection = new DataSelection(this);
+ },
+
+ get: function(inRowIndex, inItem){
+ // summary: Default data getter.
+ // description:
+ // Provides data to display in a grid cell. Called in grid cell context.
+ // So this.cell.index is the column index.
+ // inRowIndex: Integer
+ // Row for which to provide data
+ // returns:
+ // Data to display for a given grid cell.
+
+ if(inItem && this.field == "_item" && !this.fields){
+ return inItem;
+ }else if(inItem && this.fields){
+ var ret = [];
+ var s = this.grid.store;
+ array.forEach(this.fields, function(f){
+ ret = ret.concat(s.getValues(inItem, f));
+ });
+ return ret;
+ }else if(!inItem && typeof inRowIndex === "string"){
+ return this.inherited(arguments);
+ }
+ return (!inItem ? this.defaultValue : (!this.field ? this.value : (this.field == "_item" ? inItem : this.grid.store.getValue(inItem, this.field))));
+ },
+
+ _checkUpdateStatus: function(){
+ if(this.updateDelay > 0){
+ var iStarted = false;
+ if(this._endUpdateDelay){
+ clearTimeout(this._endUpdateDelay);
+ delete this._endUpdateDelay;
+ iStarted = true;
+ }
+ if(!this.updating){
+ this.beginUpdate();
+ iStarted = true;
+ }
+ if(iStarted){
+ var _this = this;
+ this._endUpdateDelay = setTimeout(function(){
+ delete _this._endUpdateDelay;
+ _this.endUpdate();
+ }, this.updateDelay);
+ }
+ }
+ },
+
+ _onSet: function(item, attribute, oldValue, newValue){
+ this._checkUpdateStatus();
+ var idx = this.getItemIndex(item);
+ if(idx>-1){
+ this.updateRow(idx);
+ }
+ },
+
+ _createItem: function(item, index){
+ var idty = this._hasIdentity ? this.store.getIdentity(item) : json.toJson(this.query) + ":idx:" + index + ":sort:" + json.toJson(this.getSortProps());
+ var o = this._by_idty[idty] = { idty: idty, item: item };
+ return o;
+ },
+
+ _addItem: function(item, index, noUpdate){
+ this._by_idx[index] = this._createItem(item, index);
+ if(!noUpdate){
+ this.updateRow(index);
+ }
+ },
+
+ _onNew: function(item, parentInfo){
+ this._checkUpdateStatus();
+ var rowCount = this.get('rowCount');
+ this._addingItem = true;
+ this.updateRowCount(rowCount+1);
+ this._addingItem = false;
+ this._addItem(item, rowCount);
+ this.showMessage();
+ },
+
+ _onDelete: function(item){
+ this._checkUpdateStatus();
+ var idx = this._getItemIndex(item, true);
+
+ if(idx >= 0){
+ // When a row is deleted, all rest rows are shifted down,
+ // and migrate from page to page. If some page is not
+ // loaded yet empty rows can migrate to initialized pages
+ // without refreshing. It causes empty rows in some pages, see:
+ // http://bugs.dojotoolkit.org/ticket/6818
+ // this code fix this problem by reseting loaded page info
+ this._pages = [];
+ this._bop = -1;
+ this._eop = -1;
+
+ var o = this._by_idx[idx];
+ this._by_idx.splice(idx, 1);
+ delete this._by_idty[o.idty];
+ this.updateRowCount(this.get('rowCount')-1);
+ if(this.get('rowCount') === 0){
+ this.showMessage(this.noDataMessage);
+ }
+ }
+ if(this.selection.isSelected(idx)){
+ this.selection.deselect(idx);
+ this.selection.selected.splice(idx, 1);
+ }
+ },
+
+ _onRevert: function(){
+ this._refresh();
+ },
+
+ setStore: function(store, query, queryOptions){
+ if(this._requestsPending(0)){
+ return;
+ }
+ this._setQuery(query, queryOptions);
+ this._setStore(store);
+ this._refresh(true);
+ },
+
+ setQuery: function(query, queryOptions){
+ if(this._requestsPending(0)){
+ return;
+ }
+ this._setQuery(query, queryOptions);
+ this._refresh(true);
+ },
+
+ setItems: function(items){
+ this.items = items;
+ this._setStore(this.store);
+ this._refresh(true);
+ },
+
+ _setQuery: function(query, queryOptions){
+ this.query = query;
+ this.queryOptions = queryOptions || this.queryOptions;
+ },
+
+ _setStore: function(store){
+ if(this.store && this._store_connects){
+ array.forEach(this._store_connects, this.disconnect, this);
+ }
+ this.store = store;
+
+ if(this.store){
+ var f = this.store.getFeatures();
+ var h = [];
+
+ this._canEdit = !!f["dojo.data.api.Write"] && !!f["dojo.data.api.Identity"];
+ this._hasIdentity = !!f["dojo.data.api.Identity"];
+
+ if(!!f["dojo.data.api.Notification"] && !this.items){
+ h.push(this.connect(this.store, "onSet", "_onSet"));
+ h.push(this.connect(this.store, "onNew", "_onNew"));
+ h.push(this.connect(this.store, "onDelete", "_onDelete"));
+ }
+ if(this._canEdit){
+ h.push(this.connect(this.store, "revert", "_onRevert"));
+ }
+
+ this._store_connects = h;
+ }
+ },
+
+ _onFetchBegin: function(size, req){
+ if(!this.scroller){ return; }
+ if(this.rowCount != size){
+ if(req.isRender){
+ this.scroller.init(size, this.keepRows, this.rowsPerPage);
+ this.rowCount = size;
+ this._setAutoHeightAttr(this.autoHeight, true);
+ this._skipRowRenormalize = true;
+ this.prerender();
+ this._skipRowRenormalize = false;
+ }else{
+ this.updateRowCount(size);
+ }
+ }
+ if(!size){
+ this.views.render();
+ this._resize();
+ this.showMessage(this.noDataMessage);
+ this.focus.initFocusView();
+ }else{
+ this.showMessage();
+ }
+ },
+
+ _onFetchComplete: function(items, req){
+ if(!this.scroller){ return; }
+ if(items && items.length > 0){
+ //console.log(items);
+ array.forEach(items, function(item, idx){
+ this._addItem(item, req.start+idx, true);
+ }, this);
+ this.updateRows(req.start, items.length);
+ if(req.isRender){
+ this.setScrollTop(0);
+ this.postrender();
+ }else if(this._lastScrollTop){
+ this.setScrollTop(this._lastScrollTop);
+ }
+ if(has("ie")){
+ html.setSelectable(this.domNode, this.selectable);
+ }
+ }
+ delete this._lastScrollTop;
+ if(!this._isLoaded){
+ this._isLoading = false;
+ this._isLoaded = true;
+ }
+ this._pending_requests[req.start] = false;
+ },
+
+ _onFetchError: function(err, req){
+ console.log(err);
+ delete this._lastScrollTop;
+ if(!this._isLoaded){
+ this._isLoading = false;
+ this._isLoaded = true;
+ this.showMessage(this.errorMessage);
+ }
+ this._pending_requests[req.start] = false;
+ this.onFetchError(err, req);
+ },
+
+ onFetchError: function(err, req){
+ },
+
+ _fetch: function(start, isRender){
+ start = start || 0;
+ if(this.store && !this._pending_requests[start]){
+ if(!this._isLoaded && !this._isLoading){
+ this._isLoading = true;
+ this.showMessage(this.loadingMessage);
+ }
+ this._pending_requests[start] = true;
+ //console.log("fetch: ", start);
+ try{
+ if(this.items){
+ var items = this.items;
+ var store = this.store;
+ this.rowsPerPage = items.length;
+ var req = {
+ start: start,
+ count: this.rowsPerPage,
+ isRender: isRender
+ };
+ this._onFetchBegin(items.length, req);
+
+ // Load them if we need to
+ var waitCount = 0;
+ array.forEach(items, function(i){
+ if(!store.isItemLoaded(i)){ waitCount++; }
+ });
+ if(waitCount === 0){
+ this._onFetchComplete(items, req);
+ }else{
+ var onItem = function(item){
+ waitCount--;
+ if(waitCount === 0){
+ this._onFetchComplete(items, req);
+ }
+ };
+ array.forEach(items, function(i){
+ if(!store.isItemLoaded(i)){
+ store.loadItem({item: i, onItem: onItem, scope: this});
+ }
+ }, this);
+ }
+ }else{
+ this.store.fetch({
+ start: start,
+ count: this.rowsPerPage,
+ query: this.query,
+ sort: this.getSortProps(),
+ queryOptions: this.queryOptions,
+ isRender: isRender,
+ onBegin: lang.hitch(this, "_onFetchBegin"),
+ onComplete: lang.hitch(this, "_onFetchComplete"),
+ onError: lang.hitch(this, "_onFetchError")
+ });
+ }
+ }catch(e){
+ this._onFetchError(e, {start: start, count: this.rowsPerPage});
+ }
+ }
+ },
+
+ _clearData: function(){
+ this.updateRowCount(0);
+ this._by_idty = {};
+ this._by_idx = [];
+ this._pages = [];
+ this._bop = this._eop = -1;
+ this._isLoaded = false;
+ this._isLoading = false;
+ },
+
+ getItem: function(idx){
+ var data = this._by_idx[idx];
+ if(!data||(data&&!data.item)){
+ this._preparePage(idx);
+ return null;
+ }
+ return data.item;
+ },
+
+ getItemIndex: function(item){
+ return this._getItemIndex(item, false);
+ },
+
+ _getItemIndex: function(item, isDeleted){
+ if(!isDeleted && !this.store.isItem(item)){
+ return -1;
+ }
+
+ var idty = this._hasIdentity ? this.store.getIdentity(item) : null;
+
+ for(var i=0, l=this._by_idx.length; i<l; i++){
+ var d = this._by_idx[i];
+ if(d && ((idty && d.idty == idty) || (d.item === item))){
+ return i;
+ }
+ }
+ return -1;
+ },
+
+ filter: function(query, reRender){
+ this.query = query;
+ if(reRender){
+ this._clearData();
+ }
+ this._fetch();
+ },
+
+ _getItemAttr: function(idx, attr){
+ var item = this.getItem(idx);
+ return (!item ? this.fetchText : this.store.getValue(item, attr));
+ },
+
+ // rendering
+ _render: function(){
+ if(this.domNode.parentNode){
+ this.scroller.init(this.get('rowCount'), this.keepRows, this.rowsPerPage);
+ this.prerender();
+ this._fetch(0, true);
+ }
+ },
+
+ // paging
+ _requestsPending: function(inRowIndex){
+ return this._pending_requests[inRowIndex];
+ },
+
+ _rowToPage: function(inRowIndex){
+ return (this.rowsPerPage ? Math.floor(inRowIndex / this.rowsPerPage) : inRowIndex);
+ },
+
+ _pageToRow: function(inPageIndex){
+ return (this.rowsPerPage ? this.rowsPerPage * inPageIndex : inPageIndex);
+ },
+
+ _preparePage: function(inRowIndex){
+ if((inRowIndex < this._bop || inRowIndex >= this._eop) && !this._addingItem){
+ var pageIndex = this._rowToPage(inRowIndex);
+ this._needPage(pageIndex);
+ this._bop = pageIndex * this.rowsPerPage;
+ this._eop = this._bop + (this.rowsPerPage || this.get('rowCount'));
+ }
+ },
+
+ _needPage: function(inPageIndex){
+ if(!this._pages[inPageIndex]){
+ this._pages[inPageIndex] = true;
+ this._requestPage(inPageIndex);
+ }
+ },
+
+ _requestPage: function(inPageIndex){
+ var row = this._pageToRow(inPageIndex);
+ var count = Math.min(this.rowsPerPage, this.get('rowCount') - row);
+ if(count > 0){
+ this._requests++;
+ if(!this._requestsPending(row)){
+ setTimeout(lang.hitch(this, "_fetch", row, false), 1);
+ //this.requestRows(row, count);
+ }
+ }
+ },
+
+ getCellName: function(inCell){
+ return inCell.field;
+ //console.log(inCell);
+ },
+
+ _refresh: function(isRender){
+ this._clearData();
+ this._fetch(0, isRender);
+ },
+
+ sort: function(){
+ this.edit.apply();
+ this._lastScrollTop = this.scrollTop;
+ this._refresh();
+ },
+
+ canSort: function(){
+ return (!this._isLoading);
+ },
+
+ getSortProps: function(){
+ var c = this.getCell(this.getSortIndex());
+ if(!c){
+ if(this.sortFields){
+ return this.sortFields;
+ }
+ return null;
+ }else{
+ var desc = c["sortDesc"];
+ var si = !(this.sortInfo>0);
+ if(typeof desc == "undefined"){
+ desc = si;
+ }else{
+ desc = si ? !desc : desc;
+ }
+ return [{ attribute: c.field, descending: desc }];
+ }
+ },
+
+ styleRowState: function(inRow){
+ // summary: Perform row styling
+ if(this.store && this.store.getState){
+ var states=this.store.getState(inRow.index), c='';
+ for(var i=0, ss=["inflight", "error", "inserting"], s; s=ss[i]; i++){
+ if(states[s]){
+ c = ' dojoxGridRow-' + s;
+ break;
+ }
+ }
+ inRow.customClasses += c;
+ }
+ },
+
+ onStyleRow: function(inRow){
+ this.styleRowState(inRow);
+ this.inherited(arguments);
+ },
+
+ // editing
+ canEdit: function(inCell, inRowIndex){
+ return this._canEdit;
+ },
+
+ _copyAttr: function(idx, attr){
+ var row = {};
+ var backstop = {};
+ var src = this.getItem(idx);
+ return this.store.getValue(src, attr);
+ },
+
+ doStartEdit: function(inCell, inRowIndex){
+ if(!this._cache[inRowIndex]){
+ this._cache[inRowIndex] = this._copyAttr(inRowIndex, inCell.field);
+ }
+ this.onStartEdit(inCell, inRowIndex);
+ },
+
+ doApplyCellEdit: function(inValue, inRowIndex, inAttrName){
+ this.store.fetchItemByIdentity({
+ identity: this._by_idx[inRowIndex].idty,
+ onItem: lang.hitch(this, function(item){
+ var oldValue = this.store.getValue(item, inAttrName);
+ if(typeof oldValue == 'number'){
+ inValue = isNaN(inValue) ? inValue : parseFloat(inValue);
+ }else if(typeof oldValue == 'boolean'){
+ inValue = inValue == 'true' ? true : inValue == 'false' ? false : inValue;
+ }else if(oldValue instanceof Date){
+ var asDate = new Date(inValue);
+ inValue = isNaN(asDate.getTime()) ? inValue : asDate;
+ }
+ this.store.setValue(item, inAttrName, inValue);
+ this.onApplyCellEdit(inValue, inRowIndex, inAttrName);
+ })
+ });
+ },
+
+ doCancelEdit: function(inRowIndex){
+ var cache = this._cache[inRowIndex];
+ if(cache){
+ this.updateRow(inRowIndex);
+ delete this._cache[inRowIndex];
+ }
+ this.onCancelEdit.apply(this, arguments);
+ },
+
+ doApplyEdit: function(inRowIndex, inDataAttr){
+ var cache = this._cache[inRowIndex];
+ /*if(cache){
+ var data = this.getItem(inRowIndex);
+ if(this.store.getValue(data, inDataAttr) != cache){
+ this.update(cache, data, inRowIndex);
+ }
+ delete this._cache[inRowIndex];
+ }*/
+ this.onApplyEdit(inRowIndex);
+ },
+
+ removeSelectedRows: function(){
+ // summary:
+ // Remove the selected rows from the grid.
+ if(this._canEdit){
+ this.edit.apply();
+ var fx = lang.hitch(this, function(items){
+ if(items.length){
+ array.forEach(items, this.store.deleteItem, this.store);
+ this.selection.clear();
+ }
+ });
+ if(this.allItemsSelected){
+ this.store.fetch({
+ query: this.query,
+ queryOptions: this.queryOptions,
+ onComplete: fx});
+ }else{
+ fx(this.selection.getSelected());
+ }
+ }
+ }
+});
+
+DataGrid.cell_markupFactory = function(cellFunc, node, cellDef){
+ var field = lang.trim(html.attr(node, "field")||"");
+ if(field){
+ cellDef.field = field;
+ }
+ cellDef.field = cellDef.field||cellDef.name;
+ var fields = lang.trim(html.attr(node, "fields")||"");
+ if(fields){
+ cellDef.fields = fields.split(",");
+ }
+ if(cellFunc){
+ cellFunc(node, cellDef);
+ }
+};
+
+DataGrid.markupFactory = function(props, node, ctor, cellFunc){
+ return _Grid.markupFactory(props, node, ctor,
+ lang.partial(DataGrid.cell_markupFactory, cellFunc));
+};
+
+return DataGrid;
+
+}); \ No newline at end of file
diff --git a/js/dojo-1.7.2/dojox/grid/DataSelection.js b/js/dojo-1.7.2/dojox/grid/DataSelection.js
new file mode 100644
index 0000000..c3c630e
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/DataSelection.js
@@ -0,0 +1,82 @@
+//>>built
+define("dojox/grid/DataSelection", [
+ "dojo/_base/declare",
+ "./_SelectionPreserver",
+ "./Selection"
+], function(declare, _SelectionPreserver, Selection){
+
+return declare("dojox.grid.DataSelection", Selection, {
+ constructor: function(grid){
+ if(grid.keepSelection){
+ this.preserver = new _SelectionPreserver(this);
+ }
+ },
+
+ destroy: function(){
+ if(this.preserver){
+ this.preserver.destroy();
+ }
+ },
+
+ getFirstSelected: function(){
+ var idx = Selection.prototype.getFirstSelected.call(this);
+
+ if(idx == -1){ return null; }
+ return this.grid.getItem(idx);
+ },
+
+ getNextSelected: function(inPrev){
+ var old_idx = this.grid.getItemIndex(inPrev);
+ var idx = Selection.prototype.getNextSelected.call(this, old_idx);
+
+ if(idx == -1){ return null; }
+ return this.grid.getItem(idx);
+ },
+
+ getSelected: function(){
+ var result = [];
+ for(var i=0, l=this.selected.length; i<l; i++){
+ if(this.selected[i]){
+ result.push(this.grid.getItem(i));
+ }
+ }
+ return result;
+ },
+
+ addToSelection: function(inItemOrIndex){
+ if(this.mode == 'none'){ return; }
+ var idx = null;
+ if(typeof inItemOrIndex == "number" || typeof inItemOrIndex == "string"){
+ idx = inItemOrIndex;
+ }else{
+ idx = this.grid.getItemIndex(inItemOrIndex);
+ }
+ Selection.prototype.addToSelection.call(this, idx);
+ },
+
+ deselect: function(inItemOrIndex){
+ if(this.mode == 'none'){ return; }
+ var idx = null;
+ if(typeof inItemOrIndex == "number" || typeof inItemOrIndex == "string"){
+ idx = inItemOrIndex;
+ }else{
+ idx = this.grid.getItemIndex(inItemOrIndex);
+ }
+ Selection.prototype.deselect.call(this, idx);
+ },
+
+ deselectAll: function(inItemOrIndex){
+ var idx = null;
+ if(inItemOrIndex || typeof inItemOrIndex == "number"){
+ if(typeof inItemOrIndex == "number" || typeof inItemOrIndex == "string"){
+ idx = inItemOrIndex;
+ }else{
+ idx = this.grid.getItemIndex(inItemOrIndex);
+ }
+ Selection.prototype.deselectAll.call(this, idx);
+ }else{
+ this.inherited(arguments);
+ }
+ }
+});
+}); \ No newline at end of file
diff --git a/js/dojo-1.7.2/dojox/grid/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/EnhancedGrid.js
new file mode 100644
index 0000000..9852dba
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/EnhancedGrid.js
@@ -0,0 +1,263 @@
+//>>built
+define("dojox/grid/EnhancedGrid", [
+ "dojo/_base/kernel",
+ "../main",
+ "dojo/_base/declare",
+ "dojo/_base/lang",
+ "dojo/_base/array",
+ "dojo/_base/sniff",
+ "dojo/dom",
+ "dojo/dom-geometry",
+ "dojo/i18n",
+ "./DataGrid",
+ "./DataSelection",
+ "./enhanced/_PluginManager",
+ "./enhanced/plugins/_SelectionPreserver",//default loaded plugin
+ "dojo/i18n!./enhanced/nls/EnhancedGrid"
+], function(dojo, dojox, declare, lang, array, has, dom, domGeometry, i18n,
+ DataGrid, DataSelection, _PluginManager, _SelectionPreserver){
+
+dojo.experimental("dojox.grid.EnhancedGrid");
+
+var EnhancedGrid = declare("dojox.grid.EnhancedGrid", DataGrid, {
+ // summary:
+ // Provides enhanced features based on DataGrid
+ //
+ // description:
+ // EnhancedGrid features are implemented as plugins that could be loaded on demand.
+ // Explicit dojo.require() is needed to use these feature plugins.
+ //
+ // example:
+ // A quick sample to use EnhancedGrid features:
+ //
+ // Step 1. Load EnhancedGrid and required features
+ // | <script type="text/javascript">
+ // | dojo.require("dojox.grid.EnhancedGrid");
+ // | dojo.require("dojox.grid.enhanced.plugins.DnD");
+ // | dojo.require("dojox.grid.enhanced.plugins.Menu");
+ // | dojo.require("dojox.grid.enhanced.plugins.NestedSorting");
+ // | dojo.require("dojox.grid.enhanced.plugins.IndirectSelection");
+ // | </script>
+ //
+ // Step 2. Use EnhancedGrid
+ // - Via HTML markup
+ // | <div dojoType="dojox.grid.EnhancedGrid" ...
+ // | plugins="{nestedSorting: true, dnd: true, indirectSelection: true,
+ // | menus:{headerMenu:"headerMenuId", rowMenu:"rowMenuId", cellMenu:"cellMenuId",
+ // | selectedRegionMenu:"selectedRegionMenuId"}}">
+ // | ...
+ // | </div>
+ //
+ // - Or via JavaScript
+ // | <script type="text/javascript">
+ // | var grid = new dojox.grid.EnhancedGrid({plugins : {nestedSorting: true, dnd: true, indirectSelection: true,
+ // | menus:{headerMenu:"headerMenuId", rowMenu:"rowMenuId", cellMenu:"cellMenuId",selectedRegionMenu:"selectedRegionMenuId"}},
+ // | ... }, dojo.byId('gridDiv'));
+ // | grid.startup();
+ // | </script>
+ //
+ //
+ // Plugin Support
+ // [Note: Plugin support is still experimental]
+ //
+ // You can either customize the default plugins or add new ones, more details please see
+ // - dojox.grid.enhanced._PluginManager
+ // - dojox.grid.enhanced._Plugin
+ // - dojox.grid.enhanced.plugins.*
+
+ //plugins: Object
+ // Plugin properties, e.g. {nestedSorting: true, dnd: true, ...}
+ plugins: null,
+
+ //pluginMgr: Object
+ // Singleton plugin manager
+ pluginMgr: null,
+
+ //_pluginMgrClass: Object
+ // Default plugin manager class
+ _pluginMgrClass: _PluginManager,
+
+ postMixInProperties: function(){
+ //load nls bundle
+ this._nls = i18n.getLocalization("dojox.grid.enhanced", "EnhancedGrid", this.lang);
+ this.inherited(arguments);
+ },
+ postCreate: function(){
+ //create plugin manager
+ this.pluginMgr = new this._pluginMgrClass(this);
+ this.pluginMgr.preInit();
+ this.inherited(arguments);
+ this.pluginMgr.postInit();
+ },
+ plugin: function(/*String*/name){
+ // summary:
+ // An easier way for getting a plugin, e.g. grid.plugin('dnd')
+ return this.pluginMgr.getPlugin(name);
+ },
+ startup: function(){
+ this.inherited(arguments);
+ this.pluginMgr.startup();
+ },
+ createSelection: function(){
+ this.selection = new dojox.grid.enhanced.DataSelection(this);
+ },
+ canSort: function(colIndex, field){
+ // summary:
+ // Overwritten
+ return true;
+ },
+ doKeyEvent: function(e){
+ // summary:
+ // Overwritten, see _Grid.doKeyEvent()
+ try{
+ var view = this.focus.focusView;
+ view.content.decorateEvent(e);
+ if(!e.cell){ view.header.decorateEvent(e); }
+ }catch(e){}
+ this.inherited(arguments);
+ },
+ doApplyCellEdit: function(inValue, inRowIndex, inAttrName){
+ // summary:
+ // Overwritten, see DataGrid.doApplyCellEdit()
+ if(!inAttrName){
+ this.invalidated[inRowIndex] = true;
+ return;
+ }
+ this.inherited(arguments);
+ },
+ mixin: function(target, source){
+ var props = {};
+ for(var p in source){
+ if(p == '_inherited' || p == 'declaredClass' || p == 'constructor' ||
+ source['privates'] && source['privates'][p]){
+ continue;
+ }
+ props[p] = source[p];
+ }
+ lang.mixin(target, props);
+ },
+ _copyAttr: function(idx, attr){
+ // summary:
+ // Overwritten, see DataGrid._copyAttr()
+ // Fix cell TAB navigation for single click editing
+ if(!attr){ return; }
+ return this.inherited(arguments);
+ },
+ _getHeaderHeight: function(){
+ // summary:
+ // Overwritten, see _Grid._getHeaderHeight()
+ // Should include borders/margins of this.viewsHeaderNode
+ this.inherited(arguments);
+ return domGeometry.getMarginBox(this.viewsHeaderNode).h;
+ },
+ _fetch: function(start, isRender){
+ // summary:
+ // Overwritten, see DataGrid._fetch()
+ if(this.items){
+ return this.inherited(arguments);
+ }
+ start = start || 0;
+ if(this.store && !this._pending_requests[start]){
+ if(!this._isLoaded && !this._isLoading){
+ this._isLoading = true;
+ this.showMessage(this.loadingMessage);
+ }
+ this._pending_requests[start] = true;
+ try{
+ var req = {
+ start: start,
+ count: this.rowsPerPage,
+ query: this.query,
+ sort: this.getSortProps(),
+ queryOptions: this.queryOptions,
+ isRender: isRender,
+ onBegin: lang.hitch(this, "_onFetchBegin"),
+ onComplete: lang.hitch(this, "_onFetchComplete"),
+ onError: lang.hitch(this, "_onFetchError")
+ };
+ this._storeLayerFetch(req);
+ }catch(e){
+ this._onFetchError(e, {start: start, count: this.rowsPerPage});
+ }
+ }
+ return 0;
+ },
+ _storeLayerFetch: function(req){
+ // summary:
+ // Extracted fetch specifically for store layer use
+ this.store.fetch(req);
+ },
+ getCellByField: function(field){
+ return array.filter(this.layout.cells, function(cell){
+ return cell.field == field;
+ })[0];
+ },
+ onMouseUp: function(e){ },
+ createView: function(){
+ // summary
+ // Overwrite: rewrite getCellX of view.header
+ var view = this.inherited(arguments);
+ if(has("mozilla")){
+ var ascendDom = function(inNode, inWhile){
+ for(var n = inNode; n && inWhile(n); n = n.parentNode){}
+ return n;
+ };//copied from dojox.grid._Builder
+ var makeNotTagName = function(inTagName){
+ var name = inTagName.toUpperCase();
+ return function(node){ return node.tagName != name; };
+ };//copied from dojox.grid._Builder
+
+ var func = view.header.getCellX;
+ view.header.getCellX = function(e){
+ var x = func.call(view.header, e);
+ var n = ascendDom(e.target, makeNotTagName("th"));
+ if(n && n !== e.target && dom.isDescendant(e.target, n)){ x += n.firstChild.offsetLeft; }
+ return x;
+ };
+ }
+ return view;
+ },
+ destroy: function(){
+ // summary:
+ // Destroy all resources
+ delete this._nls;
+ this.pluginMgr.destroy();
+ this.inherited(arguments);
+ }
+});
+
+declare("dojox.grid.enhanced.DataSelection", DataSelection, {
+ constructor: function(grid){
+ if(grid.keepSelection){
+ if(this.preserver){
+ this.preserver.destroy();
+ }
+ this.preserver = new _SelectionPreserver(this);
+ }
+ },
+ _range: function(inFrom, inTo){
+ this.grid._selectingRange = true;
+ this.inherited(arguments);
+ this.grid._selectingRange = false;
+ this.onChanged();
+ },
+ deselectAll: function(inItemOrIndex){
+ this.grid._selectingRange = true;
+ this.inherited(arguments);
+ this.grid._selectingRange = false;
+ this.onChanged();
+ }
+});
+
+EnhancedGrid.markupFactory = function(props, node, ctor, cellFunc){
+ return dojox.grid._Grid.markupFactory(props, node, ctor,
+ lang.partial(DataGrid.cell_markupFactory, cellFunc));
+};
+
+EnhancedGrid.registerPlugin = function(clazz, props){
+ _PluginManager.registerPlugin(clazz, props);
+};
+
+return EnhancedGrid;
+
+}); \ No newline at end of file
diff --git a/js/dojo-1.7.2/dojox/grid/LazyTreeGrid.js b/js/dojo-1.7.2/dojox/grid/LazyTreeGrid.js
new file mode 100644
index 0000000..3ad3030
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/LazyTreeGrid.js
@@ -0,0 +1,837 @@
+//>>built
+require({cache:{
+'url:dojox/grid/resources/Expando.html':"<div class=\"dojoxGridExpando\"\n\t><div class=\"dojoxGridExpandoNode\" dojoAttachEvent=\"onclick:onToggle\"\n\t\t><div class=\"dojoxGridExpandoNodeInner\" dojoAttachPoint=\"expandoInner\"></div\n\t></div\n></div>\n"}});
+define("dojox/grid/LazyTreeGrid", [
+ "dojo/_base/kernel",
+ "dojo/_base/declare",
+ "dojo/_base/lang",
+ "dojo/_base/event",
+ "dojo/_base/array",
+ "dojo/query",
+ "dojo/parser",
+ "dojo/dom-construct",
+ "dojo/dom-class",
+ "dojo/dom-style",
+ "dojo/dom-geometry",
+ "dojo/dom",
+ "dojo/keys",
+ "dojo/text!./resources/Expando.html",
+ "dijit/_Widget",
+ "dijit/_TemplatedMixin",
+ "./TreeGrid",
+ "./_Builder",
+ "./_View",
+ "./_Layout",
+ "./cells/tree",
+ "./_RowManager",
+ "./_FocusManager",
+ "./_EditManager",
+ "./DataSelection",
+ "./util"
+], function(dojo, declare, lang, event, array, query, parser, domConstruct,
+ domClass, domStyle, domGeometry, dom, keys, template, _widget, _templatedMixin,
+ TreeGrid, _Builder, _View, _Layout, TreeCell, _RowManager, _FocusManager, _EditManager, DataSelection, util){
+
+var _LazyExpando = declare("dojox.grid._LazyExpando", [_widget, _templatedMixin], {
+ grid: null,
+ view: null,
+ rowIdx: -1,
+ cellIdx: -1,
+ level: 0,
+ itemId: "",
+ templateString: template,
+ onToggle: function(evt){
+ // summary:
+ // The onclick handler of expando, expand/collapse a tree node if has children.
+ if(this.grid._treeCache.items[this.rowIdx]){
+ this.grid.focus.setFocusIndex(this.rowIdx, this.cellIdx);
+ this.setOpen(!this.grid._treeCache.items[this.rowIdx].opened);
+ try{
+ event.stop(evt);
+ }catch(e){}
+ }
+ },
+ setOpen: function(open){
+ // summary:
+ // expand/collapse the row where the expando is in.
+ var g = this.grid,
+ item = g._by_idx[this.rowIdx].item;
+ if(item && g.treeModel.mayHaveChildren(item) && !g._loading && g._treeCache.items[this.rowIdx].opened !== open){
+ g._treeCache.items[this.rowIdx].opened = open;
+ g.expandoFetch(this.rowIdx, open);
+ this._updateOpenState(item);
+ }
+ },
+ _updateOpenState: function(item){
+ var g = this.grid, state;
+ if(item && g.treeModel.mayHaveChildren(item)){
+ state = g._treeCache.items[this.rowIdx].opened;
+ this.expandoInner.innerHTML = state ? "-" : "+";
+ domClass.toggle(this.domNode, "dojoxGridExpandoOpened", state);
+ this.domNode.parentNode.setAttribute("aria-expanded", state);
+ }else{
+ domClass.remove(this.domNode, "dojoxGridExpandoOpened");
+ }
+ },
+ setRowNode: function(rowIdx, rowNode, view){
+ if(this.cellIdx < 0 || !this.itemId){
+ return false;
+ }
+ this.view = view;
+ this.grid = view.grid;
+ this.rowIdx = rowIdx;
+ var marginPos = this.grid.isLeftToRight() ? "marginLeft" : "marginRight";
+ domStyle.set(this.domNode.parentNode, marginPos, (this.level * 1.125) + "em");
+ this._updateOpenState(this.grid._by_idx[this.rowIdx].item);
+ return true;
+ }
+});
+
+var _TreeGridContentBuilder = declare("dojox.grid._TreeGridContentBuilder", _Builder._ContentBuilder, {
+ generateHtml: function(inDataIndex, rowIndex){
+ var html = this.getTableArray(),
+ grid = this.grid,
+ v = this.view,
+ cells = v.structure.cells,
+ item = grid.getItem(rowIndex),
+ level = 0,
+ toggleClass = "",
+ treePath = grid._treeCache.items[rowIndex] ? grid._treeCache.items[rowIndex].treePath : null;
+ util.fire(this.view, "onBeforeRow", [rowIndex, cells]);
+ if(item && lang.isArray(treePath)){
+ level = treePath.length;
+ toggleClass = grid.treeModel.mayHaveChildren(item) ? "" : "dojoxGridNoChildren";
+ }
+ var i = 0, j = 0, row, cell,
+ mergedCells, totalWidth = 0, totalWidthes = [];
+ for(; row = cells[j]; j++){
+ if(row.hidden || row.header){
+ continue;
+ }
+ html.push('<tr class="' + toggleClass + '">');
+ // cell merge
+ mergedCells = this._getColSpans(level);
+ if(mergedCells){
+ array.forEach(mergedCells, function(c){
+ for(i = 0; cell = row[i]; i++){
+ if(i >= c.start && i <= c.end){
+ totalWidth += this._getCellWidth(row, i);
+ }
+ }
+ totalWidthes.push(totalWidth);
+ totalWidth = 0;
+ }, this);
+ }
+ var m, cc, cs, pbm, k = 0;
+ for(i = 0; cell = row[i]; i++){
+ m = cell.markup;
+ cc = cell.customClasses = [];
+ cs = cell.customStyles = [];
+ if(mergedCells && mergedCells[k] && (i >= mergedCells[k].start && i <= mergedCells[k].end)){
+ var primaryIdx = mergedCells[k].primary || mergedCells[k].start;
+ if(i == primaryIdx){
+ m[5] = cell.formatAtLevel(item, level, rowIndex);
+ m[1] = cc.join(' ');
+ pbm = domGeometry.getMarginBox(cell.getHeaderNode()).w - domGeometry.getContentBox(cell.getHeaderNode()).w;
+ cs = cell.customStyles = ['width:' + (totalWidthes[k] - pbm) + "px"];
+ m[3] = cs.join(';');
+ html.push.apply(html, m);
+ }else if(i == mergedCells[k].end){
+ k++;
+ continue;
+ }else{
+ continue;
+ }
+ }else{
+ m[5] = cell.formatAtLevel(item, level, rowIndex);
+ m[1] = cc.join(' ');
+ m[3] = cs.join(';');
+ html.push.apply(html, m);
+ }
+ }
+ html.push('</tr>');
+ }
+ html.push('</table>');
+ return html.join(''); // String
+ },
+ _getColSpans: function(level){
+ var colSpans = this.grid.colSpans;
+ return colSpans && colSpans[level] ? colSpans[level] : null;
+ },
+ _getCellWidth: function(cells, colIndex){
+ var curCell = cells[colIndex], node = curCell.getHeaderNode();
+ if(curCell.hidden){
+ return 0;
+ }
+ if(colIndex == cells.length - 1 || array.every(cells.slice(colIndex + 1), function(cell){
+ return cell.hidden;
+ })){
+ var headerNodePos = domGeometry.position(cells[colIndex].view.headerContentNode.firstChild);
+ return headerNodePos.x + headerNodePos.w - domGeometry.position(node).x;
+ }else{
+ var nextCell;
+ do{
+ nextCell = cells[++colIndex];
+ }while(nextCell.hidden);
+ return domGeometry.position(nextCell.getHeaderNode()).x - domGeometry.position(node).x;
+ }
+ }
+});
+
+declare("dojox.grid._TreeGridView", _View, {
+ _contentBuilderClass: _TreeGridContentBuilder,
+ postCreate: function(){
+ this.inherited(arguments);
+ this._expandos = {};
+ this.connect(this.grid, '_onCleanupExpandoCache', '_cleanupExpandoCache');
+ },
+ destroy: function(){
+ this._cleanupExpandoCache();
+ this.inherited(arguments);
+ },
+ _cleanupExpandoCache: function(identity){
+ if(identity && this._expandos[identity]){
+ this._expandos[identity].destroy();
+ delete this._expandos[identity];
+ }else{
+ var i;
+ for(i in this._expandos){
+ this._expandos[i].destroy();
+ }
+ this._expandos = {};
+ }
+ },
+ onAfterRow: function(rowIndex, cells, rowNode){
+ query("span.dojoxGridExpando", rowNode).forEach(function(n){
+ if(n && n.parentNode){
+ var idty, expando, _byIdx = this.grid._by_idx;
+ if(_byIdx && _byIdx[rowIndex] && _byIdx[rowIndex].idty){
+ idty = _byIdx[rowIndex].idty;
+ expando = this._expandos[idty];
+ }
+ if(expando){
+ domConstruct.place(expando.domNode, n, "replace");
+ expando.itemId = n.getAttribute("itemId");
+ expando.cellIdx = parseInt(n.getAttribute("cellIdx"), 10);
+ if(isNaN(expando.cellIdx)){
+ expando.cellIdx = -1;
+ }
+ }else{
+ expando = parser.parse(n.parentNode)[0];
+ if(idty){
+ this._expandos[idty] = expando;
+ }
+ }
+ if(!expando.setRowNode(rowIndex, rowNode, this)){
+ expando.domNode.parentNode.removeChild(expando.domNode);
+ }
+ domConstruct.destroy(n);
+ }
+ }, this);
+ this.inherited(arguments);
+ },
+ updateRow: function(rowIndex){
+ var grid = this.grid, item;
+ if(grid.keepSelection){
+ item = grid.getItem(rowIndex);
+ if(item){
+ grid.selection.preserver._reSelectById(item, rowIndex);
+ }
+ }
+ this.inherited(arguments);
+ }
+});
+
+var LazyTreeCell = lang.mixin(lang.clone(TreeCell), {
+ formatAtLevel: function(item, level, rowIndex){
+ if(!item){
+ return this.formatIndexes(rowIndex, item, level);
+ }
+ var result = "", ret = "", content;
+ if(this.isCollapsable && this.grid.store.isItem(item)){
+ ret = '<span ' + dojo._scopeName + 'Type="dojox.grid._LazyExpando" level="' + level + '" class="dojoxGridExpando"' +
+ ' itemId="' + this.grid.store.getIdentity(item) + '" cellIdx="' + this.index + '"></span>';
+ }
+ content = this.formatIndexes(rowIndex, item, level);
+ result = ret !== "" ? '<div>' + ret + content + '</div>' : content;
+ return result;
+ },
+ formatIndexes: function(rowIndex, item, level){
+ var info = this.grid.edit.info,
+ d = this.get ? this.get(rowIndex, item) : (this.value || this.defaultValue);
+ if(this.editable && (this.alwaysEditing || (info.rowIndex === rowIndex && info.cell === this))){
+ return this.formatEditing(d, rowIndex);
+ }else{
+ return this._defaultFormat(d, [d, rowIndex, level, this]);
+ }
+ }
+});
+
+var _LazyTreeLayout = declare("dojox.grid._LazyTreeLayout", _Layout, {
+ // summary:
+ // Override the dojox.grid._TreeLayout to modify the _TreeGridView and cell formatter
+ setStructure: function(structure){
+ var g = this.grid, s = structure;
+ if(g && !array.every(s, function(i){
+ return !!i.cells;
+ })){
+ s = arguments[0] = [{cells:[s]}];//intentionally change arguments[0]
+ }
+ if(s.length === 1 && s[0].cells.length === 1){
+ s[0].type = "dojox.grid._TreeGridView";
+ this._isCollapsable = true;
+ s[0].cells[0][this.grid.expandoCell].isCollapsable = true;
+ }
+ this.inherited(arguments);
+ },
+ addCellDef: function(rowIndex, cellIndex, def){
+ var obj = this.inherited(arguments);
+ return lang.mixin(obj, LazyTreeCell);
+ }
+});
+
+var _LazyTreeGridCache = declare("dojox.grid._LazyTreeGridCache", null, {
+ // summary:
+ // An internal object used to cache the tree path and open state of each item.
+ // The form of the cache items would be an object array:
+ // [{opened: true/false, treePath: [level0 parent id, level1 parent id, ...]}]
+ // example:
+ // | [{opened: true, treePath: []},
+ // | {opened: false, treePath: ["root0"]},
+ // | {opened: false, treePath: ["root0"]},
+ // | {opened: false, treePath: []},
+ // | ...]
+ constructor: function(){
+ this.items = [];
+ },
+ getSiblingIndex: function(rowIndex, treePath){
+ var i = rowIndex - 1, indexCount = 0, tp;
+ for(; i >=0; i--){
+ tp = this.items[i] ? this.items[i].treePath : [];
+ if(tp.join('/') === treePath.join('/')){
+ indexCount++;
+ }else if(tp.length < treePath.length){
+ break;
+ }
+ }
+ return indexCount;
+ },
+ removeChildren: function(rowIndex){
+ // find next sibling index
+ var i = rowIndex + 1, count, tp,
+ treePath = this.items[rowIndex] ? this.items[rowIndex].treePath : [];
+ for(; i < this.items.length; i++){
+ tp = this.items[i] ? this.items[i].treePath : [];
+ if(tp.join('/') === treePath.join('/') || tp.length <= treePath.length){
+ break;
+ }
+ }
+ count = i - (rowIndex + 1);
+ this.items.splice(rowIndex + 1, count);
+ return count;
+ }
+});
+
+var LazyTreeGrid = declare("dojox.grid.LazyTreeGrid", TreeGrid, {
+ // summary:
+ // An enhanced TreeGrid widget which supports lazy-loading for nested children items
+ //
+ // description:
+ // LazyTreeGrid inherits from dojo.grid.TreeGrid and applies virtual scrolling mechanism
+ // to nested children rows so that it's possible to deal with complex tree structure data set
+ // with nested and huge children rows. It's also compatible with dijit.tree.ForestStoreModel
+ //
+ // Most methods and properties pertaining to dojox.grid.DataGrid
+ // and dojox.grid.TreeGrid also apply here
+ //
+ // LazyTreeGrid does not support summary row/items aggregate due to the lazy-loading rationale.
+ _layoutClass: _LazyTreeLayout,
+ _size: 0,
+ // treeModel: dijit.tree.ForestStoreModel | dojox.grid.LazyTreeGridStoreModel
+ // A tree store model object.
+ treeModel: null,
+ // defaultState: Object
+ // Used to restore the state of LazyTreeGrid.
+ // This object should ONLY be obtained from `LazyTreeGrid.getState()`.
+ defaultState: null,
+ // colSpans: Object
+ // a json object that defines column span of each level rows
+ // attributes:
+ // 0/1/..: which level need to colspan
+ // start: start column index of colspan
+ // end: end column index of colspan
+ // primary: index of column which content will be displayed (default is value of start).
+ // example:
+ // | colSpans = {
+ // | 0: [
+ // | {start: 0, end: 1, primary: 0},
+ // | {start: 2, end: 4, primary: 3}
+ // | ],
+ // | 1: [
+ // | {start: 0, end: 3, primary: 1}
+ // | ]
+ // | };
+ colSpans: null,
+
+ postCreate: function(){
+ this._setState();
+ this.inherited(arguments);
+ if(!this._treeCache){
+ this._treeCache = new _LazyTreeGridCache();
+ }
+ if(!this.treeModel || !(this.treeModel instanceof dijit.tree.ForestStoreModel)){
+ throw new Error("dojox.grid.LazyTreeGrid: must be used with a treeModel which is an instance of dijit.tree.ForestStoreModel");
+ }
+ domClass.add(this.domNode, "dojoxGridTreeModel");
+ dom.setSelectable(this.domNode, this.selectable);
+ },
+ createManagers: function(){
+ this.rows = new _RowManager(this);
+ this.focus = new _FocusManager(this);
+ this.edit = new _EditManager(this);
+ },
+ createSelection: function(){
+ this.selection = new DataSelection(this);
+ },
+ setModel: function(treeModel){
+ if(!treeModel){
+ return;
+ }
+ this._setModel(treeModel);
+ this._cleanup();
+ this._refresh(true);
+ },
+ setStore: function(store, query, queryOptions){
+ if(!store){
+ return;
+ }
+ this._setQuery(query, queryOptions);
+ this.treeModel.query = query;
+ this.treeModel.store = store;
+ this.treeModel.root.children = [];
+ this.setModel(this.treeModel);
+ },
+ onSetState: function(){
+ // summary:
+ // Event fired when a default state being set.
+ },
+ _setState: function(){
+ if(this.defaultState){
+ this._treeCache = this.defaultState.cache;
+ this.sortInfo = this.defaultState.sortInfo || 0;
+ this.query = this.defaultState.query || this.query;
+ this._lastScrollTop = this.defaultState.scrollTop;
+ if(this.keepSelection){
+ this.selection.preserver._selectedById = this.defaultState.selection;
+ }else{
+ this.selection.selected = this.defaultState.selection || [];
+ }
+ this.onSetState();
+ }
+ },
+ getState: function(){
+ // summary:
+ // Get the current state of LazyTreeGrid including expanding, sorting, selection and scroll top state.
+ var _this = this,
+ selection = this.keepSelection ? this.selection.preserver._selectedById : this.selection.selected;
+ return {
+ cache: lang.clone(_this._treeCache),
+ query: lang.clone(_this.query),
+ sortInfo: lang.clone(_this.sortInfo),
+ scrollTop: lang.clone(_this.scrollTop),
+ selection: lang.clone(selection)
+ };
+ },
+ _setQuery: function(query, queryOptions){
+ this.inherited(arguments);
+ this.treeModel.query = query;
+ },
+ filter: function(query, reRender){
+ this._cleanup();
+ this.inherited(arguments);
+ },
+ destroy: function(){
+ this._cleanup();
+ this.inherited(arguments);
+ },
+ expand: function(itemId){
+ // summary:
+ // Expand the row with the given itemId.
+ // id: string?
+ this._fold(itemId, true);
+ },
+ collapse: function(itemId){
+ // summary:
+ // Collapse the row with the given itemId.
+ // id: string?
+ this._fold(itemId, false);
+ },
+ refresh: function(keepState){
+ // summary:
+ // Refresh, and persist the expand/collapse state when keepState equals true
+ // keepState: boolean
+ if(!keepState){
+ this._cleanup();
+ }
+ this._refresh(true);
+ },
+ _cleanup: function(){
+ this._treeCache.items = [];
+ this._onCleanupExpandoCache();
+ },
+ setSortIndex: function(inIndex, inAsc){
+ // Need to clean up the cache before sorting
+ if(this.canSort(inIndex + 1)){
+ this._cleanup();
+ }
+ this.inherited(arguments);
+ },
+ _refresh: function(isRender){
+ this._clearData();
+ this.updateRowCount(this._size);
+ this._fetch(0, true);
+ },
+ render: function(){
+ this.inherited(arguments);
+ this.setScrollTop(this.scrollTop);
+ },
+ _onNew: function(item, parentInfo){
+ var addingChild = parentInfo && this.store.isItem(parentInfo.item) && array.some(this.treeModel.childrenAttrs, function(c){
+ return c === parentInfo.attribute;
+ });
+ var items = this._treeCache.items, byIdx = this._by_idx;
+ if(!addingChild){
+ items.push({opened: false, treePath: []});
+ this._size += 1;
+ this.inherited(arguments);
+ }else{
+ var parentItem = parentInfo.item,
+ parentIdty = this.store.getIdentity(parentItem),
+ rowIndex = -1, i = 0;
+ for(; i < byIdx.length; i++){
+ if(parentIdty === byIdx[i].idty){
+ rowIndex = i;
+ break;
+ }
+ }
+ if(rowIndex >= 0){
+ if(items[rowIndex] && items[rowIndex].opened){
+ var parentTreePath = items[rowIndex].treePath, pos = rowIndex + 1;
+ for(; pos < items.length; pos++){
+ if(items[pos].treePath.length <= parentTreePath.length){
+ break;
+ }
+ }
+ var treePath = parentTreePath.slice();
+ treePath.push(parentIdty);
+ this._treeCache.items.splice(pos, 0, {opened: false, treePath: treePath});
+ // update grid._by_idx
+ var idty = this.store.getIdentity(item);
+ this._by_idty[idty] = { idty: idty, item: item };
+ byIdx.splice(pos, 0, this._by_idty[idty]);
+ // update grid
+ this._size += 1;
+ this.updateRowCount(this._size);
+ this._updateRenderedRows(pos);
+ }else{
+ this.updateRow(rowIndex);
+ }
+ }
+ }
+ },
+ _onDelete: function(item){
+ var i = 0, rowIndex = -1, idty = this.store.getIdentity(item);
+ for(; i < this._by_idx.length; i++){
+ if(idty === this._by_idx[i].idty){
+ rowIndex = i;
+ break;
+ }
+ }
+ if(rowIndex >= 0){
+ var items = this._treeCache.items, treePath = items[rowIndex] ? items[rowIndex].treePath : [], tp, count = 1;
+ i = rowIndex + 1;
+ for(; i < this._size; i++, count++){
+ tp = items[i] ? items[i].treePath : [];
+ if(items[i].treePath.length <= treePath.length){
+ break;
+ }
+ }
+ items.splice(rowIndex, count);
+ this._onCleanupExpandoCache(idty);
+ this._by_idx.splice(rowIndex, count);
+ this._size -= count;
+ this.updateRowCount(this._size);
+ this._updateRenderedRows(rowIndex);
+ }
+ },
+ _onCleanupExpandoCache: function(identity){},
+ _fetch: function(start, isRender){
+ if(!this._loading){
+ this._loading = true;
+ }
+ start = start || 0;
+ var count = this._size - start > 0 ? Math.min(this.rowsPerPage, this._size - start) : this.rowsPerPage;
+ var i = 0;
+ var fetchedItems = [];
+ this._reqQueueLen = 0;
+ for(; i < count; i++){
+ if(this._by_idx[start + i]){
+ fetchedItems.push(this._by_idx[start + i].item);
+ }else{
+ break;
+ }
+ }
+ if(fetchedItems.length === count){
+ this._reqQueueLen = 1;
+ this._onFetchBegin(this._size, {startRowIdx: start, count: count});
+ this._onFetchComplete(fetchedItems, {startRowIdx: start, count: count});
+ }else{
+ var level, nextLevel, len = 1, items = this._treeCache.items,
+ treePath = items[start] ? items[start].treePath : [];
+ for(i = 1; i < count; i++){
+ level = items[start + len - 1] ? items[start + len - 1].treePath.length : 0;
+ nextLevel = items[start + len] ? items[start + len].treePath.length : 0;
+ if(level !== nextLevel){
+ this._reqQueueLen++;
+ this._fetchItems({startRowIdx: start, count: len, treePath: treePath});
+ start = start + len;
+ len = 1;
+ treePath = items[start] ? items[start].treePath : 0;
+ }else{
+ len++;
+ }
+ }
+ this._reqQueueLen++;
+ this._fetchItems({startRowIdx: start, count: len, treePath: treePath});
+ }
+ },
+ _fetchItems: function(req){
+ if(this._pending_requests[req.startRowIdx]){
+ return;
+ }
+ this.showMessage(this.loadingMessage);
+ this._pending_requests[req.startRowIdx] = true;
+ var onError = lang.hitch(this, '_onFetchError'),
+ start = this._treeCache.getSiblingIndex(req.startRowIdx, req.treePath);
+ if(req.treePath.length === 0){
+ this.store.fetch({
+ start: start,
+ startRowIdx: req.startRowIdx,
+ treePath: req.treePath,
+ count: req.count,
+ query: this.query,
+ sort: this.getSortProps(),
+ queryOptions: this.queryOptions,
+ onBegin: lang.hitch(this, '_onFetchBegin'),
+ onComplete: lang.hitch(this, '_onFetchComplete'),
+ onError: lang.hitch(this, '_onFetchError')
+ });
+ }else{
+ var parentId = req.treePath[req.treePath.length - 1], parentItem;
+ var queryObj = {
+ start: start,
+ startRowIdx: req.startRowIdx,
+ treePath: req.treePath,
+ count: req.count,
+ parentId: parentId,
+ sort: this.getSortProps()
+ };
+ var _this = this;
+ var onComplete = function(){
+ var f = lang.hitch(_this, '_onFetchComplete');
+ if(arguments.length == 1){
+ f.apply(_this, [arguments[0], queryObj]);
+ }else{
+ f.apply(_this, arguments);
+ }
+ };
+ if(this._by_idty[parentId]){
+ parentItem = this._by_idty[parentId].item;
+ this.treeModel.getChildren(parentItem, onComplete, onError, queryObj);
+ }else{
+ this.store.fetchItemByIdentity({
+ identity: parentId,
+ onItem: function(item){
+ _this.treeModel.getChildren(item, onComplete, onError, queryObj);
+ },
+ onError: onError
+ });
+ }
+ }
+ },
+ _onFetchBegin: function(size, request){
+ if(this._treeCache.items.length === 0){
+ this._size = parseInt(size, 10);
+ }
+ size = this._size;
+ // this._size = size = this._treeCache.items.length;
+ this.inherited(arguments);
+ },
+ _onFetchComplete: function(items, request){
+ var startRowIdx = request.startRowIdx,
+ count = request.count,
+ start = items.length <= count ? 0: request.start,
+ treePath = request.treePath || [];
+ if(lang.isArray(items) && items.length > 0){
+ var i = 0, len = Math.min(count, items.length);
+ for(; i < len; i++){
+ if(!this._treeCache.items[startRowIdx + i]){
+ this._treeCache.items[startRowIdx + i] = {opened: false, treePath: treePath};
+ }
+ if(!this._by_idx[startRowIdx + i]){
+ this._addItem(items[start + i], startRowIdx + i, true);
+ }
+ // this._treeCache.items.splice(startRowIdx + i, 0, {opened: false, treePath: treePath});
+ }
+ this.updateRows(startRowIdx, len);
+ }
+ if(this._size == 0){
+ this.showMessage(this.noDataMessage);
+ }else{
+ this.showMessage();
+ }
+ this._pending_requests[startRowIdx] = false;
+ this._reqQueueLen--;
+ if(this._loading && this._reqQueueLen === 0){
+ this._loading = false;
+ if(this._lastScrollTop){
+ this.setScrollTop(this._lastScrollTop);
+ }
+ }
+ },
+ expandoFetch: function(rowIndex, open){
+ // summary:
+ // Function for fetch children of a given row
+ if(this._loading || !this._by_idx[rowIndex]){return;}
+ this._loading = true;
+ this._toggleLoadingClass(rowIndex, true);
+ this.expandoRowIndex = rowIndex;
+ var item = this._by_idx[rowIndex].item;
+ // this._pages = [];
+ if(open){
+ var queryObj = {
+ start: 0,
+ count: this.rowsPerPage,
+ parentId: this.store.getIdentity(this._by_idx[rowIndex].item),
+ sort: this.getSortProps()
+ };
+ this.treeModel.getChildren(item, lang.hitch(this, "_onExpandoComplete"), lang.hitch(this, "_onFetchError"), queryObj);
+ }else{
+ // get the whole children number when clear the children from cache
+ var num = this._treeCache.removeChildren(rowIndex);
+ // remove the items from grid._by_idx
+ this._by_idx.splice(rowIndex + 1, num);
+ this._bop = this._eop = -1;
+ //update grid
+ this._size -= num;
+ this.updateRowCount(this._size);
+ this._updateRenderedRows(rowIndex + 1);
+ this._toggleLoadingClass(rowIndex, false);
+ if(this._loading){
+ this._loading = false;
+ }
+ this.focus._delayedCellFocus();
+ }
+ },
+ _onExpandoComplete: function(childItems, request, size){
+ size = isNaN(size) ? childItems.length : parseInt(size, 10);
+ var treePath = this._treeCache.items[this.expandoRowIndex].treePath.slice(0);
+ treePath.push(this.store.getIdentity(this._by_idx[this.expandoRowIndex].item));
+ var i = 1, idty;
+ for(; i <= size; i++){
+ this._treeCache.items.splice(this.expandoRowIndex + i, 0, {treePath: treePath, opened: false});
+ }
+ this._size += size;
+ this.updateRowCount(this._size);
+ for(i = 0; i < size; i++){
+ if(childItems[i]){
+ idty = this.store.getIdentity(childItems[i]);
+ this._by_idty[idty] = { idty: idty, item: childItems[i] };
+ this._by_idx.splice(this.expandoRowIndex + 1 + i, 0, this._by_idty[idty]);
+ }else{
+ this._by_idx.splice(this.expandoRowIndex + 1 + i, 0, null);
+ }
+ }
+ this._updateRenderedRows(this.expandoRowIndex + 1);
+ this._toggleLoadingClass(this.expandoRowIndex, false);
+ this.stateChangeNode = null;
+ if(this._loading){
+ this._loading = false;
+ }
+ if(this.autoHeight === true){
+ this._resize();
+ }
+ this.focus._delayedCellFocus();
+ },
+ styleRowNode: function(rowIndex, rowNode){
+ if(rowNode){
+ this.rows.styleRowNode(rowIndex, rowNode);
+ }
+ },
+ onStyleRow: function(row){
+ if(!this.layout._isCollapsable){
+ this.inherited(arguments);
+ return;
+ }
+ row.customClasses = (row.odd ? " dojoxGridRowOdd" : "") + (row.selected ? " dojoxGridRowSelected" : "") + (row.over ? " dojoxGridRowOver" : "");
+ this.focus.styleRow(row);
+ this.edit.styleRow(row);
+ },
+ onKeyDown: function(e){
+ if(e.altKey || e.metaKey){
+ return;
+ }
+ var expando = dijit.findWidgets(e.target)[0];
+ if(e.keyCode === keys.ENTER && expando instanceof _LazyExpando){
+ expando.onToggle();
+ }
+ this.inherited(arguments);
+ },
+ _toggleLoadingClass: function(rowIndex, flag){
+ var views = this.views.views, node,
+ rowNode = views[views.length - 1].getRowNode(rowIndex);
+ if(rowNode){
+ node = query('.dojoxGridExpando', rowNode)[0];
+ if(node){
+ domClass.toggle(node, "dojoxGridExpandoLoading", flag);
+ }
+ }
+ },
+ _updateRenderedRows: function(start){
+ array.forEach(this.scroller.stack, function(p){
+ if(p * this.rowsPerPage >= start){
+ this.updateRows(p * this.rowsPerPage, this.rowsPerPage);
+ }else if((p + 1) * this.rowsPerPage >= start){
+ this.updateRows(start, (p + 1) * this.rowsPerPage - start + 1);
+ }
+ }, this);
+ },
+ _fold: function(itemId, open){
+ var rowIndex = -1, i = 0, byIdx = this._by_idx, idty = this._by_idty[itemId];
+ if(idty && idty.item && this.treeModel.mayHaveChildren(idty.item)){
+ for(; i < byIdx.length; i++){
+ if(byIdx[i] && byIdx[i].idty === itemId){
+ rowIndex = i;
+ break;
+ }
+ }
+ if(rowIndex >= 0){
+ var rowNode = this.views.views[this.views.views.length - 1].getRowNode(rowIndex);
+ if(rowNode){
+ var expando = dijit.findWidgets(rowNode)[0];
+ if(expando){
+ expando.setOpen(open);
+ }
+ }
+ }
+ }
+ }
+});
+
+LazyTreeGrid.markupFactory = function(props, node, ctor, cellFunc){
+ return TreeGrid.markupFactory(props, node, ctor, cellFunc);
+};
+
+return LazyTreeGrid;
+
+}); \ No newline at end of file
diff --git a/js/dojo-1.7.2/dojox/grid/LazyTreeGridStoreModel.js b/js/dojo-1.7.2/dojox/grid/LazyTreeGridStoreModel.js
new file mode 100644
index 0000000..340fbe3
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/LazyTreeGridStoreModel.js
@@ -0,0 +1,114 @@
+//>>built
+define("dojox/grid/LazyTreeGridStoreModel", [
+ "dojo/_base/declare",
+ "dojo/_base/array",
+ "dojo/_base/lang",
+ "dijit/tree/ForestStoreModel"], function(declare, array, lang, ForestStoreModel){
+
+return declare("dojox.grid.LazyTreeGridStoreModel", ForestStoreModel, {
+
+ // There are different approaches to get children for client-side
+ // DataStore (e.g. dojo.data.ItemFileReadStore) or server-side DataStore
+ // (e.g. dojox.data.QueryReadStore), so we need to be sure what kind of
+ // DataStore is being used
+ serverStore: false, // server side store
+
+ constructor: function(/* Object */ args){
+ this.serverStore = !!args.serverStore;
+ },
+
+ mayHaveChildren: function(/*dojo.data.Item*/ item){
+ var children = null;
+ return array.some(this.childrenAttrs, function(attr){
+ children = this.store.getValue(item, attr);
+ if(lang.isString(children)){
+ return parseInt(children, 10) > 0 || children.toLowerCase() === "true" ? true : false;
+ }else if(typeof children == "number"){
+ return children > 0;
+ }else if(typeof children == "boolean"){
+ return children;
+ }else if(this.store.isItem(children)){
+ children = this.store.getValues(item, attr);
+ return lang.isArray(children) ? children.length > 0 : false;
+ }else{
+ return false;
+ }
+ }, this);
+ },
+
+ getChildren: function(/*dojo.data.Item*/parentItem, /*function(items, size)*/onComplete, /*function*/ onError, /*object*/queryObj){
+ if(queryObj){
+ var start = queryObj.start || 0,
+ count = queryObj.count,
+ parentId = queryObj.parentId,
+ sort = queryObj.sort;
+ if(parentItem === this.root){
+ this.root.size = 0;
+ this.store.fetch({
+ start: start,
+ count: count,
+ sort: sort,
+ query: this.query,
+ onBegin: lang.hitch(this, function(size){
+ this.root.size = size;
+ }),
+ onComplete: lang.hitch(this, function(items){
+ onComplete(items, queryObj, this.root.size);
+ }),
+ onError: onError
+ });
+ }else{
+ var store = this.store;
+ if(!store.isItemLoaded(parentItem)){
+ var getChildren = lang.hitch(this, arguments.callee);
+ store.loadItem({
+ item: parentItem,
+ onItem: function(parentItem){
+ getChildren(parentItem, onComplete, onError, queryObj);
+ },
+ onError: onError
+ });
+ return;
+ }
+ if(this.serverStore && !this._isChildrenLoaded(parentItem)){
+ this.childrenSize = 0;
+ this.store.fetch({
+ start: start,
+ count: count,
+ sort: sort,
+ query: lang.mixin({parentId: parentId}, this.query || {}),
+ onBegin: lang.hitch(this, function(size){
+ this.childrenSize = size;
+ }),
+ onComplete: lang.hitch(this, function(items){
+ onComplete(items, queryObj, this.childrenSize);
+ }),
+ onError: onError
+ });
+ }else{
+ this.inherited(arguments);
+ }
+ }
+ }else{
+ this.inherited(arguments);
+ }
+ },
+
+ _isChildrenLoaded: function(parentItem){
+ // summary:
+ // Check if all children of the given item have been loaded
+ var children = null;
+ return array.every(this.childrenAttrs, function(attr){
+ children = this.store.getValues(parentItem, attr);
+ return array.every(children, function(c){
+ return this.store.isItemLoaded(c);
+ }, this);
+ }, this);
+ },
+
+ //overwritten
+ onNewItem: function(item, parentInfo){ },
+
+ onDeleteItem: function(item){ }
+});
+});
diff --git a/js/dojo-1.7.2/dojox/grid/README b/js/dojo-1.7.2/dojox/grid/README
new file mode 100644
index 0000000..91b762c
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/README
@@ -0,0 +1,151 @@
+-------------------------------------------------------------------------------
+dojox.grid
+-------------------------------------------------------------------------------
+Version 1.00
+Release date: 10/04/2007
+-------------------------------------------------------------------------------
+Project state:
+beta
+-------------------------------------------------------------------------------
+Credits
+ Scott J. Miles (sjmiles@activegrid.com)
+ Steve Orvell (sorvell@activegrid.com)
+ Bryan Forbes (bryan AT reigndropsfall.net)
+ Nathan Toone (toonetown AT dojotoolkit.org)
+-------------------------------------------------------------------------------
+Project description
+
+TurboGrid has been made available in Dojo and is now the dojox.grid!
+
+-------------------------------------------------------------------------------
+Dependencies:
+
+Dojo Core
+Dojo Base (dnd)
+Dijit Templated Widget
+dojox.html (metrics)
+-------------------------------------------------------------------------------
+Documentation
+
+None available for this version yet.
+
+See http://www.turboajax.com/products/turbogrid/ for legacy documentation.
+-------------------------------------------------------------------------------
+Installation instructions
+
+Grab the following from the Dojo SVN Repository:
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/grid/*
+http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/html/*
+
+Install into the following directory structure:
+/dojox/grid/
+/dojox/html/
+
+...which should be at the same level as your Dojo checkout.
+
+If you wish us use the old (compat / 1.2) grid, you can untar the
+compatGrid.tar.gz archive. This version of the grid is no longer maintained
+or updated - but should work with any newer version of the dojo library.
+
+dojox.grid.* is a11y enabled, please see the following doc page for more details
+- http://dojotoolkit.org/reference-guide/dojox/grid/DataGrid.html#accessibility-in-1-3-and-beyond
+-------------------------------------------------------------------------------
+
+
+
+-------------------------------------------------------------------------------
+Sub-projects:
+-------------------------------------------------------------------------------
+
+-------------------------------------------------------------------------------
+1. dojox.grid.EnhancedGrid
+-------------------------------------------------------------------------------
+Version 0.9
+Release date: 12/11/2009
+-------------------------------------------------------------------------------
+Project state
+
+alpha
+-------------------------------------------------------------------------------
+Credits
+ David Schwartz (drschwar@us.ibm.com, IBM, CCLA) - Author, UX design
+ Wei Huang (evan@dojotoolkit.org) - Author, IndirectSelection, Menus
+ Xiao Wen Zhu (xwzhu@cn.ibm.com, IBM, CCLA)
+ - Filter, Exporter, Printer, Selector, DnD, CellMerge, Cookie, Search
+ Qiang Wang (wangqsh@cn.ibm.com, IBM, CCLA) - Pagination
+ Pei Wang (wpei@cn.ibm.com, IBM, CCLA) - NestedSorting
+-------------------------------------------------------------------------------
+Project description
+
+Enhanced Grid inherits base DataGrid and provides the following enhanced features:
+ 1. Nested Sorting
+ 2. Built-in declarative Indirect Selection (radio buttons and check boxes)
+ 3. Context menu for header, row, column and selected region
+ 4. Advanced Selector: support selecting rows/columns/cells via swipe
+ 5. Drag-n-drop: columns,rows - MOVE, cells - MOVE/COPY
+ 6. Filter: filter grid content in various data types
+ 7. Exporter: export grid content to various formats
+ 8. Printer: provide convenient ways for printing grid
+ 9. Pagination: an alternative to deal with huge data set besides the default virtual scrolling way
+ 10.CellMerge: merge adjacent cells within a row
+ 11.Cookie: persist grid preferences including column width, column order, sorting order etc.
+ 12.Search: a handy way for searching grid content by regular expressions
+-------------------------------------------------------------------------------
+Dependencies
+
+Dojo Core, dojox.grid.DataGrid
+-------------------------------------------------------------------------------
+Documentation
+
+http://dojotoolkit.org/reference-guide/dojox/grid/EnhancedGrid.html
+-------------------------------------------------------------------------------
+Installation instructions
+
+Same as dojox.grid, for detail sample usages, please refer to /dojox/grid/tests/enhanced/*.html
+-------------------------------------------------------------------------------
+Known issues
+
+ - 'Claro' is the major supported theme for EnhancedGrid features
+ - EnhancedGrid features are not fully compatible with complicated layouts (e.g. multiple rows in column header) and TreeGrid(SubGrid).
+ - Indirect Selection is not fully compatible with Advanced Selector(for selecting row/column/cells) and DnD
+ - RTL support is still in progress for Nested Sorting
+-------------------------------------------------------------------------------
+
+-------------------------------------------------------------------------------
+2. dojox.grid.LazyTreeGrid
+-------------------------------------------------------------------------------
+Version 0.9
+Release date:
+-------------------------------------------------------------------------------
+Project state
+
+alpha
+-------------------------------------------------------------------------------
+Credits
+ Qiang Wang (wangqsh@cn.ibm.com, IBM, CCLA)
+ Wei Huang (evan@dojotoolkit.org)
+-------------------------------------------------------------------------------
+Project description
+
+LazyTreeGrid applies virtual scrolling mechanism to nested children rows so that it's possible to
+deal with large data set specifically in tree structure with large number of children rows.
+It's also compatible with dijit.tree.ForestStoreModel
+-------------------------------------------------------------------------------
+Dependencies
+
+Dojo Core, dojox.grid.TreeGrid
+-------------------------------------------------------------------------------
+Documentation
+
+http://dojotoolkit.org/reference-guide/dojox/grid/LazyTreeGrid.html
+-------------------------------------------------------------------------------
+Installation instructions
+
+Same as dojox.grid, for detail sample usages, please refer to /dojox/grid/tests/test_treegrid_lazyloading.html
+-------------------------------------------------------------------------------
+Known issues
+
+LazyTreeGrid is not compatible with:
+ - Most Enhanced Grid features
+ - Complicated layouts (e.g. multiple rows in column header)
+-------------------------------------------------------------------------------
diff --git a/js/dojo-1.7.2/dojox/grid/Selection.js b/js/dojo-1.7.2/dojox/grid/Selection.js
new file mode 100644
index 0000000..56e6884
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/Selection.js
@@ -0,0 +1,267 @@
+//>>built
+define("dojox/grid/Selection", [
+ "dojo/_base/declare",
+ "dojo/_base/array",
+ "dojo/_base/lang",
+ "dojo/dom-attr"
+], function(declare, array, lang, domAttr){
+
+return declare("dojox.grid.Selection", null, {
+ // summary:
+ // Manages row selection for grid. Owned by grid and used internally
+ // for selection. Override to implement custom selection.
+
+ constructor: function(inGrid){
+ this.grid = inGrid;
+ this.selected = [];
+
+ this.setMode(inGrid.selectionMode);
+ },
+
+ mode: 'extended',
+
+ selected: null,
+ updating: 0,
+ selectedIndex: -1,
+
+ setMode: function(mode){
+ if(this.selected.length){
+ this.deselectAll();
+ }
+ if(mode != 'extended' && mode != 'multiple' && mode != 'single' && mode != 'none'){
+ this.mode = 'extended';
+ }else{
+ this.mode = mode;
+ }
+ },
+
+ onCanSelect: function(inIndex){
+ return this.grid.onCanSelect(inIndex);
+ },
+
+ onCanDeselect: function(inIndex){
+ return this.grid.onCanDeselect(inIndex);
+ },
+
+ onSelected: function(inIndex){
+ },
+
+ onDeselected: function(inIndex){
+ },
+
+ //onSetSelected: function(inIndex, inSelect) { };
+ onChanging: function(){
+ },
+
+ onChanged: function(){
+ },
+
+ isSelected: function(inIndex){
+ if(this.mode == 'none'){
+ return false;
+ }
+ return this.selected[inIndex];
+ },
+
+ getFirstSelected: function(){
+ if(!this.selected.length||this.mode == 'none'){ return -1; }
+ for(var i=0, l=this.selected.length; i<l; i++){
+ if(this.selected[i]){
+ return i;
+ }
+ }
+ return -1;
+ },
+
+ getNextSelected: function(inPrev){
+ if(this.mode == 'none'){ return -1; }
+ for(var i=inPrev+1, l=this.selected.length; i<l; i++){
+ if(this.selected[i]){
+ return i;
+ }
+ }
+ return -1;
+ },
+
+ getSelected: function(){
+ var result = [];
+ for(var i=0, l=this.selected.length; i<l; i++){
+ if(this.selected[i]){
+ result.push(i);
+ }
+ }
+ return result;
+ },
+
+ getSelectedCount: function(){
+ var c = 0;
+ for(var i=0; i<this.selected.length; i++){
+ if(this.selected[i]){
+ c++;
+ }
+ }
+ return c;
+ },
+
+ _beginUpdate: function(){
+ if(this.updating === 0){
+ this.onChanging();
+ }
+ this.updating++;
+ },
+
+ _endUpdate: function(){
+ this.updating--;
+ if(this.updating === 0){
+ this.onChanged();
+ }
+ },
+
+ select: function(inIndex){
+ if(this.mode == 'none'){ return; }
+ if(this.mode != 'multiple'){
+ this.deselectAll(inIndex);
+ this.addToSelection(inIndex);
+ }else{
+ this.toggleSelect(inIndex);
+ }
+ },
+
+ addToSelection: function(inIndex){
+ if(this.mode == 'none'){ return; }
+ if(lang.isArray(inIndex)){
+ array.forEach(inIndex, this.addToSelection, this);
+ return;
+ }
+ inIndex = Number(inIndex);
+ if(this.selected[inIndex]){
+ this.selectedIndex = inIndex;
+ }else{
+ if(this.onCanSelect(inIndex) !== false){
+ this.selectedIndex = inIndex;
+ var rowNode = this.grid.getRowNode(inIndex);
+ if(rowNode){
+ domAttr.set(rowNode, "aria-selected", "true");
+ }
+ this._beginUpdate();
+ this.selected[inIndex] = true;
+ //this.grid.onSelected(inIndex);
+ this.onSelected(inIndex);
+ //this.onSetSelected(inIndex, true);
+ this._endUpdate();
+ }
+ }
+ },
+
+ deselect: function(inIndex){
+ if(this.mode == 'none'){ return; }
+ if(lang.isArray(inIndex)){
+ array.forEach(inIndex, this.deselect, this);
+ return;
+ }
+ inIndex = Number(inIndex);
+ if(this.selectedIndex == inIndex){
+ this.selectedIndex = -1;
+ }
+ if(this.selected[inIndex]){
+ if(this.onCanDeselect(inIndex) === false){
+ return;
+ }
+ var rowNode = this.grid.getRowNode(inIndex);
+ if(rowNode){
+ domAttr.set(rowNode, "aria-selected", "false");
+ }
+ this._beginUpdate();
+ delete this.selected[inIndex];
+ //this.grid.onDeselected(inIndex);
+ this.onDeselected(inIndex);
+ //this.onSetSelected(inIndex, false);
+ this._endUpdate();
+ }
+ },
+
+ setSelected: function(inIndex, inSelect){
+ this[(inSelect ? 'addToSelection' : 'deselect')](inIndex);
+ },
+
+ toggleSelect: function(inIndex){
+ if(lang.isArray(inIndex)){
+ array.forEach(inIndex, this.toggleSelect, this);
+ return;
+ }
+ this.setSelected(inIndex, !this.selected[inIndex]);
+ },
+
+ _range: function(inFrom, inTo, func){
+ var s = (inFrom >= 0 ? inFrom : inTo), e = inTo;
+ if(s > e){
+ e = s;
+ s = inTo;
+ }
+ for(var i=s; i<=e; i++){
+ func(i);
+ }
+ },
+
+ selectRange: function(inFrom, inTo){
+ this._range(inFrom, inTo, lang.hitch(this, "addToSelection"));
+ },
+
+ deselectRange: function(inFrom, inTo){
+ this._range(inFrom, inTo, lang.hitch(this, "deselect"));
+ },
+
+ insert: function(inIndex){
+ this.selected.splice(inIndex, 0, false);
+ if(this.selectedIndex >= inIndex){
+ this.selectedIndex++;
+ }
+ },
+
+ remove: function(inIndex){
+ this.selected.splice(inIndex, 1);
+ if(this.selectedIndex >= inIndex){
+ this.selectedIndex--;
+ }
+ },
+
+ deselectAll: function(inExcept){
+ for(var i in this.selected){
+ if((i!=inExcept)&&(this.selected[i]===true)){
+ this.deselect(i);
+ }
+ }
+ },
+
+ clickSelect: function(inIndex, inCtrlKey, inShiftKey){
+ if(this.mode == 'none'){ return; }
+ this._beginUpdate();
+ if(this.mode != 'extended'){
+ this.select(inIndex);
+ }else{
+ var lastSelected = this.selectedIndex;
+ if(!inCtrlKey){
+ this.deselectAll(inIndex);
+ }
+ if(inShiftKey){
+ this.selectRange(lastSelected, inIndex);
+ }else if(inCtrlKey){
+ this.toggleSelect(inIndex);
+ }else{
+ this.addToSelection(inIndex);
+ }
+ }
+ this._endUpdate();
+ },
+
+ clickSelectEvent: function(e){
+ this.clickSelect(e.rowIndex, dojo.isCopyKey(e), e.shiftKey);
+ },
+
+ clear: function(){
+ this._beginUpdate();
+ this.deselectAll();
+ this._endUpdate();
+ }
+});
+}); \ No newline at end of file
diff --git a/js/dojo-1.7.2/dojox/grid/TreeGrid.js b/js/dojo-1.7.2/dojox/grid/TreeGrid.js
new file mode 100644
index 0000000..e80f78b
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/TreeGrid.js
@@ -0,0 +1,970 @@
+//>>built
+define("dojox/grid/TreeGrid", [
+ "dojo/_base/kernel",
+ "../main",
+ "dojo/_base/declare",
+ "dojo/_base/array",
+ "dojo/_base/lang",
+ "dojo/_base/event",
+ "dojo/dom-attr",
+ "dojo/dom-class",
+ "dojo/query",
+ "dojo/keys",
+ "dijit/tree/ForestStoreModel",
+ "./DataGrid",
+ "./_Layout",
+ "./_FocusManager",
+ "./_RowManager",
+ "./_EditManager",
+ "./TreeSelection",
+ "./cells/tree",
+ "./_TreeView"
+], function(dojo, dojox, declare, array, lang, event, domAttr, domClass, query, keys, ForestStoreModel,
+ DataGrid, _Layout, _FocusManager, _RowManager, _EditManager, TreeSelection, TreeCell){
+
+dojo.experimental("dojox.grid.TreeGrid");
+
+var _TreeAggregator = declare("dojox.grid._TreeAggregator", null, {
+ cells: [],
+ grid: null,
+ childFields: [],
+
+ constructor: function(kwArgs){
+ this.cells = kwArgs.cells || [];
+ this.childFields = kwArgs.childFields || [];
+ this.grid = kwArgs.grid;
+ this.store = this.grid.store;
+ },
+ _cacheValue: function(cache, id, value){
+ cache[id] = value;
+ return value;
+ },
+ clearSubtotalCache: function(){
+ // summary:
+ // Clears the subtotal cache so that we are forced to recalc it
+ // (or reread it) again. This is needed, for example, when
+ // column order is changed.
+ if(this.store){
+ delete this.store._cachedAggregates;
+ }
+ },
+
+ cnt: function(cell, level, item){
+ // summary:
+ // calculates the count of the children of item at the given level
+ var total = 0;
+ var store = this.store;
+ var childFields = this.childFields;
+ if(childFields[level]){
+ var children = store.getValues(item, childFields[level]);
+ if (cell.index <= level + 1){
+ total = children.length;
+ }else{
+ array.forEach(children, function(c){
+ total += this.getForCell(cell, level + 1, c, "cnt");
+ }, this);
+ }
+ }else{
+ total = 1;
+ }
+ return total;
+ },
+ sum: function(cell, level, item){
+ // summary:
+ // calculates the sum of the children of item at the given level
+ var total = 0;
+ var store = this.store;
+ var childFields = this.childFields;
+ if(childFields[level]){
+ array.forEach(store.getValues(item, childFields[level]), function(c){
+ total += this.getForCell(cell, level + 1, c, "sum");
+ }, this);
+ }else{
+ total += store.getValue(item, cell.field);
+ }
+ return total;
+ },
+ value: function(cell, level, item){
+ // summary:
+ // Empty function so that we can set "aggregate='value'" to
+ // force loading from the data - and bypass calculating
+ },
+ getForCell: function(cell, level, item, type){
+ // summary:
+ // Gets the value of the given cell at the given level and type.
+ // type can be one of "sum", "cnt", or "value". If itemAggregates
+ // is set and can be used, it is used instead. Values are also
+ // cached to prevent calculating them too often.
+ var store = this.store;
+ if(!store || !item || !store.isItem(item)){ return ""; }
+ var storeCache = store._cachedAggregates = store._cachedAggregates || {};
+ var id = store.getIdentity(item);
+ var itemCache = storeCache[id] = storeCache[id] || [];
+ if(!cell.getOpenState){
+ cell = this.grid.getCell(cell.layoutIndex + level + 1);
+ }
+ var idx = cell.index;
+ var idxCache = itemCache[idx] = itemCache[idx] || {};
+ type = (type || (cell.parentCell ? cell.parentCell.aggregate : "sum"))||"sum";
+ var attr = cell.field;
+ if(attr == store.getLabelAttributes()[0]){
+ // If our attribute is one of the label attributes, we should
+ // use cnt instead (since it makes no sense to do a sum of labels)
+ type = "cnt";
+ }
+ var typeCache = idxCache[type] = idxCache[type] || [];
+
+ // See if we have it in our cache immediately for easy returning
+ if(typeCache[level] != undefined){
+ return typeCache[level];
+ }
+
+ // See if they have specified a valid field
+ var field = ((cell.parentCell && cell.parentCell.itemAggregates) ?
+ cell.parentCell.itemAggregates[cell.idxInParent] : "")||"";
+ if(field && store.hasAttribute(item, field)){
+ return this._cacheValue(typeCache, level, store.getValue(item, field));
+ }else if(field){
+ return this._cacheValue(typeCache, level, 0);
+ }
+
+ // Calculate it
+ return this._cacheValue(typeCache, level, this[type](cell, level, item));
+ }
+});
+
+var _TreeLayout = declare("dojox.grid._TreeLayout", _Layout, {
+ // Whether or not we are collapsable - this is calculated when we
+ // set our structure.
+ _isCollapsable: false,
+
+ _getInternalStructure: function(inStructure){
+ // Create a "Tree View" with 1 row containing references for
+ // each column (recursively)
+ var g = this.grid;
+
+ var s = inStructure;
+ var cells = s[0].cells[0];
+ var tree = {
+ type: "dojox.grid._TreeView",
+ cells: [[]]
+ };
+ var cFields = [];
+ var maxLevels = 0;
+ var getTreeCells = function(parentCell, level){
+ var children = parentCell.children;
+ var cloneTreeCell = function(originalCell, idx){
+ var k, n = {};
+ for(k in originalCell){
+ n[k] = originalCell[k];
+ }
+ n = lang.mixin(n, {
+ level: level,
+ idxInParent: level > 0 ? idx : -1,
+ parentCell: level > 0 ? parentCell : null
+ });
+ return n;
+ };
+ var ret = [];
+ array.forEach(children, function(c, idx){
+ if("children" in c){
+ cFields.push(c.field);
+ var last = ret[ret.length - 1];
+ last.isCollapsable = true;
+ c.level = level;
+ ret = ret.concat(getTreeCells(c, level + 1));
+ }else{
+ ret.push(cloneTreeCell(c, idx));
+ }
+ });
+ maxLevels = Math.max(maxLevels, level);
+ return ret;
+ };
+ var tCell = {children: cells, itemAggregates: []};
+ tree.cells[0] = getTreeCells(tCell, 0);
+ g.aggregator = new _TreeAggregator({cells: tree.cells[0],
+ grid: g,
+ childFields: cFields});
+ if(g.scroller && g.defaultOpen){
+ g.scroller.defaultRowHeight = g.scroller._origDefaultRowHeight * (2 * maxLevels + 1);
+ }
+ return [ tree ];
+ },
+
+ setStructure: function(inStructure){
+ // Mangle the structure a bit and make it work as desired
+ var s = inStructure;
+ var g = this.grid;
+ // Only supporting single-view, single row or else we
+ // are not collapsable
+ if(g && g.treeModel && !array.every(s, function(i){
+ return ("cells" in i);
+ })){
+ s = arguments[0] = [{cells:[s]}];
+ }
+ if(s.length == 1 && s[0].cells.length == 1){
+ if(g && g.treeModel){
+ s[0].type = "dojox.grid._TreeView";
+ this._isCollapsable = true;
+ s[0].cells[0][(this.grid.treeModel?this.grid.expandoCell:0)].isCollapsable = true;
+ }else{
+ var childCells = array.filter(s[0].cells[0], function(c){
+ return ("children" in c);
+ });
+ if(childCells.length === 1){
+ this._isCollapsable = true;
+ }
+ }
+ }
+ if(this._isCollapsable && (!g || !g.treeModel)){
+ arguments[0] = this._getInternalStructure(s);
+ }
+ this.inherited(arguments);
+ },
+
+ addCellDef: function(inRowIndex, inCellIndex, inDef){
+ var obj = this.inherited(arguments);
+ return lang.mixin(obj, TreeCell);
+ }
+});
+
+var TreePath = declare("dojox.grid.TreePath", null, {
+ level: 0,
+ _str: "",
+ _arr: null,
+ grid: null,
+ store: null,
+ cell: null,
+ item: null,
+
+ constructor: function(/*String|Integer[]|Integer|dojox.grid.TreePath*/ path, /*dojox.grid.TreeGrid*/ grid){
+ if(lang.isString(path)){
+ this._str = path;
+ this._arr = array.map(path.split('/'), function(item){ return parseInt(item, 10); });
+ }else if(lang.isArray(path)){
+ this._str = path.join('/');
+ this._arr = path.slice(0);
+ }else if(typeof path == "number"){
+ this._str = String(path);
+ this._arr = [path];
+ }else{
+ this._str = path._str;
+ this._arr = path._arr.slice(0);
+ }
+ this.level = this._arr.length-1;
+ this.grid = grid;
+ this.store = this.grid.store;
+ if(grid.treeModel){
+ this.cell = grid.layout.cells[grid.expandoCell];
+ }else{
+ this.cell = grid.layout.cells[this.level];
+ }
+ },
+ item: function(){
+ // summary:
+ // gets the dojo.data item associated with this path
+ if(!this._item){
+ this._item = this.grid.getItem(this._arr);
+ }
+ return this._item;
+ },
+ compare: function(path /*dojox.grid.TreePath|String|Array*/){
+ // summary:
+ // compares two paths
+ if(lang.isString(path) || lang.isArray(path)){
+ if(this._str == path){ return 0; }
+ if(path.join && this._str == path.join('/')){ return 0; }
+ path = new TreePath(path, this.grid);
+ }else if(path instanceof TreePath){
+ if(this._str == path._str){ return 0; }
+ }
+ for(var i=0, l=(this._arr.length < path._arr.length ? this._arr.length : path._arr.length); i<l; i++){
+ if(this._arr[i]<path._arr[i]){ return -1; }
+ if(this._arr[i]>path._arr[i]){ return 1; }
+ }
+ if(this._arr.length<path._arr.length){ return -1; }
+ if(this._arr.length>path._arr.length){ return 1; }
+ return 0;
+ },
+ isOpen: function(){
+ // summary:
+ // Returns the open state of this cell.
+ return this.cell.openStates && this.cell.getOpenState(this.item());
+ },
+ previous: function(){
+ // summary:
+ // Returns the path that is before this path in the
+ // grid. If no path is found, returns null.
+ var new_path = this._arr.slice(0);
+
+ if(this._str == "0"){
+ return null;
+ }
+
+ var last = new_path.length-1;
+
+ if(new_path[last] === 0){
+ new_path.pop();
+ return new TreePath(new_path, this.grid);
+ }
+
+ new_path[last]--;
+ var path = new TreePath(new_path, this.grid);
+ return path.lastChild(true);
+ },
+ next: function(){
+ // summary:
+ // Returns the next path in the grid. If no path
+ // is found, returns null.
+ var new_path = this._arr.slice(0);
+
+ if(this.isOpen()){
+ new_path.push(0);
+ }else{
+ new_path[new_path.length-1]++;
+ for(var i=this.level; i>=0; i--){
+ var item = this.grid.getItem(new_path.slice(0, i+1));
+ if(i>0){
+ if(!item){
+ new_path.pop();
+ new_path[i-1]++;
+ }
+ }else{
+ if(!item){
+ return null;
+ }
+ }
+ }
+ }
+
+ return new TreePath(new_path, this.grid);
+ },
+ children: function(alwaysReturn){
+ // summary:
+ // Returns the child data items of this row. If this
+ // row isn't open and alwaysReturn is falsey, returns null.
+ if(!this.isOpen()&&!alwaysReturn){
+ return null;
+ }
+ var items = [];
+ var model = this.grid.treeModel;
+ if(model){
+ var item = this.item();
+ var store = model.store;
+ if(!model.mayHaveChildren(item)){
+ return null;
+ }
+ array.forEach(model.childrenAttrs, function(attr){
+ items = items.concat(store.getValues(item, attr));
+ });
+ }else{
+ items = this.store.getValues(this.item(), this.grid.layout.cells[this.cell.level+1].parentCell.field);
+ if(items.length>1&&this.grid.sortChildItems){
+ var sortProps = this.grid.getSortProps();
+ if(sortProps&&sortProps.length){
+ var attr = sortProps[0].attribute,
+ grid = this.grid;
+ if(attr&&items[0][attr]){
+ var desc = !!sortProps[0].descending;
+ items = items.slice(0); // don't touch the array in the store, make a copy
+ items.sort(function(a, b){
+ return grid._childItemSorter(a, b, attr, desc);
+ });
+ }
+ }
+ }
+ }
+ return items;
+ },
+ childPaths: function(){
+ var childItems = this.children();
+ if(!childItems){
+ return [];
+ }
+ return array.map(childItems, function(item, index){
+ return new TreePath(this._str + '/' + index, this.grid);
+ }, this);
+ },
+ parent: function(){
+ // summary:
+ // Returns the parent path of this path. If this is a
+ // top-level row, returns null.
+ if(this.level === 0){
+ return null;
+ }
+ return new TreePath(this._arr.slice(0, this.level), this.grid);
+ },
+ lastChild: function(/*Boolean?*/ traverse){
+ // summary:
+ // Returns the last child row below this path. If traverse
+ // is true, will traverse down to find the last child row
+ // of this branch. If there are no children, returns itself.
+ var children = this.children();
+ if(!children || !children.length){
+ return this;
+ }
+ var path = new TreePath(this._str + "/" + String(children.length-1), this.grid);
+ if(!traverse){
+ return path;
+ }
+ return path.lastChild(true);
+ },
+ toString: function(){
+ return this._str;
+ }
+});
+
+var _TreeFocusManager = declare("dojox.grid._TreeFocusManager", _FocusManager, {
+ setFocusCell: function(inCell, inRowIndex){
+ if(inCell && inCell.getNode(inRowIndex)){
+ this.inherited(arguments);
+ }
+ },
+ isLastFocusCell: function(){
+ if(this.cell && this.cell.index == this.grid.layout.cellCount-1){
+ var path = new TreePath(this.grid.rowCount-1, this.grid);
+ path = path.lastChild(true);
+ return this.rowIndex == path._str;
+ }
+ return false;
+ },
+ next: function(){
+ // summary:
+ // focus next grid cell
+ if(this.cell){
+ var row=this.rowIndex, col=this.cell.index+1, cc=this.grid.layout.cellCount-1;
+ var path = new TreePath(this.rowIndex, this.grid);
+ if(col > cc){
+ var new_path = path.next();
+ if(!new_path){
+ col--;
+ }else{
+ col = 0;
+ path = new_path;
+ }
+ }
+ if(this.grid.edit.isEditing()){ //when editing, only navigate to editable cells
+ var nextCell = this.grid.getCell(col);
+ if (!this.isLastFocusCell() && !nextCell.editable){
+ this._focusifyCellNode(false);
+ this.cell=nextCell;
+ this.rowIndex=path._str;
+ this.next();
+ return;
+ }
+ }
+ this.setFocusIndex(path._str, col);
+ }
+ },
+ previous: function(){
+ // summary:
+ // focus previous grid cell
+ if(this.cell){
+ var row=(this.rowIndex || 0), col=(this.cell.index || 0) - 1;
+ var path = new TreePath(row, this.grid);
+ if(col < 0){
+ var new_path = path.previous();
+ if(!new_path){
+ col = 0;
+ }else{
+ col = this.grid.layout.cellCount-1;
+ path = new_path;
+ }
+ }
+ if(this.grid.edit.isEditing()){ //when editing, only navigate to editable cells
+ var prevCell = this.grid.getCell(col);
+ if (!this.isFirstFocusCell() && !prevCell.editable){
+ this._focusifyCellNode(false);
+ this.cell=prevCell;
+ this.rowIndex=path._str;
+ this.previous();
+ return;
+ }
+ }
+ this.setFocusIndex(path._str, col);
+ }
+ },
+ move: function(inRowDelta, inColDelta){
+ if(this.isNavHeader()){
+ this.inherited(arguments);
+ return;
+ }
+ if(!this.cell){ return; }
+ // Handle grid proper.
+ var sc = this.grid.scroller,
+ r = this.rowIndex,
+ rc = this.grid.rowCount-1,
+ path = new TreePath(this.rowIndex, this.grid);
+ if(inRowDelta){
+ var row;
+ if(inRowDelta>0){
+ path = path.next();
+ row = path._arr[0];
+ if(row > sc.getLastPageRow(sc.page)){
+ //need to load additional data, let scroller do that
+ this.grid.setScrollTop(this.grid.scrollTop+sc.findScrollTop(row)-sc.findScrollTop(r));
+ }
+ }else if(inRowDelta<0){
+ path = path.previous();
+ row = path._arr[0];
+ if(row <= sc.getPageRow(sc.page)){
+ //need to load additional data, let scroller do that
+ this.grid.setScrollTop(this.grid.scrollTop-sc.findScrollTop(r)-sc.findScrollTop(row));
+ }
+ }
+ }
+ var cc = this.grid.layout.cellCount-1,
+ i = this.cell.index,
+ col = Math.min(cc, Math.max(0, i+inColDelta));
+ var cell = this.grid.getCell(col);
+ var colDir = inColDelta < 0 ? -1 : 1;
+ while(col>=0 && col < cc && cell && cell.hidden === true){
+ // skip hidden cells
+ col += colDir;
+ cell = this.grid.getCell(col);
+ }
+ if (!cell || cell.hidden === true){
+ // don't change col if would move to hidden
+ col = i;
+ }
+ if(inRowDelta){
+ this.grid.updateRow(r);
+ }
+ this.setFocusIndex(path._str, col);
+ }
+});
+
+var TreeGrid = declare("dojox.grid.TreeGrid", DataGrid, {
+ // summary:
+ // A grid that supports nesting rows - it provides an expando function
+ // similar to dijit.Tree. It also provides mechanisms for aggregating
+ // the values of subrows
+ //
+ // description:
+ // TreeGrid currently only works on "simple" structures. That is,
+ // single-view structures with a single row in them.
+ //
+ // The TreeGrid works using the concept of "levels" - level 0 are the
+ // top-level items.
+
+ // defaultOpen: Boolean
+ // Whether or not we default to open (all levels). This defaults to
+ // false for grids with a treeModel.
+ defaultOpen: true,
+
+ // sortChildItems: Boolean
+ // If true, child items will be returned sorted according to the sorting
+ // properties of the grid.
+ sortChildItems: false,
+
+ // openAtLevels: Array
+ // Which levels we are open at (overrides defaultOpen for the values
+ // that exist here). Its values can be a boolean (true/false) or an
+ // integer (for the # of children to be closed if there are more than
+ // that)
+ openAtLevels: [],
+
+ // treeModel: dijit.tree.ForestStoreModel
+ // A dijit.Tree model that will be used instead of using aggregates.
+ // Setting this value will make the TreeGrid behave like a columnar
+ // tree. When setting this value, defaultOpen will default to false,
+ // and openAtLevels will be ignored.
+ treeModel: null,
+
+ // expandoCell: Integer
+ // When used in conjunction with a treeModel (see above), this is a 0-based
+ // index of the cell in which to place the actual expando
+ expandoCell: 0,
+
+ // private values
+ // aggregator: Object
+ // The aggregator class - it will be populated automatically if we
+ // are a collapsable grid
+ aggregator: null,
+
+
+ // Override this to get our "magic" layout
+ _layoutClass: _TreeLayout,
+
+ createSelection: function(){
+ this.selection = new TreeSelection(this);
+ },
+
+ _childItemSorter: function(a, b, attribute, descending){
+ var av = this.store.getValue(a, attribute);
+ var bv = this.store.getValue(b, attribute);
+ if(av != bv){
+ return av < bv == descending ? 1 : -1;
+ }
+ return 0;
+ },
+
+ _onNew: function(item, parentInfo){
+ if(!parentInfo || !parentInfo.item){
+ this.inherited(arguments);
+ }else{
+ var idx = this.getItemIndex(parentInfo.item);
+ if(typeof idx == "string"){
+ this.updateRow(idx.split('/')[0]);
+ }else if(idx > -1){
+ this.updateRow(idx);
+ }
+ }
+ },
+
+ _onSet: function(item, attribute, oldValue, newValue){
+ this._checkUpdateStatus();
+ if(this.aggregator){
+ this.aggregator.clearSubtotalCache();
+ }
+ var idx = this.getItemIndex(item);
+ if(typeof idx == "string"){
+ this.updateRow(idx.split('/')[0]);
+ }else if(idx > -1){
+ this.updateRow(idx);
+ }
+ },
+
+ _onDelete: function(item){
+ this._cleanupExpandoCache(this._getItemIndex(item, true), this.store.getIdentity(item), item);
+ this.inherited(arguments);
+ },
+
+ _cleanupExpandoCache: function(index, identity, item){},
+
+ _addItem: function(item, index, noUpdate, dontUpdateRoot){
+ // add our root items to the root of the model's children
+ // list since we don't query the model
+ if(!dontUpdateRoot && this.model && array.indexOf(this.model.root.children, item) == -1){
+ this.model.root.children[index] = item;
+ }
+ this.inherited(arguments);
+ },
+
+ getItem: function(/*integer|Array|String*/ idx){
+ // summary:
+ // overridden so that you can pass in a '/' delimited string of indexes to get the
+ // item based off its path...that is, passing in "1/3/2" will get the
+ // 3rd (0-based) child from the 4th child of the 2nd top-level item.
+ var isArray = lang.isArray(idx);
+ if(lang.isString(idx) && idx.indexOf('/')){
+ idx = idx.split('/');
+ isArray = true;
+ }
+ if(isArray && idx.length == 1){
+ idx = idx[0];
+ isArray = false;
+ }
+ if(!isArray){
+ return DataGrid.prototype.getItem.call(this, idx);
+ }
+ var s = this.store;
+ var itm = DataGrid.prototype.getItem.call(this, idx[0]);
+ var cf, i, j;
+ if(this.aggregator){
+ cf = this.aggregator.childFields||[];
+ if(cf){
+ for(i = 0; i < idx.length - 1 && itm; i++){
+ if(cf[i]){
+ itm = (s.getValues(itm, cf[i])||[])[idx[i + 1]];
+ }else{
+ itm = null;
+ }
+ }
+ }
+ }else if(this.treeModel){
+ cf = this.treeModel.childrenAttrs||[];
+ if(cf&&itm){
+ for(i=1, il=idx.length; (i<il) && itm; i++) {
+ for(j=0, jl=cf.length; j<jl; j++) {
+ if(cf[j]){
+ itm = (s.getValues(itm, cf[j])||[])[idx[i]];
+ }else{
+ itm = null;
+ }
+ if(itm){ break; }
+ }
+ }
+ }
+ }
+ return itm || null;
+ },
+
+ _getItemIndex: function(item, isDeleted){
+ if(!isDeleted && !this.store.isItem(item)){
+ return -1;
+ }
+ var idx = this.inherited(arguments);
+ if(idx == -1){
+ var idty = this.store.getIdentity(item);
+ return this._by_idty_paths[idty] || -1;
+ }
+ return idx;
+ },
+
+ postMixInProperties: function(){
+ if(this.treeModel && !("defaultOpen" in this.params)){
+ // Default open to false for tree models, true for other tree
+ // grids.
+ this.defaultOpen = false;
+ }
+ var def = this.defaultOpen;
+ this.openAtLevels = array.map(this.openAtLevels, function(l){
+ if(typeof l == "string"){
+ switch(l.toLowerCase()){
+ case "true":
+ return true;
+ break;
+ case "false":
+ return false;
+ break;
+ default:
+ var r = parseInt(l, 10);
+ if(isNaN(r)){
+ return def;
+ }
+ return r;
+ break;
+ }
+ }
+ return l;
+ });
+ this._by_idty_paths = {};
+ this.inherited(arguments);
+ },
+
+ postCreate: function(){
+ this.inherited(arguments);
+ if(this.treeModel){
+ this._setModel(this.treeModel);
+ }
+ },
+
+ setModel: function(treeModel){
+ this._setModel(treeModel);
+ this._refresh(true);
+ },
+
+ _setModel: function(treeModel){
+ if(treeModel && (!ForestStoreModel || !(treeModel instanceof ForestStoreModel))){
+ throw new Error("dojox.grid.TreeGrid: treeModel must be an instance of dijit.tree.ForestStoreModel");
+ }
+ this.treeModel = treeModel;
+ domClass.toggle(this.domNode, "dojoxGridTreeModel", this.treeModel ? true : false);
+ this._setQuery(treeModel ? treeModel.query : null);
+ this._setStore(treeModel ? treeModel.store : null);
+ },
+
+ createScroller: function(){
+ this.inherited(arguments);
+ this.scroller._origDefaultRowHeight = this.scroller.defaultRowHeight;
+ },
+
+ createManagers: function(){
+ // summary:
+ // create grid managers for various tasks including rows, focus, selection, editing
+
+ // row manager
+ this.rows = new _RowManager(this);
+ // focus manager
+ this.focus = new _TreeFocusManager(this);
+ // edit manager
+ this.edit = new _EditManager(this);
+ },
+
+ _setStore: function(store){
+ this.inherited(arguments);
+ if(this.treeModel&&!this.treeModel.root.children){
+ this.treeModel.root.children = [];
+ }
+ if(this.aggregator){
+ this.aggregator.store = store;
+ }
+ },
+
+ getDefaultOpenState: function(cellDef, item){
+ // summary:
+ // Returns the default open state for the given definition and item
+ // It reads from the openAtLevels and defaultOpen values of the
+ // grid to calculate if the given item should default to open or
+ // not.
+ var cf;
+ var store = this.store;
+ if(this.treeModel){ return this.defaultOpen; }
+ if(!cellDef || !store || !store.isItem(item) ||
+ !(cf = this.aggregator.childFields[cellDef.level])){
+ return this.defaultOpen;
+ }
+ if(this.openAtLevels.length > cellDef.level){
+ var dVal = this.openAtLevels[cellDef.level];
+ if(typeof dVal == "boolean"){
+ return dVal;
+ }else if(typeof dVal == "number"){
+ return (store.getValues(item, cf).length <= dVal);
+ }
+ }
+ return this.defaultOpen;
+ },
+ onStyleRow: function(row){
+ if(!this.layout._isCollapsable){
+ this.inherited(arguments);
+ return;
+ }
+ var base = domAttr.get(row.node, 'dojoxTreeGridBaseClasses');
+ if(base){
+ row.customClasses = base;
+ }
+ var i = row;
+ var tagName = i.node.tagName.toLowerCase();
+ i.customClasses += (i.odd?" dojoxGridRowOdd":"") +
+ (i.selected&&tagName=='tr'?" dojoxGridRowSelected":"") +
+ (i.over&&tagName=='tr'?" dojoxGridRowOver":"");
+ this.focus.styleRow(i);
+ this.edit.styleRow(i);
+ },
+ styleRowNode: function(inRowIndex, inRowNode){
+ if(inRowNode){
+ if(inRowNode.tagName.toLowerCase() == 'div' && this.aggregator){
+ query("tr[dojoxTreeGridPath]", inRowNode).forEach(function(rowNode){
+ this.rows.styleRowNode(domAttr.get(rowNode, 'dojoxTreeGridPath'), rowNode);
+ },this);
+ }
+ this.rows.styleRowNode(inRowIndex, inRowNode);
+ }
+ },
+ onCanSelect: function(inRowIndex){
+ var nodes = query("tr[dojoxTreeGridPath='" + inRowIndex + "']", this.domNode);
+ if(nodes.length){
+ if(domClass.contains(nodes[0], 'dojoxGridSummaryRow')){
+ return false;
+ }
+ }
+ return this.inherited(arguments);
+ },
+ onKeyDown: function(e){
+ if(e.altKey || e.metaKey){
+ return;
+ }
+ switch(e.keyCode){
+ case keys.UP_ARROW:
+ if(!this.edit.isEditing() && this.focus.rowIndex != "0"){
+ event.stop(e);
+ this.focus.move(-1, 0);
+ }
+ break;
+ case keys.DOWN_ARROW:
+ var currPath = new TreePath(this.focus.rowIndex, this);
+ var lastPath = new TreePath(this.rowCount-1, this);
+ lastPath = lastPath.lastChild(true);
+ if(!this.edit.isEditing() && currPath.toString() != lastPath.toString()){
+ event.stop(e);
+ this.focus.move(1, 0);
+ }
+ break;
+ default:
+ this.inherited(arguments);
+ break;
+ }
+ },
+ canEdit: function(inCell, inRowIndex){
+ var node = inCell.getNode(inRowIndex);
+ return node && this._canEdit;
+ },
+ doApplyCellEdit: function(inValue, inRowIndex, inAttrName){
+ var item = this.getItem(inRowIndex);
+ var oldValue = this.store.getValue(item, inAttrName);
+ if(typeof oldValue == 'number'){
+ inValue = isNaN(inValue) ? inValue : parseFloat(inValue);
+ }else if(typeof oldValue == 'boolean'){
+ inValue = inValue == 'true' ? true : inValue == 'false' ? false : inValue;
+ }else if(oldValue instanceof Date){
+ var asDate = new Date(inValue);
+ inValue = isNaN(asDate.getTime()) ? inValue : asDate;
+ }
+ this.store.setValue(item, inAttrName, inValue);
+ this.onApplyCellEdit(inValue, inRowIndex, inAttrName);
+ }
+});
+TreeGrid.markupFactory = function(props, node, ctor, cellFunc){
+ var widthFromAttr = function(n){
+ var w = domAttr.get(n, "width")||"auto";
+ if((w != "auto")&&(w.slice(-2) != "em")&&(w.slice(-1) != "%")){
+ w = parseInt(w, 10)+"px";
+ }
+ return w;
+ };
+
+ var cellsFromMarkup = function(table){
+ var rows;
+ // Don't support colgroup on our grid - single view, single row only
+ if(table.nodeName.toLowerCase() == "table" &&
+ query("> colgroup", table).length === 0 &&
+ (rows = query("> thead > tr", table)).length == 1){
+ var tr = rows[0];
+ return query("> th", rows[0]).map(function(th){
+ // Grab type and field (the only ones that are shared
+ var cell = {
+ type: lang.trim(domAttr.get(th, "cellType")||""),
+ field: lang.trim(domAttr.get(th, "field")||"")
+ };
+ if(cell.type){
+ cell.type = lang.getObject(cell.type);
+ }
+
+ var subTable = query("> table", th)[0];
+ if(subTable){
+ // If we have a subtable, we are an aggregate and a summary cell
+ cell.name = "";
+ cell.children = cellsFromMarkup(subTable);
+ if(domAttr.has(th, "itemAggregates")){
+ cell.itemAggregates = array.map(domAttr.get(th, "itemAggregates").split(","), function(v){
+ return lang.trim(v);
+ });
+ }else{
+ cell.itemAggregates = [];
+ }
+ if(domAttr.has(th, "aggregate")){
+ cell.aggregate = domAttr.get(th, "aggregate");
+ }
+ cell.type = cell.type || dojox.grid.cells.SubtableCell;
+ }else{
+ // Grab our other stuff we need (mostly what's in the normal
+ // Grid)
+ cell.name = lang.trim(domAttr.get(th, "name")||th.innerHTML);
+ if(domAttr.has(th, "width")){
+ cell.width = widthFromAttr(th);
+ }
+ if(domAttr.has(th, "relWidth")){
+ cell.relWidth = window.parseInt(domAttr.get(th, "relWidth"), 10);
+ }
+ if(domAttr.has(th, "hidden")){
+ cell.hidden = domAttr.get(th, "hidden") == "true";
+ }
+ cell.field = cell.field||cell.name;
+ DataGrid.cell_markupFactory(cellFunc, th, cell);
+ cell.type = cell.type || dojox.grid.cells.Cell;
+ }
+ if(cell.type && cell.type.markupFactory){
+ cell.type.markupFactory(th, cell);
+ }
+ return cell;
+ });
+ }
+ return [];
+ };
+
+ var rows;
+ if( !props.structure ){
+ var row = cellsFromMarkup(node);
+ if(row.length){
+ // Set our structure here - so that we don't try and set it in the
+ // markup factory
+ props.structure = [{__span: Infinity, cells:[row]}];
+ }
+ }
+ return DataGrid.markupFactory(props, node, ctor, cellFunc);
+};
+
+return TreeGrid;
+
+}); \ No newline at end of file
diff --git a/js/dojo-1.7.2/dojox/grid/TreeSelection.js b/js/dojo-1.7.2/dojox/grid/TreeSelection.js
new file mode 100644
index 0000000..84e4b74
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/TreeSelection.js
@@ -0,0 +1,216 @@
+//>>built
+define("dojox/grid/TreeSelection", [
+ "../main",
+ "dojo/_base/declare",
+ "dojo/_base/array",
+ "dojo/_base/lang",
+ "dojo/dom-attr",
+ "dojo/query",
+ "./DataSelection"
+], function(dojox, declare, array, lang, domAttr, query, DataSelection){
+
+return declare("dojox.grid.TreeSelection", DataSelection, {
+ setMode: function(mode){
+ this.selected = {};
+ this.sorted_sel = [];
+ this.sorted_ltos = {};
+ this.sorted_stol = {};
+ DataSelection.prototype.setMode.call(this, mode);
+ },
+ addToSelection: function(inItemOrIndex){
+ if(this.mode == 'none'){ return; }
+ var idx = null;
+ if(typeof inItemOrIndex == "number" || typeof inItemOrIndex == "string"){
+ idx = inItemOrIndex;
+ }else{
+ idx = this.grid.getItemIndex(inItemOrIndex);
+ }
+ if(this.selected[idx]){
+ this.selectedIndex = idx;
+ }else{
+ if(this.onCanSelect(idx) !== false){
+ this.selectedIndex = idx;
+ var rowNodes = query("tr[dojoxTreeGridPath='" + idx + "']", this.grid.domNode);
+ if(rowNodes.length){
+ domAttr.set(rowNodes[0], "aria-selected", "true");
+ }
+ this._beginUpdate();
+ this.selected[idx] = true;
+ this._insertSortedSelection(idx);
+ //this.grid.onSelected(idx);
+ this.onSelected(idx);
+ //this.onSetSelected(idx, true);
+ this._endUpdate();
+ }
+ }
+ },
+ deselect: function(inItemOrIndex){
+ if(this.mode == 'none'){ return; }
+ var idx = null;
+ if(typeof inItemOrIndex == "number" || typeof inItemOrIndex == "string"){
+ idx = inItemOrIndex;
+ }else{
+ idx = this.grid.getItemIndex(inItemOrIndex);
+ }
+ if(this.selectedIndex == idx){
+ this.selectedIndex = -1;
+ }
+ if(this.selected[idx]){
+ if(this.onCanDeselect(idx) === false){
+ return;
+ }
+ var rowNodes = query("tr[dojoxTreeGridPath='" + idx + "']", this.grid.domNode);
+ if(rowNodes.length){
+ domAttr.set(rowNodes[0], "aria-selected", "false");
+ }
+ this._beginUpdate();
+ delete this.selected[idx];
+ this._removeSortedSelection(idx);
+ //this.grid.onDeselected(idx);
+ this.onDeselected(idx);
+ //this.onSetSelected(idx, false);
+ this._endUpdate();
+ }
+ },
+ getSelected: function(){
+ var result = [];
+ for(var i in this.selected){
+ if(this.selected[i]){
+ result.push(this.grid.getItem(i));
+ }
+ }
+ return result;
+ },
+ getSelectedCount: function(){
+ var c = 0;
+ for(var i in this.selected){
+ if(this.selected[i]){
+ c++;
+ }
+ }
+ return c;
+ },
+ _bsearch: function(v){
+ var o = this.sorted_sel;
+ var h = o.length - 1, l = 0, m;
+ while(l<=h){
+ var cmp = this._comparePaths(o[m = (l + h) >> 1], v);
+ if(cmp < 0){ l = m + 1; continue; }
+ if(cmp > 0){ h = m - 1; continue; }
+ return m;
+ }
+ return cmp < 0 ? m - cmp : m;
+ },
+ _comparePaths: function(a, b){
+ for(var i=0, l=(a.length < b.length ? a.length : b.length); i<l; i++){
+ if(a[i]<b[i]){ return -1; }
+ if(a[i]>b[i]){ return 1; }
+ }
+ if(a.length<b.length){ return -1; }
+ if(a.length>b.length){ return 1; }
+ return 0;
+ },
+ _insertSortedSelection: function(index){
+ index = String(index);
+ var s = this.sorted_sel;
+ var sl = this.sorted_ltos;
+ var ss = this.sorted_stol;
+
+ var lpath = index.split('/');
+ lpath = array.map(lpath, function(item){ return parseInt(item, 10); });
+ sl[lpath] = index;
+ ss[index] = lpath;
+
+ if(s.length === 0){
+ s.push(lpath);
+ return;
+ }
+ if(s.length==1){
+ var cmp = this._comparePaths(s[0], lpath);
+ if(cmp==1){ s.unshift(lpath); }
+ else{ s.push(lpath); }
+ return;
+ }
+
+ var idx = this._bsearch(lpath);
+ this.sorted_sel.splice(idx, 0, lpath);
+ },
+ _removeSortedSelection: function(index){
+ index = String(index);
+ var s = this.sorted_sel;
+ var sl = this.sorted_ltos;
+ var ss = this.sorted_stol;
+
+ if(s.length === 0){
+ return;
+ }
+
+ var lpath = ss[index];
+ if(!lpath){ return; }
+
+ var idx = this._bsearch(lpath);
+ if(idx > -1){
+ delete sl[lpath];
+ delete ss[index];
+ s.splice(idx, 1);
+ }
+ },
+ getFirstSelected: function(){
+ if(!this.sorted_sel.length||this.mode == 'none'){ return -1; }
+ var fpath = this.sorted_sel[0];
+ if(!fpath){
+ return -1;
+ }
+ fpath = this.sorted_ltos[fpath];
+ if(!fpath){
+ return -1;
+ }
+ return fpath;
+ },
+ getNextSelected: function(inPrev){
+ if(!this.sorted_sel.length||this.mode == 'none'){ return -1; }
+ inPrev = String(inPrev);
+ var prevPath = this.sorted_stol[inPrev];
+ if(!prevPath){ return -1; }
+
+ var idx = this._bsearch(prevPath);
+ var lpath = this.sorted_sel[idx+1];
+ if(!lpath){
+ return -1;
+ }
+ return this.sorted_ltos[lpath];
+ },
+ _range: function(inFrom, inTo, func){
+ if(!lang.isString(inFrom) && inFrom < 0){
+ inFrom = inTo;
+ }
+ var cells = this.grid.layout.cells,
+ store = this.grid.store,
+ grid = this.grid;
+ inFrom = new dojox.grid.TreePath(String(inFrom), grid);
+ inTo = new dojox.grid.TreePath(String(inTo), grid);
+
+ if(inFrom.compare(inTo) > 0){
+ var tmp = inFrom;
+ inFrom = inTo;
+ inTo = tmp;
+ }
+
+ var inFromStr = inFrom._str, inToStr = inTo._str;
+
+ // select/deselect the first
+ func(inFromStr);
+
+ var p = inFrom;
+ while((p = p.next())){
+ if(p._str == inToStr){
+ break;
+ }
+ func(p._str);
+ }
+
+ // select/deselect the last
+ func(inToStr);
+ }
+});
+}); \ No newline at end of file
diff --git a/js/dojo-1.7.2/dojox/grid/_Builder.js b/js/dojo-1.7.2/dojox/grid/_Builder.js
new file mode 100644
index 0000000..6cc1ea6
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/_Builder.js
@@ -0,0 +1,760 @@
+//>>built
+define("dojox/grid/_Builder", [
+ "../main",
+ "dojo/_base/array",
+ "dojo/_base/lang",
+ "dojo/_base/window",
+ "dojo/_base/event",
+ "dojo/_base/sniff",
+ "dojo/_base/connect",
+ "dojo/dnd/Moveable",
+ "dojox/html/metrics",
+ "./util",
+ "dojo/_base/html"
+], function(dojox, array, lang, win, event, has, connect, Moveable, metrics, util, html){
+
+ var dg = dojox.grid;
+
+ var getTdIndex = function(td){
+ return td.cellIndex >=0 ? td.cellIndex : array.indexOf(td.parentNode.cells, td);
+ };
+
+ var getTrIndex = function(tr){
+ return tr.rowIndex >=0 ? tr.rowIndex : array.indexOf(tr.parentNode.childNodes, tr);
+ };
+
+ var getTr = function(rowOwner, index){
+ return rowOwner && ((rowOwner.rows||0)[index] || rowOwner.childNodes[index]);
+ };
+
+ var findTable = function(node){
+ for(var n=node; n && n.tagName!='TABLE'; n=n.parentNode){}
+ return n;
+ };
+
+ var ascendDom = function(inNode, inWhile){
+ for(var n=inNode; n && inWhile(n); n=n.parentNode){}
+ return n;
+ };
+
+ var makeNotTagName = function(inTagName){
+ var name = inTagName.toUpperCase();
+ return function(node){ return node.tagName != name; };
+ };
+
+ var rowIndexTag = util.rowIndexTag;
+ var gridViewTag = util.gridViewTag;
+
+ // base class for generating markup for the views
+ var _Builder = dg._Builder = lang.extend(function(view){
+ if(view){
+ this.view = view;
+ this.grid = view.grid;
+ }
+ },{
+ view: null,
+ // boilerplate HTML
+ _table: '<table class="dojoxGridRowTable" border="0" cellspacing="0" cellpadding="0" role="presentation"',
+
+ // Returns the table variable as an array - and with the view width, if specified
+ getTableArray: function(){
+ var html = [this._table];
+ if(this.view.viewWidth){
+ html.push([' style="width:', this.view.viewWidth, ';"'].join(''));
+ }
+ html.push('>');
+ return html;
+ },
+
+ // generate starting tags for a cell
+ generateCellMarkup: function(inCell, inMoreStyles, inMoreClasses, isHeader){
+ var result = [], html;
+ if(isHeader){
+ var sortInfo = inCell.index != inCell.grid.getSortIndex() ? "" : inCell.grid.sortInfo > 0 ? 'aria-sort="ascending"' : 'aria-sort="descending"';
+ if (!inCell.id){
+ inCell.id = this.grid.id + "Hdr" + inCell.index;
+ }
+ // column headers are not editable, mark as aria-readonly=true
+ html = ['<th tabIndex="-1" aria-readonly="true" role="columnheader"', sortInfo, 'id="', inCell.id, '"'];
+ }else{
+ // cells inherit grid aria-readonly property; default value for aria-readonly is false(grid is editable)
+ // if grid is editable (had any editable cells), mark non editable cells as aria-readonly=true
+ // if no editable cells, grid's aria-readonly value will have been set to true and cells will inherit
+ var editInfo = this.grid.editable && !inCell.editable ? 'aria-readonly="true"' : "";
+ html = ['<td tabIndex="-1" role="gridcell"', editInfo];
+ }
+ if(inCell.colSpan){
+ html.push(' colspan="', inCell.colSpan, '"');
+ }
+ if(inCell.rowSpan){
+ html.push(' rowspan="', inCell.rowSpan, '"');
+ }
+ html.push(' class="dojoxGridCell ');
+ if(inCell.classes){
+ html.push(inCell.classes, ' ');
+ }
+ if(inMoreClasses){
+ html.push(inMoreClasses, ' ');
+ }
+ // result[0] => td opener, style
+ result.push(html.join(''));
+ // SLOT: result[1] => td classes
+ result.push('');
+ html = ['" idx="', inCell.index, '" style="'];
+ if(inMoreStyles && inMoreStyles[inMoreStyles.length-1] != ';'){
+ inMoreStyles += ';';
+ }
+ html.push(inCell.styles, inMoreStyles||'', inCell.hidden?'display:none;':'');
+ if(inCell.unitWidth){
+ html.push('width:', inCell.unitWidth, ';');
+ }
+ // result[2] => markup
+ result.push(html.join(''));
+ // SLOT: result[3] => td style
+ result.push('');
+ html = [ '"' ];
+ if(inCell.attrs){
+ html.push(" ", inCell.attrs);
+ }
+ html.push('>');
+ // result[4] => td postfix
+ result.push(html.join(''));
+ // SLOT: result[5] => content
+ result.push('');
+ // result[6] => td closes
+ result.push(isHeader?'</th>':'</td>');
+ return result; // Array
+ },
+
+ // cell finding
+ isCellNode: function(inNode){
+ return Boolean(inNode && inNode!=win.doc && html.attr(inNode, "idx"));
+ },
+
+ getCellNodeIndex: function(inCellNode){
+ return inCellNode ? Number(html.attr(inCellNode, "idx")) : -1;
+ },
+
+ getCellNode: function(inRowNode, inCellIndex){
+ for(var i=0, row; ((row = getTr(inRowNode.firstChild, i)) && row.cells); i++){
+ for(var j=0, cell; (cell = row.cells[j]); j++){
+ if(this.getCellNodeIndex(cell) == inCellIndex){
+ return cell;
+ }
+ }
+ }
+ return null;
+ },
+
+ findCellTarget: function(inSourceNode, inTopNode){
+ var n = inSourceNode;
+ while(n && (!this.isCellNode(n) || (n.offsetParent && gridViewTag in n.offsetParent.parentNode && n.offsetParent.parentNode[gridViewTag] != this.view.id)) && (n!=inTopNode)){
+ n = n.parentNode;
+ }
+ return n!=inTopNode ? n : null;
+ },
+
+ // event decoration
+ baseDecorateEvent: function(e){
+ e.dispatch = 'do' + e.type;
+ e.grid = this.grid;
+ e.sourceView = this.view;
+ e.cellNode = this.findCellTarget(e.target, e.rowNode);
+ e.cellIndex = this.getCellNodeIndex(e.cellNode);
+ e.cell = (e.cellIndex >= 0 ? this.grid.getCell(e.cellIndex) : null);
+ },
+
+ // event dispatch
+ findTarget: function(inSource, inTag){
+ var n = inSource;
+ while(n && (n!=this.domNode) && (!(inTag in n) || (gridViewTag in n && n[gridViewTag] != this.view.id))){
+ n = n.parentNode;
+ }
+ return (n != this.domNode) ? n : null;
+ },
+
+ findRowTarget: function(inSource){
+ return this.findTarget(inSource, rowIndexTag);
+ },
+
+ isIntraNodeEvent: function(e){
+ try{
+ return (e.cellNode && e.relatedTarget && html.isDescendant(e.relatedTarget, e.cellNode));
+ }catch(x){
+ // e.relatedTarget has permission problem in FF if it's an input: https://bugzilla.mozilla.org/show_bug.cgi?id=208427
+ return false;
+ }
+ },
+
+ isIntraRowEvent: function(e){
+ try{
+ var row = e.relatedTarget && this.findRowTarget(e.relatedTarget);
+ return !row && (e.rowIndex==-1) || row && (e.rowIndex==row.gridRowIndex);
+ }catch(x){
+ // e.relatedTarget on INPUT has permission problem in FF: https://bugzilla.mozilla.org/show_bug.cgi?id=208427
+ return false;
+ }
+ },
+
+ dispatchEvent: function(e){
+ if(e.dispatch in this){
+ return this[e.dispatch](e);
+ }
+ return false;
+ },
+
+ // dispatched event handlers
+ domouseover: function(e){
+ if(e.cellNode && (e.cellNode!=this.lastOverCellNode)){
+ this.lastOverCellNode = e.cellNode;
+ this.grid.onMouseOver(e);
+ }
+ this.grid.onMouseOverRow(e);
+ },
+
+ domouseout: function(e){
+ if(e.cellNode && (e.cellNode==this.lastOverCellNode) && !this.isIntraNodeEvent(e, this.lastOverCellNode)){
+ this.lastOverCellNode = null;
+ this.grid.onMouseOut(e);
+ if(!this.isIntraRowEvent(e)){
+ this.grid.onMouseOutRow(e);
+ }
+ }
+ },
+
+ domousedown: function(e){
+ if (e.cellNode)
+ this.grid.onMouseDown(e);
+ this.grid.onMouseDownRow(e);
+ }
+ });
+
+ // Produces html for grid data content. Owned by grid and used internally
+ // for rendering data. Override to implement custom rendering.
+ var _ContentBuilder = dg._ContentBuilder = lang.extend(function(view){
+ _Builder.call(this, view);
+ },_Builder.prototype,{
+ update: function(){
+ this.prepareHtml();
+ },
+
+ // cache html for rendering data rows
+ prepareHtml: function(){
+ var defaultGet=this.grid.get, cells=this.view.structure.cells;
+ for(var j=0, row; (row=cells[j]); j++){
+ for(var i=0, cell; (cell=row[i]); i++){
+ cell.get = cell.get || (cell.value == undefined) && defaultGet;
+ cell.markup = this.generateCellMarkup(cell, cell.cellStyles, cell.cellClasses, false);
+ if (!this.grid.editable && cell.editable){
+ this.grid.editable = true;
+ }
+ }
+ }
+ },
+
+ // time critical: generate html using cache and data source
+ generateHtml: function(inDataIndex, inRowIndex){
+ var
+ html = this.getTableArray(),
+ v = this.view,
+ cells = v.structure.cells,
+ item = this.grid.getItem(inRowIndex);
+
+ util.fire(this.view, "onBeforeRow", [inRowIndex, cells]);
+ for(var j=0, row; (row=cells[j]); j++){
+ if(row.hidden || row.header){
+ continue;
+ }
+ html.push(!row.invisible ? '<tr>' : '<tr class="dojoxGridInvisible">');
+ for(var i=0, cell, m, cc, cs; (cell=row[i]); i++){
+ m = cell.markup; cc = cell.customClasses = []; cs = cell.customStyles = [];
+ // content (format can fill in cc and cs as side-effects)
+ m[5] = cell.format(inRowIndex, item);
+ if(has("ie") < 8 && (m[5] === null || m[5] === '' || /^\s+$/.test(m[5]))){
+ //fix IE 6/7 quirks - border style not effective for empty td
+ m[5] = '&nbsp;'
+ }
+ // classes
+ m[1] = cc.join(' ');
+ // styles
+ m[3] = cs.join(';');
+ // in-place concat
+ html.push.apply(html, m);
+ }
+ html.push('</tr>');
+ }
+ html.push('</table>');
+ return html.join(''); // String
+ },
+
+ decorateEvent: function(e){
+ e.rowNode = this.findRowTarget(e.target);
+ if(!e.rowNode){return false;}
+ e.rowIndex = e.rowNode[rowIndexTag];
+ this.baseDecorateEvent(e);
+ e.cell = this.grid.getCell(e.cellIndex);
+ return true; // Boolean
+ }
+ });
+
+ // Produces html for grid header content. Owned by grid and used internally
+ // for rendering data. Override to implement custom rendering.
+ var _HeaderBuilder = dg._HeaderBuilder = lang.extend(function(view){
+ this.moveable = null;
+ _Builder.call(this, view);
+ },_Builder.prototype,{
+ _skipBogusClicks: false,
+ overResizeWidth: 4,
+ minColWidth: 1,
+
+ update: function(){
+ if(this.tableMap){
+ this.tableMap.mapRows(this.view.structure.cells);
+ }else{
+ this.tableMap = new dg._TableMap(this.view.structure.cells);
+ }
+ },
+
+ generateHtml: function(inGetValue, inValue){
+ var html = this.getTableArray(), cells = this.view.structure.cells;
+
+ util.fire(this.view, "onBeforeRow", [-1, cells]);
+ for(var j=0, row; (row=cells[j]); j++){
+ if(row.hidden){
+ continue;
+ }
+ html.push(!row.invisible ? '<tr>' : '<tr class="dojoxGridInvisible">');
+ for(var i=0, cell, markup; (cell=row[i]); i++){
+ cell.customClasses = [];
+ cell.customStyles = [];
+ if(this.view.simpleStructure){
+ if(cell.draggable){
+ if(cell.headerClasses){
+ if(cell.headerClasses.indexOf('dojoDndItem') == -1){
+ cell.headerClasses += ' dojoDndItem';
+ }
+ }else{
+ cell.headerClasses = 'dojoDndItem';
+ }
+ }
+ if(cell.attrs){
+ if(cell.attrs.indexOf("dndType='gridColumn_") == -1){
+ cell.attrs += " dndType='gridColumn_" + this.grid.id + "'";
+ }
+ }else{
+ cell.attrs = "dndType='gridColumn_" + this.grid.id + "'";
+ }
+ }
+ markup = this.generateCellMarkup(cell, cell.headerStyles, cell.headerClasses, true);
+ // content
+ markup[5] = (inValue != undefined ? inValue : inGetValue(cell));
+ // styles
+ markup[3] = cell.customStyles.join(';');
+ // classes
+ markup[1] = cell.customClasses.join(' '); //(cell.customClasses ? ' ' + cell.customClasses : '');
+ html.push(markup.join(''));
+ }
+ html.push('</tr>');
+ }
+ html.push('</table>');
+ return html.join('');
+ },
+
+ // event helpers
+ getCellX: function(e){
+ var n, x = e.layerX;
+ if(has("mozilla") || has("ie") >= 9){
+ n = ascendDom(e.target, makeNotTagName("th"));
+ x -= (n && n.offsetLeft) || 0;
+ var t = e.sourceView.getScrollbarWidth();
+ if(!this.grid.isLeftToRight()/*&& e.sourceView.headerNode.scrollLeft < t*/){
+ //fix #11253
+ table = ascendDom(n,makeNotTagName("table"));
+ x -= (table && table.offsetLeft) || 0;
+ }
+ //x -= getProp(ascendDom(e.target, mkNotTagName("td")), "offsetLeft") || 0;
+ }
+ n = ascendDom(e.target, function(){
+ if(!n || n == e.cellNode){
+ return false;
+ }
+ // Mozilla 1.8 (FF 1.5) has a bug that makes offsetLeft = -parent border width
+ // when parent has border, overflow: hidden, and is positioned
+ // handle this problem here ... not a general solution!
+ x += (n.offsetLeft < 0 ? 0 : n.offsetLeft);
+ return true;
+ });
+ return x;
+ },
+
+ // event decoration
+ decorateEvent: function(e){
+ this.baseDecorateEvent(e);
+ e.rowIndex = -1;
+ e.cellX = this.getCellX(e);
+ return true;
+ },
+
+ // event handlers
+ // resizing
+ prepareResize: function(e, mod){
+ do{
+ var i = e.cellIndex;
+ e.cellNode = (i ? e.cellNode.parentNode.cells[i+mod] : null);
+ e.cellIndex = (e.cellNode ? this.getCellNodeIndex(e.cellNode) : -1);
+ }while(e.cellNode && e.cellNode.style.display == "none");
+ return Boolean(e.cellNode);
+ },
+
+ canResize: function(e){
+ if(!e.cellNode || e.cellNode.colSpan > 1){
+ return false;
+ }
+ var cell = this.grid.getCell(e.cellIndex);
+ return !cell.noresize && cell.canResize();
+ },
+
+ overLeftResizeArea: function(e){
+ // We are never over a resize area if we are in the process of moving
+ if(html.hasClass(win.body(), "dojoDndMove")){
+ return false;
+ }
+ //Bugfix for crazy IE problem (#8807). IE returns position information for the icon and text arrow divs
+ //as if they were still on the left instead of returning the position they were 'float: right' to.
+ //So, the resize check ends up checking the wrong adjacent cell. This checks to see if the hover was over
+ //the image or text nodes, then just ignored them/treat them not in scale range.
+ if(has("ie")){
+ var tN = e.target;
+ if(html.hasClass(tN, "dojoxGridArrowButtonNode") ||
+ html.hasClass(tN, "dojoxGridArrowButtonChar") ||
+ html.hasClass(tN, "dojoxGridColCaption")){
+ return false;
+ }
+ }
+
+ if(this.grid.isLeftToRight()){
+ return (e.cellIndex>0) && (e.cellX > 0 && e.cellX < this.overResizeWidth) && this.prepareResize(e, -1);
+ }
+ var t = e.cellNode && (e.cellX > 0 && e.cellX < this.overResizeWidth);
+ return t;
+ },
+
+ overRightResizeArea: function(e){
+ // We are never over a resize area if we are in the process of moving
+ if(html.hasClass(win.body(), "dojoDndMove")){
+ return false;
+ }
+ //Bugfix for crazy IE problem (#8807). IE returns position information for the icon and text arrow divs
+ //as if they were still on the left instead of returning the position they were 'float: right' to.
+ //So, the resize check ends up checking the wrong adjacent cell. This checks to see if the hover was over
+ //the image or text nodes, then just ignored them/treat them not in scale range.
+ if(has("ie")){
+ var tN = e.target;
+ if(html.hasClass(tN, "dojoxGridArrowButtonNode") ||
+ html.hasClass(tN, "dojoxGridArrowButtonChar") ||
+ html.hasClass(tN, "dojoxGridColCaption")){
+ return false;
+ }
+ }
+
+ if(this.grid.isLeftToRight()){
+ return e.cellNode && (e.cellX >= e.cellNode.offsetWidth - this.overResizeWidth);
+ }
+ return (e.cellIndex>0) && (e.cellX >= e.cellNode.offsetWidth - this.overResizeWidth) && this.prepareResize(e, -1);
+ },
+
+ domousemove: function(e){
+ //console.log(e.cellIndex, e.cellX, e.cellNode.offsetWidth);
+ if(!this.moveable){
+ var c = (this.overRightResizeArea(e) ? 'dojoxGridColResize' : (this.overLeftResizeArea(e) ? 'dojoxGridColResize' : ''));
+ if(c && !this.canResize(e)){
+ c = 'dojoxGridColNoResize';
+ }
+ html.toggleClass(e.sourceView.headerNode, "dojoxGridColNoResize", (c == "dojoxGridColNoResize"));
+ html.toggleClass(e.sourceView.headerNode, "dojoxGridColResize", (c == "dojoxGridColResize"));
+ if(c){
+ event.stop(e);
+ }
+ }
+ },
+
+ domousedown: function(e){
+ if(!this.moveable){
+ if((this.overRightResizeArea(e) || this.overLeftResizeArea(e)) && this.canResize(e)){
+ this.beginColumnResize(e);
+ }else{
+ this.grid.onMouseDown(e);
+ this.grid.onMouseOverRow(e);
+ }
+ //else{
+ // this.beginMoveColumn(e);
+ //}
+ }
+ },
+
+ doclick: function(e) {
+ if(this._skipBogusClicks){
+ event.stop(e);
+ return true;
+ }
+ return false;
+ },
+
+ // column resizing
+ colResizeSetup: function(/*Event Object*/e, /*boolean*/ isMouse ){
+ //Set up the drag object for column resizing
+ // Called with mouse event in case of drag and drop,
+ // Also called from keyboard shift-arrow event when focus is on a header
+ var headContentBox = html.contentBox(e.sourceView.headerNode);
+
+ if(isMouse){ //IE draws line even with no mouse down so separate from keyboard
+ this.lineDiv = document.createElement('div');
+
+ var vw = html.position(e.sourceView.headerNode, true);
+ var bodyContentBox = html.contentBox(e.sourceView.domNode);
+ //fix #11340
+ var l = e.pageX;
+ if(!this.grid.isLeftToRight() && has("ie") < 8){
+ l -= metrics.getScrollbar().w;
+ }
+ html.style(this.lineDiv, {
+ top: vw.y + "px",
+ left: l + "px",
+ height: (bodyContentBox.h + headContentBox.h) + "px"
+ });
+ html.addClass(this.lineDiv, "dojoxGridResizeColLine");
+ this.lineDiv._origLeft = l;
+ win.body().appendChild(this.lineDiv);
+ }
+ var spanners = [], nodes = this.tableMap.findOverlappingNodes(e.cellNode);
+ for(var i=0, cell; (cell=nodes[i]); i++){
+ spanners.push({ node: cell, index: this.getCellNodeIndex(cell), width: cell.offsetWidth });
+ //console.log("spanner: " + this.getCellNodeIndex(cell));
+ }
+
+ var view = e.sourceView;
+ var adj = this.grid.isLeftToRight() ? 1 : -1;
+ var views = e.grid.views.views;
+ var followers = [];
+ for(var j=view.idx+adj, cView; (cView=views[j]); j=j+adj){
+ followers.push({ node: cView.headerNode, left: window.parseInt(cView.headerNode.style.left) });
+ }
+ var table = view.headerContentNode.firstChild;
+ var drag = {
+ scrollLeft: e.sourceView.headerNode.scrollLeft,
+ view: view,
+ node: e.cellNode,
+ index: e.cellIndex,
+ w: html.contentBox(e.cellNode).w,
+ vw: headContentBox.w,
+ table: table,
+ tw: html.contentBox(table).w,
+ spanners: spanners,
+ followers: followers
+ };
+ return drag;
+ },
+ beginColumnResize: function(e){
+ this.moverDiv = document.createElement("div");
+ html.style(this.moverDiv,{position: "absolute", left:0}); // to make DnD work with dir=rtl
+ win.body().appendChild(this.moverDiv);
+ html.addClass(this.grid.domNode, "dojoxGridColumnResizing");
+ var m = (this.moveable = new Moveable(this.moverDiv));
+
+ var drag = this.colResizeSetup(e,true);
+
+ m.onMove = lang.hitch(this, "doResizeColumn", drag);
+
+ connect.connect(m, "onMoveStop", lang.hitch(this, function(){
+ this.endResizeColumn(drag);
+ if(drag.node.releaseCapture){
+ drag.node.releaseCapture();
+ }
+ this.moveable.destroy();
+ delete this.moveable;
+ this.moveable = null;
+ html.removeClass(this.grid.domNode, "dojoxGridColumnResizing");
+ }));
+
+ if(e.cellNode.setCapture){
+ e.cellNode.setCapture();
+ }
+ m.onMouseDown(e);
+ },
+
+ doResizeColumn: function(inDrag, mover, leftTop){
+ var changeX = leftTop.l;
+ var data = {
+ deltaX: changeX,
+ w: inDrag.w + (this.grid.isLeftToRight() ? changeX : -changeX),//fix #11341
+ vw: inDrag.vw + changeX,
+ tw: inDrag.tw + changeX
+ };
+
+ this.dragRecord = {inDrag: inDrag, mover: mover, leftTop:leftTop};
+
+ if(data.w >= this.minColWidth){
+ if (!mover) { // we are using keyboard do immediate resize
+ this.doResizeNow(inDrag, data);
+ }
+ else{
+ html.style(this.lineDiv, "left", (this.lineDiv._origLeft + data.deltaX) + "px");
+ }
+ }
+ },
+
+ endResizeColumn: function(inDrag){
+ if(this.dragRecord){
+ var leftTop = this.dragRecord.leftTop;
+ var changeX = this.grid.isLeftToRight() ? leftTop.l : -leftTop.l;
+ // Make sure we are not under our minimum
+ // http://bugs.dojotoolkit.org/ticket/9390
+ changeX += Math.max(inDrag.w + changeX, this.minColWidth) - (inDrag.w + changeX);
+ if(has("webkit") && inDrag.spanners.length){
+ // Webkit needs the pad border extents back in
+ changeX += html._getPadBorderExtents(inDrag.spanners[0].node).w;
+ }
+ var data = {
+ deltaX: changeX,
+ w: inDrag.w + changeX,
+ vw: inDrag.vw + changeX,
+ tw: inDrag.tw + changeX
+ };
+ // Only resize the columns when the drag has finished
+ this.doResizeNow(inDrag, data);
+ delete this.dragRecord;
+ }
+
+ html.destroy(this.lineDiv);
+ html.destroy(this.moverDiv);
+ html.destroy(this.moverDiv);
+ delete this.moverDiv;
+ this._skipBogusClicks = true;
+ inDrag.view.update();
+ this._skipBogusClicks = false;
+ this.grid.onResizeColumn(inDrag.index);
+ },
+ doResizeNow: function(inDrag, data){
+ inDrag.view.convertColPctToFixed();
+ if(inDrag.view.flexCells && !inDrag.view.testFlexCells()){
+ var t = findTable(inDrag.node);
+ if(t){
+ (t.style.width = '');
+ }
+ }
+ var i, s, sw, f, fl;
+ for(i=0; (s=inDrag.spanners[i]); i++){
+ sw = s.width + data.deltaX;
+ if(sw > 0){
+ s.node.style.width = sw + 'px';
+ inDrag.view.setColWidth(s.index, sw);
+ }
+ }
+ if(this.grid.isLeftToRight() || !has("ie")){//fix #11339
+ for(i=0; (f=inDrag.followers[i]); i++){
+ fl = f.left + data.deltaX;
+ f.node.style.left = fl + 'px';
+ }
+ }
+ inDrag.node.style.width = data.w + 'px';
+ inDrag.view.setColWidth(inDrag.index, data.w);
+ inDrag.view.headerNode.style.width = data.vw + 'px';
+ inDrag.view.setColumnsWidth(data.tw);
+ if(!this.grid.isLeftToRight()){
+ inDrag.view.headerNode.scrollLeft = inDrag.scrollLeft + data.deltaX;
+ }
+ }
+ });
+
+ // Maps an html table into a structure parsable for information about cell row and col spanning.
+ // Used by HeaderBuilder.
+ dg._TableMap = lang.extend(function(rows){
+ this.mapRows(rows);
+ },{
+ map: null,
+
+ mapRows: function(inRows){
+ // summary: Map table topography
+
+ //console.log('mapRows');
+ // # of rows
+ var rowCount = inRows.length;
+ if(!rowCount){
+ return;
+ }
+ // map which columns and rows fill which cells
+ this.map = [];
+ var row;
+ for(var k=0; (row=inRows[k]); k++){
+ this.map[k] = [];
+ }
+ for(var j=0; (row=inRows[j]); j++){
+ for(var i=0, x=0, cell, colSpan, rowSpan; (cell=row[i]); i++){
+ while(this.map[j][x]){x++;}
+ this.map[j][x] = { c: i, r: j };
+ rowSpan = cell.rowSpan || 1;
+ colSpan = cell.colSpan || 1;
+ for(var y=0; y<rowSpan; y++){
+ for(var s=0; s<colSpan; s++){
+ this.map[j+y][x+s] = this.map[j][x];
+ }
+ }
+ x += colSpan;
+ }
+ }
+ //this.dumMap();
+ },
+
+ dumpMap: function(){
+ for(var j=0, row, h=''; (row=this.map[j]); j++,h=''){
+ for(var i=0, cell; (cell=row[i]); i++){
+ h += cell.r + ',' + cell.c + ' ';
+ }
+ }
+ },
+
+ getMapCoords: function(inRow, inCol){
+ // summary: Find node's map coords by it's structure coords
+ for(var j=0, row; (row=this.map[j]); j++){
+ for(var i=0, cell; (cell=row[i]); i++){
+ if(cell.c==inCol && cell.r == inRow){
+ return { j: j, i: i };
+ }
+ //else{console.log(inRow, inCol, ' : ', i, j, " : ", cell.r, cell.c); };
+ }
+ }
+ return { j: -1, i: -1 };
+ },
+
+ getNode: function(inTable, inRow, inCol){
+ // summary: Find a node in inNode's table with the given structure coords
+ var row = inTable && inTable.rows[inRow];
+ return row && row.cells[inCol];
+ },
+
+ _findOverlappingNodes: function(inTable, inRow, inCol){
+ var nodes = [];
+ var m = this.getMapCoords(inRow, inCol);
+ //console.log("node j: %d, i: %d", m.j, m.i);
+ for(var j=0, row; (row=this.map[j]); j++){
+ if(j == m.j){ continue; }
+ var rw = row[m.i];
+ //console.log("overlaps: r: %d, c: %d", rw.r, rw.c);
+ var n = (rw?this.getNode(inTable, rw.r, rw.c):null);
+ if(n){ nodes.push(n); }
+ }
+ //console.log(nodes);
+ return nodes;
+ },
+
+ findOverlappingNodes: function(inNode){
+ return this._findOverlappingNodes(findTable(inNode), getTrIndex(inNode.parentNode), getTdIndex(inNode));
+ }
+ });
+
+ return {
+ _Builder: _Builder,
+ _HeaderBuilder: _HeaderBuilder,
+ _ContentBuilder: _ContentBuilder
+ };
+}); \ No newline at end of file
diff --git a/js/dojo-1.7.2/dojox/grid/_CheckBoxSelector.js b/js/dojo-1.7.2/dojox/grid/_CheckBoxSelector.js
new file mode 100644
index 0000000..56434fe
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/_CheckBoxSelector.js
@@ -0,0 +1,4 @@
+//>>built
+define("dojox/grid/_CheckBoxSelector", ["../main", "./_Selector"], function(dojox){
+ return dojox.grid._CheckBoxSelector;
+}); \ No newline at end of file
diff --git a/js/dojo-1.7.2/dojox/grid/_EditManager.js b/js/dojo-1.7.2/dojox/grid/_EditManager.js
new file mode 100644
index 0000000..bc3f2b9
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/_EditManager.js
@@ -0,0 +1,259 @@
+//>>built
+define("dojox/grid/_EditManager", [
+ "dojo/_base/lang",
+ "dojo/_base/array",
+ "dojo/_base/declare",
+ "dojo/_base/connect",
+ "dojo/_base/sniff",
+ "./util"
+], function(lang, array, declare, connect, has, util){
+
+return declare("dojox.grid._EditManager", null, {
+ // summary:
+ // Controls grid cell editing process. Owned by grid and used internally for editing.
+ constructor: function(inGrid){
+ // inGrid: dojox.Grid
+ // The dojox.Grid this editor should be attached to
+ this.grid = inGrid;
+ if(has("ie")){
+ this.connections = [connect.connect(document.body, "onfocus", lang.hitch(this, "_boomerangFocus"))];
+ }else{
+ this.connections = [connect.connect(this.grid, 'onBlur', this, 'apply')];
+ }
+ },
+
+ info: {},
+
+ destroy: function(){
+ array.forEach(this.connections, connect.disconnect);
+ },
+
+ cellFocus: function(inCell, inRowIndex){
+ // summary:
+ // Invoke editing when cell is focused
+ // inCell: cell object
+ // Grid cell object
+ // inRowIndex: Integer
+ // Grid row index
+ if(this.grid.singleClickEdit || this.isEditRow(inRowIndex)){
+ // if same row or quick editing, edit
+ this.setEditCell(inCell, inRowIndex);
+ }else{
+ // otherwise, apply any pending row edits
+ this.apply();
+ }
+ // if dynamic or static editing...
+ if(this.isEditing() || (inCell && inCell.editable && inCell.alwaysEditing)){
+ // let the editor focus itself as needed
+ this._focusEditor(inCell, inRowIndex);
+ }
+ },
+
+ rowClick: function(e){
+ if(this.isEditing() && !this.isEditRow(e.rowIndex)){
+ this.apply();
+ }
+ },
+
+ styleRow: function(inRow){
+ if(inRow.index == this.info.rowIndex){
+ inRow.customClasses += ' dojoxGridRowEditing';
+ }
+ },
+
+ dispatchEvent: function(e){
+ var c = e.cell, ed = (c && c["editable"]) ? c : 0;
+ return ed && ed.dispatchEvent(e.dispatch, e);
+ },
+
+ // Editing
+ isEditing: function(){
+ // summary:
+ // Indicates editing state of the grid.
+ // returns: Boolean
+ // True if grid is actively editing
+ return this.info.rowIndex !== undefined;
+ },
+
+ isEditCell: function(inRowIndex, inCellIndex){
+ // summary:
+ // Indicates if the given cell is being edited.
+ // inRowIndex: Integer
+ // Grid row index
+ // inCellIndex: Integer
+ // Grid cell index
+ // returns: Boolean
+ // True if given cell is being edited
+ return (this.info.rowIndex === inRowIndex) && (this.info.cell.index == inCellIndex);
+ },
+
+ isEditRow: function(inRowIndex){
+ // summary:
+ // Indicates if the given row is being edited.
+ // inRowIndex: Integer
+ // Grid row index
+ // returns: Boolean
+ // True if given row is being edited
+ return this.info.rowIndex === inRowIndex;
+ },
+
+ setEditCell: function(inCell, inRowIndex){
+ // summary:
+ // Set the given cell to be edited
+ // inRowIndex: Integer
+ // Grid row index
+ // inCell: Object
+ // Grid cell object
+ if(!this.isEditCell(inRowIndex, inCell.index) && this.grid.canEdit && this.grid.canEdit(inCell, inRowIndex)){
+ this.start(inCell, inRowIndex, this.isEditRow(inRowIndex) || inCell.editable);
+ }
+ },
+
+ _focusEditor: function(inCell, inRowIndex){
+ util.fire(inCell, "focus", [inRowIndex]);
+ },
+
+ focusEditor: function(){
+ if(this.isEditing()){
+ this._focusEditor(this.info.cell, this.info.rowIndex);
+ }
+ },
+
+ // implement fix for focus boomerang effect on IE
+ _boomerangWindow: 500,
+ _shouldCatchBoomerang: function(){
+ return this._catchBoomerang > new Date().getTime();
+ },
+ _boomerangFocus: function(){
+ //console.log("_boomerangFocus");
+ if(this._shouldCatchBoomerang()){
+ // make sure we don't utterly lose focus
+ this.grid.focus.focusGrid();
+ // let the editor focus itself as needed
+ this.focusEditor();
+ // only catch once
+ this._catchBoomerang = 0;
+ }
+ },
+ _doCatchBoomerang: function(){
+ // give ourselves a few ms to boomerang IE focus effects
+ if(has("ie")){this._catchBoomerang = new Date().getTime() + this._boomerangWindow;}
+ },
+ // end boomerang fix API
+
+ start: function(inCell, inRowIndex, inEditing){
+ if(!this._isValidInput()){
+ return;
+ }
+ this.grid.beginUpdate();
+ this.editorApply();
+ if(this.isEditing() && !this.isEditRow(inRowIndex)){
+ this.applyRowEdit();
+ this.grid.updateRow(inRowIndex);
+ }
+ if(inEditing){
+ this.info = { cell: inCell, rowIndex: inRowIndex };
+ this.grid.doStartEdit(inCell, inRowIndex);
+ this.grid.updateRow(inRowIndex);
+ }else{
+ this.info = {};
+ }
+ this.grid.endUpdate();
+ // make sure we don't utterly lose focus
+ this.grid.focus.focusGrid();
+ // let the editor focus itself as needed
+ this._focusEditor(inCell, inRowIndex);
+ // give ourselves a few ms to boomerang IE focus effects
+ this._doCatchBoomerang();
+ },
+
+ _editorDo: function(inMethod){
+ var c = this.info.cell;
+ //c && c.editor && c.editor[inMethod](c, this.info.rowIndex);
+ if(c && c.editable){
+ c[inMethod](this.info.rowIndex);
+ }
+ },
+
+ editorApply: function(){
+ this._editorDo("apply");
+ },
+
+ editorCancel: function(){
+ this._editorDo("cancel");
+ },
+
+ applyCellEdit: function(inValue, inCell, inRowIndex){
+ if(this.grid.canEdit(inCell, inRowIndex)){
+ this.grid.doApplyCellEdit(inValue, inRowIndex, inCell.field);
+ }
+ },
+
+ applyRowEdit: function(){
+ this.grid.doApplyEdit(this.info.rowIndex, this.info.cell.field);
+ },
+
+ apply: function(){
+ // summary:
+ // Apply a grid edit
+ if(this.isEditing() && this._isValidInput()){
+ this.grid.beginUpdate();
+ this.editorApply();
+ this.applyRowEdit();
+ this.info = {};
+ this.grid.endUpdate();
+ this.grid.focus.focusGrid();
+ this._doCatchBoomerang();
+ }
+ },
+
+ cancel: function(){
+ // summary:
+ // Cancel a grid edit
+ if(this.isEditing()){
+ this.grid.beginUpdate();
+ this.editorCancel();
+ this.info = {};
+ this.grid.endUpdate();
+ this.grid.focus.focusGrid();
+ this._doCatchBoomerang();
+ }
+ },
+
+ save: function(inRowIndex, inView){
+ // summary:
+ // Save the grid editing state
+ // inRowIndex: Integer
+ // Grid row index
+ // inView: Object
+ // Grid view
+ var c = this.info.cell;
+ if(this.isEditRow(inRowIndex) && (!inView || c.view==inView) && c.editable){
+ c.save(c, this.info.rowIndex);
+ }
+ },
+
+ restore: function(inView, inRowIndex){
+ // summary:
+ // Restores the grid editing state
+ // inRowIndex: Integer
+ // Grid row index
+ // inView: Object
+ // Grid view
+ var c = this.info.cell;
+ if(this.isEditRow(inRowIndex) && c.view == inView && c.editable){
+ c.restore(this.info.rowIndex);
+ }
+ },
+
+ _isValidInput: function(){
+ var w = (this.info.cell || {}).widget;
+ if(!w || !w.isValid){
+ //no validation needed
+ return true;
+ }
+ w.focused = true;
+ return w.isValid(true);
+ }
+});
+}); \ No newline at end of file
diff --git a/js/dojo-1.7.2/dojox/grid/_Events.js b/js/dojo-1.7.2/dojox/grid/_Events.js
new file mode 100644
index 0000000..0156a86
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/_Events.js
@@ -0,0 +1,508 @@
+//>>built
+define("dojox/grid/_Events", [
+ "dojo/keys",
+ "dojo/dom-class",
+ "dojo/_base/declare",
+ "dojo/_base/event",
+ "dojo/_base/sniff"
+], function(keys, domClass, declare, event, has){
+
+return declare("dojox.grid._Events", null, {
+ // summary:
+ // _Grid mixin that provides default implementations for grid events.
+ // description:
+ // Default synthetic events dispatched for _Grid. dojo.connect to events to
+ // retain default implementation or override them for custom handling.
+
+ // cellOverClass: String
+ // css class to apply to grid cells over which the cursor is placed.
+ cellOverClass: "dojoxGridCellOver",
+
+ onKeyEvent: function(e){
+ // summary: top level handler for Key Events
+ this.dispatchKeyEvent(e);
+ },
+
+ onContentEvent: function(e){
+ // summary: Top level handler for Content events
+ this.dispatchContentEvent(e);
+ },
+
+ onHeaderEvent: function(e){
+ // summary: Top level handler for header events
+ this.dispatchHeaderEvent(e);
+ },
+
+ onStyleRow: function(inRow){
+ // summary:
+ // Perform row styling on a given row. Called whenever row styling is updated.
+ //
+ // inRow: Object
+ // Object containing row state information: selected, true if the row is selcted; over:
+ // true of the mouse is over the row; odd: true if the row is odd. Use customClasses and
+ // customStyles to control row css classes and styles; both properties are strings.
+ //
+ // example: onStyleRow({ selected: true, over:true, odd:false })
+ var i = inRow;
+ i.customClasses += (i.odd?" dojoxGridRowOdd":"") + (i.selected?" dojoxGridRowSelected":"") + (i.over?" dojoxGridRowOver":"");
+ this.focus.styleRow(inRow);
+ this.edit.styleRow(inRow);
+ },
+
+ onKeyDown: function(e){
+ // summary:
+ // Grid key event handler. By default enter begins editing and applies edits, escape cancels an edit,
+ // tab, shift-tab, and arrow keys move grid cell focus.
+ if(e.altKey || e.metaKey){
+ return;
+ }
+ var colIdx;
+ switch(e.keyCode){
+ case keys.ESCAPE:
+ this.edit.cancel();
+ break;
+ case keys.ENTER:
+ if(!this.edit.isEditing()){
+ colIdx = this.focus.getHeaderIndex();
+ if(colIdx >= 0) {
+ this.setSortIndex(colIdx);
+ break;
+ }else {
+ this.selection.clickSelect(this.focus.rowIndex, dojo.isCopyKey(e), e.shiftKey);
+ }
+ event.stop(e);
+ }
+ if(!e.shiftKey){
+ var isEditing = this.edit.isEditing();
+ this.edit.apply();
+ if(!isEditing){
+ this.edit.setEditCell(this.focus.cell, this.focus.rowIndex);
+ }
+ }
+ if (!this.edit.isEditing()){
+ var curView = this.focus.focusView || this.views.views[0]; //if no focusView than only one view
+ curView.content.decorateEvent(e);
+ this.onRowClick(e);
+ event.stop(e);
+ }
+ break;
+ case keys.SPACE:
+ if(!this.edit.isEditing()){
+ colIdx = this.focus.getHeaderIndex();
+ if(colIdx >= 0) {
+ this.setSortIndex(colIdx);
+ break;
+ }else {
+ this.selection.clickSelect(this.focus.rowIndex, dojo.isCopyKey(e), e.shiftKey);
+ }
+ event.stop(e);
+ }
+ break;
+ case keys.TAB:
+ this.focus[e.shiftKey ? 'previousKey' : 'nextKey'](e);
+ break;
+ case keys.LEFT_ARROW:
+ case keys.RIGHT_ARROW:
+ if(!this.edit.isEditing()){
+ var keyCode = e.keyCode; // IE seems to lose after stopEvent when modifier keys
+ event.stop(e);
+ colIdx = this.focus.getHeaderIndex();
+ if (colIdx >= 0 && (e.shiftKey && e.ctrlKey)){
+ this.focus.colSizeAdjust(e, colIdx, (keyCode == keys.LEFT_ARROW ? -1 : 1)*5);
+ }
+ else{
+ var offset = (keyCode == keys.LEFT_ARROW) ? 1 : -1;
+ if(this.isLeftToRight()){ offset *= -1; }
+ this.focus.move(0, offset);
+ }
+ }
+ break;
+ case keys.UP_ARROW:
+ if(!this.edit.isEditing() && this.focus.rowIndex !== 0){
+ event.stop(e);
+ this.focus.move(-1, 0);
+ }
+ break;
+ case keys.DOWN_ARROW:
+ if(!this.edit.isEditing() && this.focus.rowIndex+1 != this.rowCount){
+ event.stop(e);
+ this.focus.move(1, 0);
+ }
+ break;
+ case keys.PAGE_UP:
+ if(!this.edit.isEditing() && this.focus.rowIndex !== 0){
+ event.stop(e);
+ if(this.focus.rowIndex != this.scroller.firstVisibleRow+1){
+ this.focus.move(this.scroller.firstVisibleRow-this.focus.rowIndex, 0);
+ }else{
+ this.setScrollTop(this.scroller.findScrollTop(this.focus.rowIndex-1));
+ this.focus.move(this.scroller.firstVisibleRow-this.scroller.lastVisibleRow+1, 0);
+ }
+ }
+ break;
+ case keys.PAGE_DOWN:
+ if(!this.edit.isEditing() && this.focus.rowIndex+1 != this.rowCount){
+ event.stop(e);
+ if(this.focus.rowIndex != this.scroller.lastVisibleRow-1){
+ this.focus.move(this.scroller.lastVisibleRow-this.focus.rowIndex-1, 0);
+ }else{
+ this.setScrollTop(this.scroller.findScrollTop(this.focus.rowIndex+1));
+ this.focus.move(this.scroller.lastVisibleRow-this.scroller.firstVisibleRow-1, 0);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ },
+
+ onMouseOver: function(e){
+ // summary:
+ // Event fired when mouse is over the grid.
+ // e: Event
+ // Decorated event object contains reference to grid, cell, and rowIndex
+ e.rowIndex == -1 ? this.onHeaderCellMouseOver(e) : this.onCellMouseOver(e);
+ },
+
+ onMouseOut: function(e){
+ // summary:
+ // Event fired when mouse moves out of the grid.
+ // e: Event
+ // Decorated event object that contains reference to grid, cell, and rowIndex
+ e.rowIndex == -1 ? this.onHeaderCellMouseOut(e) : this.onCellMouseOut(e);
+ },
+
+ onMouseDown: function(e){
+ // summary:
+ // Event fired when mouse is down inside grid.
+ // e: Event
+ // Decorated event object that contains reference to grid, cell, and rowIndex
+ e.rowIndex == -1 ? this.onHeaderCellMouseDown(e) : this.onCellMouseDown(e);
+ },
+
+ onMouseOverRow: function(e){
+ // summary:
+ // Event fired when mouse is over any row (data or header).
+ // e: Event
+ // Decorated event object contains reference to grid, cell, and rowIndex
+ if(!this.rows.isOver(e.rowIndex)){
+ this.rows.setOverRow(e.rowIndex);
+ e.rowIndex == -1 ? this.onHeaderMouseOver(e) : this.onRowMouseOver(e);
+ }
+ },
+ onMouseOutRow: function(e){
+ // summary:
+ // Event fired when mouse moves out of any row (data or header).
+ // e: Event
+ // Decorated event object contains reference to grid, cell, and rowIndex
+ if(this.rows.isOver(-1)){
+ this.onHeaderMouseOut(e);
+ }else if(!this.rows.isOver(-2)){
+ this.rows.setOverRow(-2);
+ this.onRowMouseOut(e);
+ }
+ },
+
+ onMouseDownRow: function(e){
+ // summary:
+ // Event fired when mouse is down inside grid row
+ // e: Event
+ // Decorated event object that contains reference to grid, cell, and rowIndex
+ if(e.rowIndex != -1)
+ this.onRowMouseDown(e);
+ },
+
+ // cell events
+ onCellMouseOver: function(e){
+ // summary:
+ // Event fired when mouse is over a cell.
+ // e: Event
+ // Decorated event object contains reference to grid, cell, and rowIndex
+ if(e.cellNode){
+ domClass.add(e.cellNode, this.cellOverClass);
+ }
+ },
+
+ onCellMouseOut: function(e){
+ // summary:
+ // Event fired when mouse moves out of a cell.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ if(e.cellNode){
+ domClass.remove(e.cellNode, this.cellOverClass);
+ }
+ },
+
+ onCellMouseDown: function(e){
+ // summary:
+ // Event fired when mouse is down in a header cell.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ },
+
+ onCellClick: function(e){
+ // summary:
+ // Event fired when a cell is clicked.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ this._click[0] = this._click[1];
+ this._click[1] = e;
+ if(!this.edit.isEditCell(e.rowIndex, e.cellIndex)){
+ this.focus.setFocusCell(e.cell, e.rowIndex);
+ }
+ // in some cases click[0] is null which causes false doubeClicks. Fixes #100703
+ if(this._click.length > 1 && this._click[0] == null){
+ this._click.shift();
+ }
+ this.onRowClick(e);
+ },
+
+ onCellDblClick: function(e){
+ // summary:
+ // Event fired when a cell is double-clicked.
+ // e: Event
+ // Decorated event object contains reference to grid, cell, and rowIndex
+ var event;
+ if(this._click.length > 1 && has("ie")){
+ event = this._click[1];
+ }else if(this._click.length > 1 && this._click[0].rowIndex != this._click[1].rowIndex){
+ event = this._click[0];
+ }else{
+ event = e;
+ }
+ this.focus.setFocusCell(event.cell, event.rowIndex);
+ this.onRowClick(event);
+ this.edit.setEditCell(event.cell, event.rowIndex);
+ this.onRowDblClick(e);
+ },
+
+ onCellContextMenu: function(e){
+ // summary:
+ // Event fired when a cell context menu is accessed via mouse right click.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ this.onRowContextMenu(e);
+ },
+
+ onCellFocus: function(inCell, inRowIndex){
+ // summary:
+ // Event fired when a cell receives focus.
+ // inCell: Object
+ // Cell object containing properties of the grid column.
+ // inRowIndex: Integer
+ // Index of the grid row
+ this.edit.cellFocus(inCell, inRowIndex);
+ },
+
+ // row events
+ onRowClick: function(e){
+ // summary:
+ // Event fired when a row is clicked.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ this.edit.rowClick(e);
+ this.selection.clickSelectEvent(e);
+ },
+
+ onRowDblClick: function(e){
+ // summary:
+ // Event fired when a row is double clicked.
+ // e: Event
+ // decorated event object which contains reference to grid, cell, and rowIndex
+ },
+
+ onRowMouseOver: function(e){
+ // summary:
+ // Event fired when mouse moves over a data row.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ },
+
+ onRowMouseOut: function(e){
+ // summary:
+ // Event fired when mouse moves out of a data row.
+ // e: Event
+ // Decorated event object contains reference to grid, cell, and rowIndex
+ },
+
+ onRowMouseDown: function(e){
+ // summary:
+ // Event fired when mouse is down in a row.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ },
+
+ onRowContextMenu: function(e){
+ // summary:
+ // Event fired when a row context menu is accessed via mouse right click.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ event.stop(e);
+ },
+
+ // header events
+ onHeaderMouseOver: function(e){
+ // summary:
+ // Event fired when mouse moves over the grid header.
+ // e: Event
+ // Decorated event object contains reference to grid, cell, and rowIndex
+ },
+
+ onHeaderMouseOut: function(e){
+ // summary:
+ // Event fired when mouse moves out of the grid header.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ },
+
+ onHeaderCellMouseOver: function(e){
+ // summary:
+ // Event fired when mouse moves over a header cell.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ if(e.cellNode){
+ domClass.add(e.cellNode, this.cellOverClass);
+ }
+ },
+
+ onHeaderCellMouseOut: function(e){
+ // summary:
+ // Event fired when mouse moves out of a header cell.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ if(e.cellNode){
+ domClass.remove(e.cellNode, this.cellOverClass);
+ }
+ },
+
+ onHeaderCellMouseDown: function(e) {
+ // summary:
+ // Event fired when mouse is down in a header cell.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ },
+
+ onHeaderClick: function(e){
+ // summary:
+ // Event fired when the grid header is clicked.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ },
+
+ onHeaderCellClick: function(e){
+ // summary:
+ // Event fired when a header cell is clicked.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ this.setSortIndex(e.cell.index);
+ this.onHeaderClick(e);
+ },
+
+ onHeaderDblClick: function(e){
+ // summary:
+ // Event fired when the grid header is double clicked.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ },
+
+ onHeaderCellDblClick: function(e){
+ // summary:
+ // Event fired when a header cell is double clicked.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ this.onHeaderDblClick(e);
+ },
+
+ onHeaderCellContextMenu: function(e){
+ // summary:
+ // Event fired when a header cell context menu is accessed via mouse right click.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ this.onHeaderContextMenu(e);
+ },
+
+ onHeaderContextMenu: function(e){
+ // summary:
+ // Event fired when the grid header context menu is accessed via mouse right click.
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ if(!this.headerMenu){
+ event.stop(e);
+ }
+ },
+
+ // editing
+ onStartEdit: function(inCell, inRowIndex){
+ // summary:
+ // Event fired when editing is started for a given grid cell
+ // inCell: Object
+ // Cell object containing properties of the grid column.
+ // inRowIndex: Integer
+ // Index of the grid row
+ },
+
+ onApplyCellEdit: function(inValue, inRowIndex, inFieldIndex){
+ // summary:
+ // Event fired when editing is applied for a given grid cell
+ // inValue: String
+ // Value from cell editor
+ // inRowIndex: Integer
+ // Index of the grid row
+ // inFieldIndex: Integer
+ // Index in the grid's data store
+ },
+
+ onCancelEdit: function(inRowIndex){
+ // summary:
+ // Event fired when editing is cancelled for a given grid cell
+ // inRowIndex: Integer
+ // Index of the grid row
+ },
+
+ onApplyEdit: function(inRowIndex){
+ // summary:
+ // Event fired when editing is applied for a given grid row
+ // inRowIndex: Integer
+ // Index of the grid row
+ },
+
+ onCanSelect: function(inRowIndex){
+ // summary:
+ // Event to determine if a grid row may be selected
+ // inRowIndex: Integer
+ // Index of the grid row
+ // returns: Boolean
+ // true if the row can be selected
+ return true;
+ },
+
+ onCanDeselect: function(inRowIndex){
+ // summary:
+ // Event to determine if a grid row may be deselected
+ // inRowIndex: Integer
+ // Index of the grid row
+ // returns: Boolean
+ // true if the row can be deselected
+ return true;
+ },
+
+ onSelected: function(inRowIndex){
+ // summary:
+ // Event fired when a grid row is selected
+ // inRowIndex: Integer
+ // Index of the grid row
+ this.updateRowStyles(inRowIndex);
+ },
+
+ onDeselected: function(inRowIndex){
+ // summary:
+ // Event fired when a grid row is deselected
+ // inRowIndex: Integer
+ // Index of the grid row
+ this.updateRowStyles(inRowIndex);
+ },
+
+ onSelectionChanged: function(){
+ }
+});
+}); \ No newline at end of file
diff --git a/js/dojo-1.7.2/dojox/grid/_FocusManager.js b/js/dojo-1.7.2/dojox/grid/_FocusManager.js
new file mode 100644
index 0000000..76d5784
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/_FocusManager.js
@@ -0,0 +1,642 @@
+//>>built
+define("dojox/grid/_FocusManager", [
+ "dojo/_base/array",
+ "dojo/_base/lang",
+ "dojo/_base/declare",
+ "dojo/_base/connect",
+ "dojo/_base/event",
+ "dojo/_base/sniff",
+ "dojo/query",
+ "./util",
+ "dojo/_base/html"
+], function(array, lang, declare, connect, event, has, query, util, html){
+
+// focus management
+return declare("dojox.grid._FocusManager", null, {
+ // summary:
+ // Controls grid cell focus. Owned by grid and used internally for focusing.
+ // Note: grid cell actually receives keyboard input only when cell is being edited.
+ constructor: function(inGrid){
+ this.grid = inGrid;
+ this.cell = null;
+ this.rowIndex = -1;
+ this._connects = [];
+ this._headerConnects = [];
+ this.headerMenu = this.grid.headerMenu;
+ this._connects.push(connect.connect(this.grid.domNode, "onfocus", this, "doFocus"));
+ this._connects.push(connect.connect(this.grid.domNode, "onblur", this, "doBlur"));
+ this._connects.push(connect.connect(this.grid.domNode, "mousedown", this, "_mouseDown"));
+ this._connects.push(connect.connect(this.grid.domNode, "mouseup", this, "_mouseUp"));
+ this._connects.push(connect.connect(this.grid.domNode, "oncontextmenu", this, "doContextMenu"));
+ this._connects.push(connect.connect(this.grid.lastFocusNode, "onfocus", this, "doLastNodeFocus"));
+ this._connects.push(connect.connect(this.grid.lastFocusNode, "onblur", this, "doLastNodeBlur"));
+ this._connects.push(connect.connect(this.grid,"_onFetchComplete", this, "_delayedCellFocus"));
+ this._connects.push(connect.connect(this.grid,"postrender", this, "_delayedHeaderFocus"));
+ },
+ destroy: function(){
+ array.forEach(this._connects, connect.disconnect);
+ array.forEach(this._headerConnects, connect.disconnect);
+ delete this.grid;
+ delete this.cell;
+ },
+ _colHeadNode: null,
+ _colHeadFocusIdx: null,
+ _contextMenuBindNode: null,
+ tabbingOut: false,
+ focusClass: "dojoxGridCellFocus",
+ focusView: null,
+ initFocusView: function(){
+ this.focusView = this.grid.views.getFirstScrollingView() || this.focusView || this.grid.views.views[0];
+ this._initColumnHeaders();
+ },
+ isFocusCell: function(inCell, inRowIndex){
+ // summary:
+ // states if the given cell is focused
+ // inCell: object
+ // grid cell object
+ // inRowIndex: int
+ // grid row index
+ // returns:
+ // true of the given grid cell is focused
+ return (this.cell == inCell) && (this.rowIndex == inRowIndex);
+ },
+ isLastFocusCell: function(){
+ if(this.cell){
+ return (this.rowIndex == this.grid.rowCount-1) && (this.cell.index == this.grid.layout.cellCount-1);
+ }
+ return false;
+ },
+ isFirstFocusCell: function(){
+ if(this.cell){
+ return (this.rowIndex === 0) && (this.cell.index === 0);
+ }
+ return false;
+ },
+ isNoFocusCell: function(){
+ return (this.rowIndex < 0) || !this.cell;
+ },
+ isNavHeader: function(){
+ // summary:
+ // states whether currently navigating among column headers.
+ // returns:
+ // true if focus is on a column header; false otherwise.
+ return (!!this._colHeadNode);
+ },
+ getHeaderIndex: function(){
+ // summary:
+ // if one of the column headers currently has focus, return its index.
+ // returns:
+ // index of the focused column header, or -1 if none have focus.
+ if(this._colHeadNode){
+ return array.indexOf(this._findHeaderCells(), this._colHeadNode);
+ }else{
+ return -1;
+ }
+ },
+ _focusifyCellNode: function(inBork){
+ var n = this.cell && this.cell.getNode(this.rowIndex);
+ if(n){
+ html.toggleClass(n, this.focusClass, inBork);
+ if(inBork){
+ var sl = this.scrollIntoView();
+ try{
+ if(!this.grid.edit.isEditing()){
+ util.fire(n, "focus");
+ if(sl){ this.cell.view.scrollboxNode.scrollLeft = sl; }
+ }
+ }catch(e){}
+ }
+ }
+ },
+ _delayedCellFocus: function(){
+ if(this.isNavHeader()||!this.grid.focused){
+ return;
+ }
+ var n = this.cell && this.cell.getNode(this.rowIndex);
+ if(n){
+ try{
+ if(!this.grid.edit.isEditing()){
+ html.toggleClass(n, this.focusClass, true);
+ if(this._colHeadNode){
+ this.blurHeader();
+ }
+ util.fire(n, "focus");
+ }
+ }
+ catch(e){}
+ }
+ },
+ _delayedHeaderFocus: function(){
+ if(this.isNavHeader()){
+ this.focusHeader();
+ this.grid.domNode.focus();
+ }
+ },
+ _initColumnHeaders: function(){
+ array.forEach(this._headerConnects, connect.disconnect);
+ this._headerConnects = [];
+ var headers = this._findHeaderCells();
+ for(var i = 0; i < headers.length; i++){
+ this._headerConnects.push(connect.connect(headers[i], "onfocus", this, "doColHeaderFocus"));
+ this._headerConnects.push(connect.connect(headers[i], "onblur", this, "doColHeaderBlur"));
+ }
+ },
+ _findHeaderCells: function(){
+ // This should be a one liner:
+ // query("th[tabindex=-1]", this.grid.viewsHeaderNode);
+ // But there is a bug in query() for IE -- see trac #7037.
+ var allHeads = query("th", this.grid.viewsHeaderNode);
+ var headers = [];
+ for (var i = 0; i < allHeads.length; i++){
+ var aHead = allHeads[i];
+ var hasTabIdx = html.hasAttr(aHead, "tabIndex");
+ var tabindex = html.attr(aHead, "tabIndex");
+ if (hasTabIdx && tabindex < 0) {
+ headers.push(aHead);
+ }
+ }
+ return headers;
+ },
+ _setActiveColHeader: function(/*Node*/colHeaderNode, /*Integer*/colFocusIdx, /*Integer*/ prevColFocusIdx){
+ //console.log("setActiveColHeader() - colHeaderNode:colFocusIdx:prevColFocusIdx = " + colHeaderNode + ":" + colFocusIdx + ":" + prevColFocusIdx);
+ this.grid.domNode.setAttribute("aria-activedescendant",colHeaderNode.id);
+ if (prevColFocusIdx != null && prevColFocusIdx >= 0 && prevColFocusIdx != colFocusIdx){
+ html.toggleClass(this._findHeaderCells()[prevColFocusIdx],this.focusClass,false);
+ }
+ html.toggleClass(colHeaderNode,this.focusClass, true);
+ this._colHeadNode = colHeaderNode;
+ this._colHeadFocusIdx = colFocusIdx;
+ this._scrollHeader(this._colHeadFocusIdx);
+ },
+ scrollIntoView: function(){
+ var info = (this.cell ? this._scrollInfo(this.cell) : null);
+ if(!info || !info.s){
+ return null;
+ }
+ var rt = this.grid.scroller.findScrollTop(this.rowIndex);
+ // place cell within horizontal view
+ if(info.n && info.sr){
+ if(info.n.offsetLeft + info.n.offsetWidth > info.sr.l + info.sr.w){
+ info.s.scrollLeft = info.n.offsetLeft + info.n.offsetWidth - info.sr.w;
+ }else if(info.n.offsetLeft < info.sr.l){
+ info.s.scrollLeft = info.n.offsetLeft;
+ }
+ }
+ // place cell within vertical view
+ if(info.r && info.sr){
+ if(rt + info.r.offsetHeight > info.sr.t + info.sr.h){
+ this.grid.setScrollTop(rt + info.r.offsetHeight - info.sr.h);
+ }else if(rt < info.sr.t){
+ this.grid.setScrollTop(rt);
+ }
+ }
+
+ return info.s.scrollLeft;
+ },
+ _scrollInfo: function(cell, domNode){
+ if(cell){
+ var cl = cell,
+ sbn = cl.view.scrollboxNode,
+ sbnr = {
+ w: sbn.clientWidth,
+ l: sbn.scrollLeft,
+ t: sbn.scrollTop,
+ h: sbn.clientHeight
+ },
+ rn = cl.view.getRowNode(this.rowIndex);
+ return {
+ c: cl,
+ s: sbn,
+ sr: sbnr,
+ n: (domNode ? domNode : cell.getNode(this.rowIndex)),
+ r: rn
+ };
+ }
+ return null;
+ },
+ _scrollHeader: function(currentIdx){
+ var info = null;
+ if(this._colHeadNode){
+ var cell = this.grid.getCell(currentIdx);
+ if(!cell){ return; }
+ info = this._scrollInfo(cell, cell.getNode(0));
+ }
+ if(info && info.s && info.sr && info.n){
+ // scroll horizontally as needed.
+ var scroll = info.sr.l + info.sr.w;
+ if(info.n.offsetLeft + info.n.offsetWidth > scroll){
+ info.s.scrollLeft = info.n.offsetLeft + info.n.offsetWidth - info.sr.w;
+ }else if(info.n.offsetLeft < info.sr.l){
+ info.s.scrollLeft = info.n.offsetLeft;
+ }else if(has("ie") <= 7 && cell && cell.view.headerNode){
+ // Trac 7158: scroll dojoxGridHeader for IE7 and lower
+ cell.view.headerNode.scrollLeft = info.s.scrollLeft;
+ }
+ }
+ },
+ _isHeaderHidden: function(){
+ // summary:
+ // determine if the grid headers are hidden
+ // relies on documented technique of setting .dojoxGridHeader { display:none; }
+ // returns: Boolean
+ // true if headers are hidden
+ // false if headers are not hidden
+
+ var curView = this.focusView;
+ if (!curView){
+ // find one so we can determine if headers are hidden
+ // there is no focusView after adding items to empty grid (test_data_grid_empty.html)
+ for (var i = 0, cView; (cView = this.grid.views.views[i]); i++) {
+ if(cView.headerNode ){
+ curView=cView;
+ break;
+ }
+ }
+ }
+ return (curView && html.getComputedStyle(curView.headerNode).display == "none");
+ },
+ colSizeAdjust: function (e, colIdx, delta){ // adjust the column specified by colIdx by the specified delta px
+ var headers = this._findHeaderCells();
+ var view = this.focusView;
+ if (!view) {
+ for (var i = 0, cView; (cView = this.grid.views.views[i]); i++) {
+ // find first view with a tableMap in order to work with empty grid
+ if(cView.header.tableMap.map ){
+ view=cView;
+ break;
+ }
+ }
+ }
+ var curHeader = headers[colIdx];
+ if (!view || (colIdx == headers.length-1 && colIdx === 0)){
+ return; // can't adjust single col. grid
+ }
+ view.content.baseDecorateEvent(e);
+ // need to adjust event with header cell info since focus is no longer on header cell
+ e.cellNode = curHeader; //this.findCellTarget(e.target, e.rowNode);
+ e.cellIndex = view.content.getCellNodeIndex(e.cellNode);
+ e.cell = (e.cellIndex >= 0 ? this.grid.getCell(e.cellIndex) : null);
+ if (view.header.canResize(e)){
+ var deltaObj = {
+ l: delta
+ };
+ var drag = view.header.colResizeSetup(e,false);
+ view.header.doResizeColumn(drag, null, deltaObj);
+ view.update();
+ }
+ },
+ styleRow: function(inRow){
+ return;
+ },
+ setFocusIndex: function(inRowIndex, inCellIndex){
+ // summary:
+ // focuses the given grid cell
+ // inRowIndex: int
+ // grid row index
+ // inCellIndex: int
+ // grid cell index
+ this.setFocusCell(this.grid.getCell(inCellIndex), inRowIndex);
+ },
+ setFocusCell: function(inCell, inRowIndex){
+ // summary:
+ // focuses the given grid cell
+ // inCell: object
+ // grid cell object
+ // inRowIndex: int
+ // grid row index
+ if(inCell && !this.isFocusCell(inCell, inRowIndex)){
+ this.tabbingOut = false;
+ if (this._colHeadNode){
+ this.blurHeader();
+ }
+ this._colHeadNode = this._colHeadFocusIdx = null;
+ this.focusGridView();
+ this._focusifyCellNode(false);
+ this.cell = inCell;
+ this.rowIndex = inRowIndex;
+ this._focusifyCellNode(true);
+ }
+ // even if this cell isFocusCell, the document focus may need to be rejiggered
+ // call opera on delay to prevent keypress from altering focus
+ if(has("opera")){
+ setTimeout(lang.hitch(this.grid, 'onCellFocus', this.cell, this.rowIndex), 1);
+ }else{
+ this.grid.onCellFocus(this.cell, this.rowIndex);
+ }
+ },
+ next: function(){
+ // summary:
+ // focus next grid cell
+ if(this.cell){
+ var row=this.rowIndex, col=this.cell.index+1, cc=this.grid.layout.cellCount-1, rc=this.grid.rowCount-1;
+ if(col > cc){
+ col = 0;
+ row++;
+ }
+ if(row > rc){
+ col = cc;
+ row = rc;
+ }
+ if(this.grid.edit.isEditing()){ //when editing, only navigate to editable cells
+ var nextCell = this.grid.getCell(col);
+ if (!this.isLastFocusCell() && (!nextCell.editable ||
+ this.grid.canEdit && !this.grid.canEdit(nextCell, row))){
+ this.cell=nextCell;
+ this.rowIndex=row;
+ this.next();
+ return;
+ }
+ }
+ this.setFocusIndex(row, col);
+ }
+ },
+ previous: function(){
+ // summary:
+ // focus previous grid cell
+ if(this.cell){
+ var row=(this.rowIndex || 0), col=(this.cell.index || 0) - 1;
+ if(col < 0){
+ col = this.grid.layout.cellCount-1;
+ row--;
+ }
+ if(row < 0){
+ row = 0;
+ col = 0;
+ }
+ if(this.grid.edit.isEditing()){ //when editing, only navigate to editable cells
+ var prevCell = this.grid.getCell(col);
+ if (!this.isFirstFocusCell() && !prevCell.editable){
+ this.cell=prevCell;
+ this.rowIndex=row;
+ this.previous();
+ return;
+ }
+ }
+ this.setFocusIndex(row, col);
+ }
+ },
+ move: function(inRowDelta, inColDelta) {
+ // summary:
+ // focus grid cell or simulate focus to column header based on position relative to current focus
+ // inRowDelta: int
+ // vertical distance from current focus
+ // inColDelta: int
+ // horizontal distance from current focus
+
+ var colDir = inColDelta < 0 ? -1 : 1;
+ // Handle column headers.
+ if(this.isNavHeader()){
+ var headers = this._findHeaderCells();
+ var savedIdx = currentIdx = array.indexOf(headers, this._colHeadNode);
+ currentIdx += inColDelta;
+ while(currentIdx >=0 && currentIdx < headers.length && headers[currentIdx].style.display == "none"){
+ // skip over hidden column headers
+ currentIdx += colDir;
+ }
+ if((currentIdx >= 0) && (currentIdx < headers.length)){
+ this._setActiveColHeader(headers[currentIdx],currentIdx, savedIdx);
+ }
+ }else{
+ if(this.cell){
+ // Handle grid proper.
+ var sc = this.grid.scroller,
+ r = this.rowIndex,
+ rc = this.grid.rowCount-1,
+ row = Math.min(rc, Math.max(0, r+inRowDelta));
+ if(inRowDelta){
+ if(inRowDelta>0){
+ if(row > sc.getLastPageRow(sc.page)){
+ //need to load additional data, let scroller do that
+ this.grid.setScrollTop(this.grid.scrollTop+sc.findScrollTop(row)-sc.findScrollTop(r));
+ }
+ }else if(inRowDelta<0){
+ if(row <= sc.getPageRow(sc.page)){
+ //need to load additional data, let scroller do that
+ this.grid.setScrollTop(this.grid.scrollTop-sc.findScrollTop(r)-sc.findScrollTop(row));
+ }
+ }
+ }
+ var cc = this.grid.layout.cellCount-1,
+ i = this.cell.index,
+ col = Math.min(cc, Math.max(0, i+inColDelta));
+ var cell = this.grid.getCell(col);
+ while(col>=0 && col < cc && cell && cell.hidden === true){
+ // skip hidden cells
+ col += colDir;
+ cell = this.grid.getCell(col);
+ }
+ if (!cell || cell.hidden === true){
+ // don't change col if would move to hidden
+ col = i;
+ }
+ //skip hidden row|cell
+ var n = cell.getNode(row);
+ if(!n && inRowDelta){
+ if((row + inRowDelta) >= 0 && (row + inRowDelta) <= rc){
+ this.move(inRowDelta > 0 ? ++inRowDelta : --inRowDelta, inColDelta);
+ }
+ return;
+ }else if((!n || html.style(n, "display") === "none") && inColDelta){
+ if((col + inRowDelta) >= 0 && (col + inRowDelta) <= cc){
+ this.move(inRowDelta, inColDelta > 0 ? ++inColDelta : --inColDelta);
+ }
+ return;
+ }
+ this.setFocusIndex(row, col);
+ if(inRowDelta){
+ this.grid.updateRow(r);
+ }
+ }
+ }
+ },
+ previousKey: function(e){
+ if(this.grid.edit.isEditing()){
+ event.stop(e);
+ this.previous();
+ }else if(!this.isNavHeader() && !this._isHeaderHidden()) {
+ this.grid.domNode.focus(); // will call doFocus and set focus into header.
+ event.stop(e);
+ }else{
+ this.tabOut(this.grid.domNode);
+ if (this._colHeadFocusIdx != null) { // clear grid header focus
+ html.toggleClass(this._findHeaderCells()[this._colHeadFocusIdx], this.focusClass, false);
+ this._colHeadFocusIdx = null;
+ }
+ this._focusifyCellNode(false);
+ }
+ },
+ nextKey: function(e) {
+ var isEmpty = (this.grid.rowCount === 0);
+ if(e.target === this.grid.domNode && this._colHeadFocusIdx == null){
+ this.focusHeader();
+ event.stop(e);
+ }else if(this.isNavHeader()){
+ // if tabbing from col header, then go to grid proper.
+ this.blurHeader();
+ if(!this.findAndFocusGridCell()){
+ this.tabOut(this.grid.lastFocusNode);
+ }
+ this._colHeadNode = this._colHeadFocusIdx= null;
+ }else if(this.grid.edit.isEditing()){
+ event.stop(e);
+ this.next();
+ }else{
+ this.tabOut(this.grid.lastFocusNode);
+ }
+ },
+ tabOut: function(inFocusNode){
+ this.tabbingOut = true;
+ inFocusNode.focus();
+ },
+ focusGridView: function(){
+ util.fire(this.focusView, "focus");
+ },
+ focusGrid: function(inSkipFocusCell){
+ this.focusGridView();
+ this._focusifyCellNode(true);
+ },
+ findAndFocusGridCell: function(){
+ // summary:
+ // find the first focusable grid cell
+ // returns: Boolean
+ // true if focus was set to a cell
+ // false if no cell found to set focus onto
+
+ var didFocus = true;
+ var isEmpty = (this.grid.rowCount === 0); // If grid is empty this.grid.rowCount == 0
+ if (this.isNoFocusCell() && !isEmpty){
+ var cellIdx = 0;
+ var cell = this.grid.getCell(cellIdx);
+ if (cell.hidden) {
+ // if first cell isn't visible, use _colHeadFocusIdx
+ // could also use a while loop to find first visible cell - not sure that is worth it
+ cellIdx = this.isNavHeader() ? this._colHeadFocusIdx : 0;
+ }
+ this.setFocusIndex(0, cellIdx);
+ }
+ else if (this.cell && !isEmpty){
+ if (this.focusView && !this.focusView.rowNodes[this.rowIndex]){
+ // if rowNode for current index is undefined (likely as a result of a sort and because of #7304)
+ // scroll to that row
+ this.grid.scrollToRow(this.rowIndex);
+ }
+ this.focusGrid();
+ }else {
+ didFocus = false;
+ }
+ this._colHeadNode = this._colHeadFocusIdx= null;
+ return didFocus;
+ },
+ focusHeader: function(){
+ var headerNodes = this._findHeaderCells();
+ var saveColHeadFocusIdx = this._colHeadFocusIdx;
+ if (this._isHeaderHidden()){
+ // grid header is hidden, focus a cell
+ this.findAndFocusGridCell();
+ }
+ else if (!this._colHeadFocusIdx) {
+ if (this.isNoFocusCell()) {
+ this._colHeadFocusIdx = 0;
+ }
+ else {
+ this._colHeadFocusIdx = this.cell.index;
+ }
+ }
+ this._colHeadNode = headerNodes[this._colHeadFocusIdx];
+ while(this._colHeadNode && this._colHeadFocusIdx >=0 && this._colHeadFocusIdx < headerNodes.length &&
+ this._colHeadNode.style.display == "none"){
+ // skip over hidden column headers
+ this._colHeadFocusIdx++;
+ this._colHeadNode = headerNodes[this._colHeadFocusIdx];
+ }
+ if(this._colHeadNode && this._colHeadNode.style.display != "none"){
+ // Column header cells know longer receive actual focus. So, for keyboard invocation of
+ // contextMenu to work, the contextMenu must be bound to the grid.domNode rather than the viewsHeaderNode.
+ // unbind the contextmenu from the viewsHeaderNode and to the grid when header cells are active. Reset
+ // the binding back to the viewsHeaderNode when header cells are no longer acive (in blurHeader) #10483
+ if (this.headerMenu && this._contextMenuBindNode != this.grid.domNode){
+ this.headerMenu.unBindDomNode(this.grid.viewsHeaderNode);
+ this.headerMenu.bindDomNode(this.grid.domNode);
+ this._contextMenuBindNode = this.grid.domNode;
+ }
+ this._setActiveColHeader(this._colHeadNode, this._colHeadFocusIdx, saveColHeadFocusIdx);
+ this._scrollHeader(this._colHeadFocusIdx);
+ this._focusifyCellNode(false);
+ }else {
+ // all col head nodes are hidden - focus the grid
+ this.findAndFocusGridCell();
+ }
+ },
+ blurHeader: function(){
+ html.removeClass(this._colHeadNode, this.focusClass);
+ html.removeAttr(this.grid.domNode,"aria-activedescendant");
+ // reset contextMenu onto viewsHeaderNode so right mouse on header will invoke (see focusHeader)
+ if (this.headerMenu && this._contextMenuBindNode == this.grid.domNode) {
+ var viewsHeader = this.grid.viewsHeaderNode;
+ this.headerMenu.unBindDomNode(this.grid.domNode);
+ this.headerMenu.bindDomNode(viewsHeader);
+ this._contextMenuBindNode = viewsHeader;
+ }
+ },
+ doFocus: function(e){
+ // trap focus only for grid dom node
+ if(e && e.target != e.currentTarget){
+ event.stop(e);
+ return;
+ }
+ // don't change focus if clicking on scroller bar
+ if(this._clickFocus){
+ return;
+ }
+ // do not focus for scrolling if grid is about to blur
+ if(!this.tabbingOut){
+ this.focusHeader();
+ }
+ this.tabbingOut = false;
+ event.stop(e);
+ },
+ doBlur: function(e){
+ event.stop(e); // FF2
+ },
+ doContextMenu: function(e){
+ //stop contextMenu event if no header Menu to prevent default/browser contextMenu
+ if (!this.headerMenu){
+ event.stop(e);
+ }
+ },
+ doLastNodeFocus: function(e){
+ if (this.tabbingOut){
+ this._focusifyCellNode(false);
+ }else if(this.grid.rowCount >0){
+ if (this.isNoFocusCell()){
+ this.setFocusIndex(0,0);
+ }
+ this._focusifyCellNode(true);
+ }else {
+ this.focusHeader();
+ }
+ this.tabbingOut = false;
+ event.stop(e); // FF2
+ },
+ doLastNodeBlur: function(e){
+ event.stop(e); // FF2
+ },
+ doColHeaderFocus: function(e){
+ this._setActiveColHeader(e.target,html.attr(e.target, "idx"),this._colHeadFocusIdx);
+ this._scrollHeader(this.getHeaderIndex());
+ event.stop(e);
+ },
+ doColHeaderBlur: function(e){
+ html.toggleClass(e.target, this.focusClass, false);
+ },
+ _mouseDown: function(e){
+ // a flag indicating grid is being focused by clicking
+ this._clickFocus = dojo.some(this.grid.views.views, function(v){
+ return v.scrollboxNode === e.target;
+ });
+ },
+ _mouseUp: function(e){
+ this._clickFocus = false;
+ }
+});
+}); \ No newline at end of file
diff --git a/js/dojo-1.7.2/dojox/grid/_Grid.js b/js/dojo-1.7.2/dojox/grid/_Grid.js
new file mode 100644
index 0000000..8c677b5
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/_Grid.js
@@ -0,0 +1,1402 @@
+//>>built
+require({cache:{
+'url:dojox/grid/resources/_Grid.html':"<div hidefocus=\"hidefocus\" role=\"grid\" dojoAttachEvent=\"onmouseout:_mouseOut\">\n\t<div class=\"dojoxGridMasterHeader\" dojoAttachPoint=\"viewsHeaderNode\" role=\"presentation\"></div>\n\t<div class=\"dojoxGridMasterView\" dojoAttachPoint=\"viewsNode\" role=\"presentation\"></div>\n\t<div class=\"dojoxGridMasterMessages\" style=\"display: none;\" dojoAttachPoint=\"messagesNode\"></div>\n\t<span dojoAttachPoint=\"lastFocusNode\" tabindex=\"0\"></span>\n</div>\n"}});
+define("dojox/grid/_Grid", [
+ "dojo/_base/kernel",
+ "../main",
+ "dojo/_base/declare",
+ "./_Events",
+ "./_Scroller",
+ "./_Layout",
+ "./_View",
+ "./_ViewManager",
+ "./_RowManager",
+ "./_FocusManager",
+ "./_EditManager",
+ "./Selection",
+ "./_RowSelector",
+ "./util",
+ "dijit/_Widget",
+ "dijit/_TemplatedMixin",
+ "dijit/CheckedMenuItem",
+ "dojo/text!./resources/_Grid.html",
+ "dojo/string",
+ "dojo/_base/array",
+ "dojo/_base/lang",
+ "dojo/_base/sniff",
+ "dojox/html/metrics",
+ "dojo/_base/html",
+ "dojo/query",
+ "dojo/dnd/common",
+ "dojo/i18n!dijit/nls/loading"
+], function(dojo, dojox, declare, _Events, _Scroller, _Layout, _View, _ViewManager,
+ _RowManager, _FocusManager, _EditManager, Selection, _RowSelector, util, _Widget,
+ _TemplatedMixin, CheckedMenuItem, template, string, array, lang, has, metrics, html, query){
+
+ // NOTE: this is for backwards compatibility with Dojo 1.3
+ if(!dojo.isCopyKey){
+ dojo.isCopyKey = dojo.dnd.getCopyKeyState;
+ }
+ /*=====
+ dojox.grid.__CellDef = function(){
+ // name: String?
+ // The text to use in the header of the grid for this cell.
+ // get: Function?
+ // function(rowIndex){} rowIndex is of type Integer. This
+ // function will be called when a cell requests data. Returns the
+ // unformatted data for the cell.
+ // value: String?
+ // If "get" is not specified, this is used as the data for the cell.
+ // defaultValue: String?
+ // If "get" and "value" aren't specified or if "get" returns an undefined
+ // value, this is used as the data for the cell. "formatter" is not run
+ // on this if "get" returns an undefined value.
+ // formatter: Function?
+ // function(data, rowIndex){} data is of type anything, rowIndex
+ // is of type Integer. This function will be called after the cell
+ // has its data but before it passes it back to the grid to render.
+ // Returns the formatted version of the cell's data.
+ // type: dojox.grid.cells._Base|Function?
+ // TODO
+ // editable: Boolean?
+ // Whether this cell should be editable or not.
+ // hidden: Boolean?
+ // If true, the cell will not be displayed.
+ // noresize: Boolean?
+ // If true, the cell will not be able to be resized.
+ // width: Integer|String?
+ // A CSS size. If it's an Integer, the width will be in em's.
+ // colSpan: Integer?
+ // How many columns to span this cell. Will not work in the first
+ // sub-row of cells.
+ // rowSpan: Integer?
+ // How many sub-rows to span this cell.
+ // styles: String?
+ // A string of styles to apply to both the header cell and main
+ // grid cells. Must end in a ';'.
+ // headerStyles: String?
+ // A string of styles to apply to just the header cell. Must end
+ // in a ';'
+ // cellStyles: String?
+ // A string of styles to apply to just the main grid cells. Must
+ // end in a ';'
+ // classes: String?
+ // A space separated list of classes to apply to both the header
+ // cell and the main grid cells.
+ // headerClasses: String?
+ // A space separated list of classes to apply to just the header
+ // cell.
+ // cellClasses: String?
+ // A space separated list of classes to apply to just the main
+ // grid cells.
+ // attrs: String?
+ // A space separated string of attribute='value' pairs to add to
+ // the header cell element and main grid cell elements.
+ this.name = name;
+ this.value = value;
+ this.get = get;
+ this.formatter = formatter;
+ this.type = type;
+ this.editable = editable;
+ this.hidden = hidden;
+ this.width = width;
+ this.colSpan = colSpan;
+ this.rowSpan = rowSpan;
+ this.styles = styles;
+ this.headerStyles = headerStyles;
+ this.cellStyles = cellStyles;
+ this.classes = classes;
+ this.headerClasses = headerClasses;
+ this.cellClasses = cellClasses;
+ this.attrs = attrs;
+ }
+ =====*/
+
+ /*=====
+ dojox.grid.__ViewDef = function(){
+ // noscroll: Boolean?
+ // If true, no scrollbars will be rendered without scrollbars.
+ // width: Integer|String?
+ // A CSS size. If it's an Integer, the width will be in em's. If
+ // "noscroll" is true, this value is ignored.
+ // cells: dojox.grid.__CellDef[]|Array[dojox.grid.__CellDef[]]?
+ // The structure of the cells within this grid.
+ // type: String?
+ // A string containing the constructor of a subclass of
+ // dojox.grid._View. If this is not specified, dojox.grid._View
+ // is used.
+ // defaultCell: dojox.grid.__CellDef?
+ // A cell definition with default values for all cells in this view. If
+ // a property is defined in a cell definition in the "cells" array and
+ // this property, the cell definition's property will override this
+ // property's property.
+ // onBeforeRow: Function?
+ // function(rowIndex, cells){} rowIndex is of type Integer, cells
+ // is of type Array[dojox.grid.__CellDef[]]. This function is called
+ // before each row of data is rendered. Before the header is
+ // rendered, rowIndex will be -1. "cells" is a reference to the
+ // internal structure of this view's cells so any changes you make to
+ // it will persist between calls.
+ // onAfterRow: Function?
+ // function(rowIndex, cells, rowNode){} rowIndex is of type Integer, cells
+ // is of type Array[dojox.grid.__CellDef[]], rowNode is of type DOMNode.
+ // This function is called after each row of data is rendered. After the
+ // header is rendered, rowIndex will be -1. "cells" is a reference to the
+ // internal structure of this view's cells so any changes you make to
+ // it will persist between calls.
+ this.noscroll = noscroll;
+ this.width = width;
+ this.cells = cells;
+ this.type = type;
+ this.defaultCell = defaultCell;
+ this.onBeforeRow = onBeforeRow;
+ this.onAfterRow = onAfterRow;
+ }
+ =====*/
+
+ var _Grid = declare('dojox.grid._Grid',
+ [ _Widget, _TemplatedMixin, _Events ],
+ {
+ // summary:
+ // A grid widget with virtual scrolling, cell editing, complex rows,
+ // sorting, fixed columns, sizeable columns, etc.
+ //
+ // description:
+ // _Grid provides the full set of grid features without any
+ // direct connection to a data store.
+ //
+ // The grid exposes a get function for the grid, or optionally
+ // individual columns, to populate cell contents.
+ //
+ // The grid is rendered based on its structure, an object describing
+ // column and cell layout.
+ //
+ // example:
+ // A quick sample:
+ //
+ // define a get function
+ // | function get(inRowIndex){ // called in cell context
+ // | return [this.index, inRowIndex].join(', ');
+ // | }
+ //
+ // define the grid structure:
+ // | var structure = [ // array of view objects
+ // | { cells: [// array of rows, a row is an array of cells
+ // | [
+ // | { name: "Alpha", width: 6 },
+ // | { name: "Beta" },
+ // | { name: "Gamma", get: get }]
+ // | ]}
+ // | ];
+ //
+ // | <div id="grid"
+ // | rowCount="100" get="get"
+ // | structure="structure"
+ // | dojoType="dojox.grid._Grid"></div>
+
+ templateString: template,
+
+ // classTag: String
+ // CSS class applied to the grid's domNode
+ classTag: 'dojoxGrid',
+
+ // settings
+ // rowCount: Integer
+ // Number of rows to display.
+ rowCount: 5,
+
+ // keepRows: Integer
+ // Number of rows to keep in the rendering cache.
+ keepRows: 75,
+
+ // rowsPerPage: Integer
+ // Number of rows to render at a time.
+ rowsPerPage: 25,
+
+ // autoWidth: Boolean
+ // If autoWidth is true, grid width is automatically set to fit the data.
+ autoWidth: false,
+
+ // initialWidth: String
+ // A css string to use to set our initial width (only used if autoWidth
+ // is true). The first rendering of the grid will be this width, any
+ // resizing of columns, etc will result in the grid switching to
+ // autoWidth mode. Note, this width will override any styling in a
+ // stylesheet or directly on the node.
+ initialWidth: "",
+
+ // autoHeight: Boolean|Integer
+ // If autoHeight is true, grid height is automatically set to fit the data.
+ // If it is an integer, the height will be automatically set to fit the data
+ // if there are fewer than that many rows - and the height will be set to show
+ // that many rows if there are more
+ autoHeight: '',
+
+ // rowHeight: Integer
+ // If rowHeight is set to a positive number, it will define the height of the rows
+ // in pixels. This can provide a significant performance advantage, since it
+ // eliminates the need to measure row sizes during rendering, which is one
+ // the primary bottlenecks in the DataGrid's performance.
+ rowHeight: 0,
+
+ // autoRender: Boolean
+ // If autoRender is true, grid will render itself after initialization.
+ autoRender: true,
+
+ // defaultHeight: String
+ // default height of the grid, measured in any valid css unit.
+ defaultHeight: '15em',
+
+ // height: String
+ // explicit height of the grid, measured in any valid css unit. This will be populated (and overridden)
+ // if the height: css attribute exists on the source node.
+ height: '',
+
+ // structure: dojox.grid.__ViewDef|dojox.grid.__ViewDef[]|dojox.grid.__CellDef[]|Array[dojox.grid.__CellDef[]]
+ // View layout defintion.
+ structure: null,
+
+ // elasticView: Integer
+ // Override defaults and make the indexed grid view elastic, thus filling available horizontal space.
+ elasticView: -1,
+
+ // singleClickEdit: boolean
+ // Single-click starts editing. Default is double-click
+ singleClickEdit: false,
+
+ // selectionMode: String
+ // Set the selection mode of grid's Selection. Value must be 'single', 'multiple',
+ // or 'extended'. Default is 'extended'.
+ selectionMode: 'extended',
+
+ // rowSelector: Boolean|String
+ // If set to true, will add a row selector view to this grid. If set to a CSS width, will add
+ // a row selector of that width to this grid.
+ rowSelector: '',
+
+ // columnReordering: Boolean
+ // If set to true, will add drag and drop reordering to views with one row of columns.
+ columnReordering: false,
+
+ // headerMenu: dijit.Menu
+ // If set to a dijit.Menu, will use this as a context menu for the grid headers.
+ headerMenu: null,
+
+ // placeholderLabel: String
+ // Label of placeholders to search for in the header menu to replace with column toggling
+ // menu items.
+ placeholderLabel: "GridColumns",
+
+ // selectable: Boolean
+ // Set to true if you want to be able to select the text within the grid.
+ selectable: false,
+
+ // Used to store the last two clicks, to ensure double-clicking occurs based on the intended row
+ _click: null,
+
+ // loadingMessage: String
+ // Message that shows while the grid is loading
+ loadingMessage: "<span class='dojoxGridLoading'>${loadingState}</span>",
+
+ // errorMessage: String
+ // Message that shows when the grid encounters an error loading
+ errorMessage: "<span class='dojoxGridError'>${errorState}</span>",
+
+ // noDataMessage: String
+ // Message that shows if the grid has no data - wrap it in a
+ // span with class 'dojoxGridNoData' if you want it to be
+ // styled similar to the loading and error messages
+ noDataMessage: "",
+
+ // escapeHTMLInData: Boolean
+ // This will escape HTML brackets from the data to prevent HTML from
+ // user-inputted data being rendered with may contain JavaScript and result in
+ // XSS attacks. This is true by default, and it is recommended that it remain
+ // true. Setting this to false will allow data to be displayed in the grid without
+ // filtering, and should be only used if it is known that the data won't contain
+ // malicious scripts. If HTML is needed in grid cells, it is recommended that
+ // you use the formatter function to generate the HTML (the output of
+ // formatter functions is not filtered, even with escapeHTMLInData set to true).
+ escapeHTMLInData: true,
+
+ // formatterScope: Object
+ // An object to execute format functions within. If not set, the
+ // format functions will execute within the scope of the cell that
+ // has a format function.
+ formatterScope: null,
+
+ // editable: boolean
+ // indicates if the grid contains editable cells, default is false
+ // set to true if editable cell encountered during rendering
+ editable: false,
+
+ // private
+ sortInfo: 0,
+ themeable: true,
+ _placeholders: null,
+
+ // _layoutClass: Object
+ // The class to use for our layout - can be overridden by grid subclasses
+ _layoutClass: _Layout,
+
+ // initialization
+ buildRendering: function(){
+ this.inherited(arguments);
+ if(!this.domNode.getAttribute('tabIndex')){
+ this.domNode.tabIndex = "0";
+ }
+ this.createScroller();
+ this.createLayout();
+ this.createViews();
+ this.createManagers();
+
+ this.createSelection();
+
+ this.connect(this.selection, "onSelected", "onSelected");
+ this.connect(this.selection, "onDeselected", "onDeselected");
+ this.connect(this.selection, "onChanged", "onSelectionChanged");
+
+ metrics.initOnFontResize();
+ this.connect(metrics, "onFontResize", "textSizeChanged");
+ util.funnelEvents(this.domNode, this, 'doKeyEvent', util.keyEvents);
+ if (this.selectionMode != "none") {
+ this.domNode.setAttribute("aria-multiselectable", this.selectionMode == "single" ? "false" : "true");
+ }
+
+ html.addClass(this.domNode, this.classTag);
+ if(!this.isLeftToRight()){
+ html.addClass(this.domNode, this.classTag+"Rtl");
+ }
+ },
+
+ postMixInProperties: function(){
+ this.inherited(arguments);
+ var messages = dojo.i18n.getLocalization("dijit", "loading", this.lang);
+ this.loadingMessage = string.substitute(this.loadingMessage, messages);
+ this.errorMessage = string.substitute(this.errorMessage, messages);
+ if(this.srcNodeRef && this.srcNodeRef.style.height){
+ this.height = this.srcNodeRef.style.height;
+ }
+ // Call this to update our autoheight to start out
+ this._setAutoHeightAttr(this.autoHeight, true);
+ this.lastScrollTop = this.scrollTop = 0;
+ },
+
+ postCreate: function(){
+ this._placeholders = [];
+ this._setHeaderMenuAttr(this.headerMenu);
+ this._setStructureAttr(this.structure);
+ this._click = [];
+ this.inherited(arguments);
+ if(this.domNode && this.autoWidth && this.initialWidth){
+ this.domNode.style.width = this.initialWidth;
+ }
+ if (this.domNode && !this.editable){
+ // default value for aria-readonly is false, set to true if grid is not editable
+ html.attr(this.domNode,"aria-readonly", "true");
+ }
+ },
+
+ destroy: function(){
+ this.domNode.onReveal = null;
+ this.domNode.onSizeChange = null;
+
+ // Fixes IE domNode leak
+ delete this._click;
+
+ if(this.scroller){
+ this.scroller.destroy();
+ delete this.scroller;
+ }
+ this.edit.destroy();
+ delete this.edit;
+ this.views.destroyViews();
+ if(this.focus){
+ this.focus.destroy();
+ delete this.focus;
+ }
+ if(this.headerMenu&&this._placeholders.length){
+ array.forEach(this._placeholders, function(p){ p.unReplace(true); });
+ this.headerMenu.unBindDomNode(this.viewsHeaderNode);
+ }
+ this.inherited(arguments);
+ },
+
+ _setAutoHeightAttr: function(ah, skipRender){
+ // Calculate our autoheight - turn it into a boolean or an integer
+ if(typeof ah == "string"){
+ if(!ah || ah == "false"){
+ ah = false;
+ }else if (ah == "true"){
+ ah = true;
+ }else{
+ ah = window.parseInt(ah, 10);
+ }
+ }
+ if(typeof ah == "number"){
+ if(isNaN(ah)){
+ ah = false;
+ }
+ // Autoheight must be at least 1, if it's a number. If it's
+ // less than 0, we'll take that to mean "all" rows (same as
+ // autoHeight=true - if it is equal to zero, we'll take that
+ // to mean autoHeight=false
+ if(ah < 0){
+ ah = true;
+ }else if (ah === 0){
+ ah = false;
+ }
+ }
+ this.autoHeight = ah;
+ if(typeof ah == "boolean"){
+ this._autoHeight = ah;
+ }else if(typeof ah == "number"){
+ this._autoHeight = (ah >= this.get('rowCount'));
+ }else{
+ this._autoHeight = false;
+ }
+ if(this._started && !skipRender){
+ this.render();
+ }
+ },
+
+ _getRowCountAttr: function(){
+ return this.updating && this.invalidated && this.invalidated.rowCount != undefined ?
+ this.invalidated.rowCount : this.rowCount;
+ },
+
+ textSizeChanged: function(){
+ this.render();
+ },
+
+ sizeChange: function(){
+ this.update();
+ },
+
+ createManagers: function(){
+ // summary:
+ // create grid managers for various tasks including rows, focus, selection, editing
+
+ // row manager
+ this.rows = new _RowManager(this);
+ // focus manager
+ this.focus = new _FocusManager(this);
+ // edit manager
+ this.edit = new _EditManager(this);
+ },
+
+ createSelection: function(){
+ // summary: Creates a new Grid selection manager.
+
+ // selection manager
+ this.selection = new Selection(this);
+ },
+
+ createScroller: function(){
+ // summary: Creates a new virtual scroller
+ this.scroller = new _Scroller();
+ this.scroller.grid = this;
+ this.scroller.renderRow = lang.hitch(this, "renderRow");
+ this.scroller.removeRow = lang.hitch(this, "rowRemoved");
+ },
+
+ createLayout: function(){
+ // summary: Creates a new Grid layout
+ this.layout = new this._layoutClass(this);
+ this.connect(this.layout, "moveColumn", "onMoveColumn");
+ },
+
+ onMoveColumn: function(){
+ this.render();
+ },
+
+ onResizeColumn: function(/*int*/ cellIdx){
+ // Called when a column is resized.
+ },
+
+ // views
+ createViews: function(){
+ this.views = new _ViewManager(this);
+ this.views.createView = lang.hitch(this, "createView");
+ },
+
+ createView: function(inClass, idx){
+ var c = lang.getObject(inClass);
+ var view = new c({ grid: this, index: idx });
+ this.viewsNode.appendChild(view.domNode);
+ this.viewsHeaderNode.appendChild(view.headerNode);
+ this.views.addView(view);
+ html.attr(this.domNode, "align", this.isLeftToRight() ? 'left' : 'right');
+ return view;
+ },
+
+ buildViews: function(){
+ for(var i=0, vs; (vs=this.layout.structure[i]); i++){
+ this.createView(vs.type || dojox._scopeName + ".grid._View", i).setStructure(vs);
+ }
+ this.scroller.setContentNodes(this.views.getContentNodes());
+ },
+
+ _setStructureAttr: function(structure){
+ var s = structure;
+ if(s && lang.isString(s)){
+ dojo.deprecated("dojox.grid._Grid.set('structure', 'objVar')", "use dojox.grid._Grid.set('structure', objVar) instead", "2.0");
+ s=lang.getObject(s);
+ }
+ this.structure = s;
+ if(!s){
+ if(this.layout.structure){
+ s = this.layout.structure;
+ }else{
+ return;
+ }
+ }
+ this.views.destroyViews();
+ this.focus.focusView = null;
+ if(s !== this.layout.structure){
+ this.layout.setStructure(s);
+ }
+ this._structureChanged();
+ },
+
+ setStructure: function(/* dojox.grid.__ViewDef|dojox.grid.__ViewDef[]|dojox.grid.__CellDef[]|Array[dojox.grid.__CellDef[]] */ inStructure){
+ // summary:
+ // Install a new structure and rebuild the grid.
+ dojo.deprecated("dojox.grid._Grid.setStructure(obj)", "use dojox.grid._Grid.set('structure', obj) instead.", "2.0");
+ this._setStructureAttr(inStructure);
+ },
+
+ getColumnTogglingItems: function(){
+ // Summary: returns an array of dijit.CheckedMenuItem widgets that can be
+ // added to a menu for toggling columns on and off.
+ var items, checkedItems = [];
+ items = array.map(this.layout.cells, function(cell){
+ if(!cell.menuItems){ cell.menuItems = []; }
+
+ var self = this;
+ var item = new CheckedMenuItem({
+ label: cell.name,
+ checked: !cell.hidden,
+ _gridCell: cell,
+ onChange: function(checked){
+ if(self.layout.setColumnVisibility(this._gridCell.index, checked)){
+ var items = this._gridCell.menuItems;
+ if(items.length > 1){
+ array.forEach(items, function(item){
+ if(item !== this){
+ item.setAttribute("checked", checked);
+ }
+ }, this);
+ }
+ checked = array.filter(self.layout.cells, function(c){
+ if(c.menuItems.length > 1){
+ array.forEach(c.menuItems, "item.set('disabled', false);");
+ }else{
+ c.menuItems[0].set('disabled', false);
+ }
+ return !c.hidden;
+ });
+ if(checked.length == 1){
+ array.forEach(checked[0].menuItems, "item.set('disabled', true);");
+ }
+ }
+ },
+ destroy: function(){
+ var index = array.indexOf(this._gridCell.menuItems, this);
+ this._gridCell.menuItems.splice(index, 1);
+ delete this._gridCell;
+ CheckedMenuItem.prototype.destroy.apply(this, arguments);
+ }
+ });
+ cell.menuItems.push(item);
+ if(!cell.hidden) {
+ checkedItems.push(item);
+ }
+ return item;
+ }, this); // dijit.CheckedMenuItem[]
+ if(checkedItems.length == 1) {
+ checkedItems[0].set('disabled', true);
+ }
+ return items;
+ },
+
+ _setHeaderMenuAttr: function(menu){
+ if(this._placeholders && this._placeholders.length){
+ array.forEach(this._placeholders, function(p){
+ p.unReplace(true);
+ });
+ this._placeholders = [];
+ }
+ if(this.headerMenu){
+ this.headerMenu.unBindDomNode(this.viewsHeaderNode);
+ }
+ this.headerMenu = menu;
+ if(!menu){ return; }
+
+ this.headerMenu.bindDomNode(this.viewsHeaderNode);
+ if(this.headerMenu.getPlaceholders){
+ this._placeholders = this.headerMenu.getPlaceholders(this.placeholderLabel);
+ }
+ },
+
+ setHeaderMenu: function(/* dijit.Menu */ menu){
+ dojo.deprecated("dojox.grid._Grid.setHeaderMenu(obj)", "use dojox.grid._Grid.set('headerMenu', obj) instead.", "2.0");
+ this._setHeaderMenuAttr(menu);
+ },
+
+ setupHeaderMenu: function(){
+ if(this._placeholders && this._placeholders.length){
+ array.forEach(this._placeholders, function(p){
+ if(p._replaced){
+ p.unReplace(true);
+ }
+ p.replace(this.getColumnTogglingItems());
+ }, this);
+ }
+ },
+
+ _fetch: function(start){
+ this.setScrollTop(0);
+ },
+
+ getItem: function(inRowIndex){
+ return null;
+ },
+
+ showMessage: function(message){
+ if(message){
+ this.messagesNode.innerHTML = message;
+ this.messagesNode.style.display = "";
+ }else{
+ this.messagesNode.innerHTML = "";
+ this.messagesNode.style.display = "none";
+ }
+ },
+
+ _structureChanged: function() {
+ this.buildViews();
+ if(this.autoRender && this._started){
+ this.render();
+ }
+ },
+
+ hasLayout: function() {
+ return this.layout.cells.length;
+ },
+
+ // sizing
+ resize: function(changeSize, resultSize){
+ // summary:
+ // Update the grid's rendering dimensions and resize it
+
+ // Calling sizeChange calls update() which calls _resize...so let's
+ // save our input values, if any, and use them there when it gets
+ // called. This saves us an extra call to _resize(), which can
+ // get kind of heavy.
+
+ // fixes #11101, should ignore resize when in autoheight mode(IE) to avoid a deadlock
+ // e.g when an autoheight editable grid put in dijit.form.Form or other similar containers,
+ // grid switch to editing mode --> grid height change --> From height change
+ // ---> Form call grid.resize() ---> grid height change --> deaklock
+ if(dojo.isIE && !changeSize && !resultSize && this._autoHeight){
+ return;
+ }
+ this._pendingChangeSize = changeSize;
+ this._pendingResultSize = resultSize;
+ this.sizeChange();
+ },
+
+ _getPadBorder: function() {
+ this._padBorder = this._padBorder || html._getPadBorderExtents(this.domNode);
+ return this._padBorder;
+ },
+
+ _getHeaderHeight: function(){
+ var vns = this.viewsHeaderNode.style, t = vns.display == "none" ? 0 : this.views.measureHeader();
+ vns.height = t + 'px';
+ // header heights are reset during measuring so must be normalized after measuring.
+ this.views.normalizeHeaderNodeHeight();
+ return t;
+ },
+
+ _resize: function(changeSize, resultSize){
+ // Restore our pending values, if any
+ changeSize = changeSize || this._pendingChangeSize;
+ resultSize = resultSize || this._pendingResultSize;
+ delete this._pendingChangeSize;
+ delete this._pendingResultSize;
+ // if we have set up everything except the DOM, we cannot resize
+ if(!this.domNode){ return; }
+ var pn = this.domNode.parentNode;
+ if(!pn || pn.nodeType != 1 || !this.hasLayout() || pn.style.visibility == "hidden" || pn.style.display == "none"){
+ return;
+ }
+ // useful measurement
+ var padBorder = this._getPadBorder();
+ var hh = undefined;
+ var h;
+ // grid height
+ if(this._autoHeight){
+ this.domNode.style.height = 'auto';
+ }else if(typeof this.autoHeight == "number"){
+ h = hh = this._getHeaderHeight();
+ h += (this.scroller.averageRowHeight * this.autoHeight);
+ this.domNode.style.height = h + "px";
+ }else if(this.domNode.clientHeight <= padBorder.h){
+ if(pn == document.body){
+ this.domNode.style.height = this.defaultHeight;
+ }else if(this.height){
+ this.domNode.style.height = this.height;
+ }else{
+ this.fitTo = "parent";
+ }
+ }
+ // if we are given dimensions, size the grid's domNode to those dimensions
+ if(resultSize){
+ changeSize = resultSize;
+ }
+ if(!this._autoHeight && changeSize){
+ html.marginBox(this.domNode, changeSize);
+ this.height = this.domNode.style.height;
+ delete this.fitTo;
+ }else if(this.fitTo == "parent"){
+ h = this._parentContentBoxHeight = this._parentContentBoxHeight || html._getContentBox(pn).h;
+ this.domNode.style.height = Math.max(0, h) + "px";
+ }
+
+ var hasFlex = array.some(this.views.views, function(v){ return v.flexCells; });
+
+ if(!this._autoHeight && (h || html._getContentBox(this.domNode).h) === 0){
+ // We need to hide the header, since the Grid is essentially hidden.
+ this.viewsHeaderNode.style.display = "none";
+ }else{
+ // Otherwise, show the header and give it an appropriate height.
+ this.viewsHeaderNode.style.display = "block";
+ if(!hasFlex && hh === undefined){
+ hh = this._getHeaderHeight();
+ }
+ }
+ if(hasFlex){
+ hh = undefined;
+ }
+
+ // NOTE: it is essential that width be applied before height
+ // Header height can only be calculated properly after view widths have been set.
+ // This is because flex column width is naturally 0 in Firefox.
+ // Therefore prior to width sizing flex columns with spaces are maximally wrapped
+ // and calculated to be too tall.
+ this.adaptWidth();
+ this.adaptHeight(hh);
+
+ this.postresize();
+ },
+
+ adaptWidth: function() {
+ // private: sets width and position for views and update grid width if necessary
+ var doAutoWidth = (!this.initialWidth && this.autoWidth);
+ var w = doAutoWidth ? 0 : this.domNode.clientWidth || (this.domNode.offsetWidth - this._getPadBorder().w),
+ vw = this.views.arrange(1, w);
+ this.views.onEach("adaptWidth");
+ if(doAutoWidth){
+ this.domNode.style.width = vw + "px";
+ }
+ },
+
+ adaptHeight: function(inHeaderHeight){
+ // private: measures and normalizes header height, then sets view heights, and then updates scroller
+ // content extent
+ var t = inHeaderHeight === undefined ? this._getHeaderHeight() : inHeaderHeight;
+ var h = (this._autoHeight ? -1 : Math.max(this.domNode.clientHeight - t, 0) || 0);
+ this.views.onEach('setSize', [0, h]);
+ this.views.onEach('adaptHeight');
+ if(!this._autoHeight){
+ var numScroll = 0, numNoScroll = 0;
+ var noScrolls = array.filter(this.views.views, function(v){
+ var has = v.hasHScrollbar();
+ if(has){ numScroll++; }else{ numNoScroll++; }
+ return (!has);
+ });
+ if(numScroll > 0 && numNoScroll > 0){
+ array.forEach(noScrolls, function(v){
+ v.adaptHeight(true);
+ });
+ }
+ }
+ if(this.autoHeight === true || h != -1 || (typeof this.autoHeight == "number" && this.autoHeight >= this.get('rowCount'))){
+ this.scroller.windowHeight = h;
+ }else{
+ this.scroller.windowHeight = Math.max(this.domNode.clientHeight - t, 0);
+ }
+ },
+
+ // startup
+ startup: function(){
+ if(this._started){return;}
+ this.inherited(arguments);
+ if(this.autoRender){
+ this.render();
+ }
+ },
+
+ // render
+ render: function(){
+ // summary:
+ // Render the grid, headers, and views. Edit and scrolling states are reset. To retain edit and
+ // scrolling states, see Update.
+
+ if(!this.domNode){return;}
+ if(!this._started){return;}
+
+ if(!this.hasLayout()) {
+ this.scroller.init(0, this.keepRows, this.rowsPerPage);
+ return;
+ }
+ //
+ this.update = this.defaultUpdate;
+ this._render();
+ },
+
+ _render: function(){
+ this.scroller.init(this.get('rowCount'), this.keepRows, this.rowsPerPage);
+ this.prerender();
+ this.setScrollTop(0);
+ this.postrender();
+ },
+
+ prerender: function(){
+ // if autoHeight, make sure scroller knows not to virtualize; everything must be rendered.
+ this.keepRows = this._autoHeight ? 0 : this.keepRows;
+ this.scroller.setKeepInfo(this.keepRows);
+ this.views.render();
+ this._resize();
+ },
+
+ postrender: function(){
+ this.postresize();
+ this.focus.initFocusView();
+ // make rows unselectable
+ html.setSelectable(this.domNode, this.selectable);
+ },
+
+ postresize: function(){
+ // views are position absolute, so they do not inflate the parent
+ if(this._autoHeight){
+ var size = Math.max(this.views.measureContent()) + 'px';
+
+ this.viewsNode.style.height = size;
+ }
+ },
+
+ renderRow: function(inRowIndex, inNodes){
+ // summary: private, used internally to render rows
+ this.views.renderRow(inRowIndex, inNodes, this._skipRowRenormalize);
+ },
+
+ rowRemoved: function(inRowIndex){
+ // summary: private, used internally to remove rows
+ this.views.rowRemoved(inRowIndex);
+ },
+
+ invalidated: null,
+
+ updating: false,
+
+ beginUpdate: function(){
+ // summary:
+ // Use to make multiple changes to rows while queueing row updating.
+ // NOTE: not currently supporting nested begin/endUpdate calls
+ this.invalidated = [];
+ this.updating = true;
+ },
+
+ endUpdate: function(){
+ // summary:
+ // Use after calling beginUpdate to render any changes made to rows.
+ this.updating = false;
+ var i = this.invalidated, r;
+ if(i.all){
+ this.update();
+ }else if(i.rowCount != undefined){
+ this.updateRowCount(i.rowCount);
+ }else{
+ for(r in i){
+ this.updateRow(Number(r));
+ }
+ }
+ this.invalidated = [];
+ },
+
+ // update
+ defaultUpdate: function(){
+ // note: initial update calls render and subsequently this function.
+ if(!this.domNode){return;}
+ if(this.updating){
+ this.invalidated.all = true;
+ return;
+ }
+ //this.edit.saveState(inRowIndex);
+ this.lastScrollTop = this.scrollTop;
+ this.prerender();
+ this.scroller.invalidateNodes();
+ this.setScrollTop(this.lastScrollTop);
+ this.postrender();
+ //this.edit.restoreState(inRowIndex);
+ },
+
+ update: function(){
+ // summary:
+ // Update the grid, retaining edit and scrolling states.
+ this.render();
+ },
+
+ updateRow: function(inRowIndex){
+ // summary:
+ // Render a single row.
+ // inRowIndex: Integer
+ // Index of the row to render
+ inRowIndex = Number(inRowIndex);
+ if(this.updating){
+ this.invalidated[inRowIndex]=true;
+ }else{
+ this.views.updateRow(inRowIndex);
+ this.scroller.rowHeightChanged(inRowIndex);
+ }
+ },
+
+ updateRows: function(startIndex, howMany){
+ // summary:
+ // Render consecutive rows at once.
+ // startIndex: Integer
+ // Index of the starting row to render
+ // howMany: Integer
+ // How many rows to update.
+ startIndex = Number(startIndex);
+ howMany = Number(howMany);
+ var i;
+ if(this.updating){
+ for(i=0; i<howMany; i++){
+ this.invalidated[i+startIndex]=true;
+ }
+ }else{
+ for(i=0; i<howMany; i++){
+ this.views.updateRow(i+startIndex, this._skipRowRenormalize);
+ }
+ this.scroller.rowHeightChanged(startIndex);
+ }
+ },
+
+ updateRowCount: function(inRowCount){
+ //summary:
+ // Change the number of rows.
+ // inRowCount: int
+ // Number of rows in the grid.
+ if(this.updating){
+ this.invalidated.rowCount = inRowCount;
+ }else{
+ this.rowCount = inRowCount;
+ this._setAutoHeightAttr(this.autoHeight, true);
+ if(this.layout.cells.length){
+ this.scroller.updateRowCount(inRowCount);
+ }
+ this._resize();
+ if(this.layout.cells.length){
+ this.setScrollTop(this.scrollTop);
+ }
+ }
+ },
+
+ updateRowStyles: function(inRowIndex){
+ // summary:
+ // Update the styles for a row after it's state has changed.
+ this.views.updateRowStyles(inRowIndex);
+ },
+ getRowNode: function(inRowIndex){
+ // summary:
+ // find the rowNode that is not a rowSelector
+ if (this.focus.focusView && !(this.focus.focusView instanceof _RowSelector)){
+ return this.focus.focusView.rowNodes[inRowIndex];
+ }else{ // search through views
+ for (var i = 0, cView; (cView = this.views.views[i]); i++) {
+ if (!(cView instanceof _RowSelector)) {
+ return cView.rowNodes[inRowIndex];
+ }
+ }
+ }
+ return null;
+ },
+ rowHeightChanged: function(inRowIndex){
+ // summary:
+ // Update grid when the height of a row has changed. Row height is handled automatically as rows
+ // are rendered. Use this function only to update a row's height outside the normal rendering process.
+ // inRowIndex: Integer
+ // index of the row that has changed height
+
+ this.views.renormalizeRow(inRowIndex);
+ this.scroller.rowHeightChanged(inRowIndex);
+ },
+
+ // fastScroll: Boolean
+ // flag modifies vertical scrolling behavior. Defaults to true but set to false for slower
+ // scroll performance but more immediate scrolling feedback
+ fastScroll: true,
+
+ delayScroll: false,
+
+ // scrollRedrawThreshold: int
+ // pixel distance a user must scroll vertically to trigger grid scrolling.
+ scrollRedrawThreshold: (has("ie") ? 100 : 50),
+
+ // scroll methods
+ scrollTo: function(inTop){
+ // summary:
+ // Vertically scroll the grid to a given pixel position
+ // inTop: Integer
+ // vertical position of the grid in pixels
+ if(!this.fastScroll){
+ this.setScrollTop(inTop);
+ return;
+ }
+ var delta = Math.abs(this.lastScrollTop - inTop);
+ this.lastScrollTop = inTop;
+ if(delta > this.scrollRedrawThreshold || this.delayScroll){
+ this.delayScroll = true;
+ this.scrollTop = inTop;
+ this.views.setScrollTop(inTop);
+ if(this._pendingScroll){
+ window.clearTimeout(this._pendingScroll);
+ }
+ var _this = this;
+ this._pendingScroll = window.setTimeout(function(){
+ delete _this._pendingScroll;
+ _this.finishScrollJob();
+ }, 200);
+ }else{
+ this.setScrollTop(inTop);
+ }
+ },
+
+ finishScrollJob: function(){
+ this.delayScroll = false;
+ this.setScrollTop(this.scrollTop);
+ },
+
+ setScrollTop: function(inTop){
+ this.scroller.scroll(this.views.setScrollTop(inTop));
+ },
+
+ scrollToRow: function(inRowIndex){
+ // summary:
+ // Scroll the grid to a specific row.
+ // inRowIndex: Integer
+ // grid row index
+ this.setScrollTop(this.scroller.findScrollTop(inRowIndex) + 1);
+ },
+
+ // styling (private, used internally to style individual parts of a row)
+ styleRowNode: function(inRowIndex, inRowNode){
+ if(inRowNode){
+ this.rows.styleRowNode(inRowIndex, inRowNode);
+ }
+ },
+
+ // called when the mouse leaves the grid so we can deselect all hover rows
+ _mouseOut: function(e){
+ this.rows.setOverRow(-2);
+ },
+
+ // cells
+ getCell: function(inIndex){
+ // summary:
+ // Retrieves the cell object for a given grid column.
+ // inIndex: Integer
+ // Grid column index of cell to retrieve
+ // returns:
+ // a grid cell
+ return this.layout.cells[inIndex];
+ },
+
+ setCellWidth: function(inIndex, inUnitWidth){
+ this.getCell(inIndex).unitWidth = inUnitWidth;
+ },
+
+ getCellName: function(inCell){
+ // summary: Returns the cell name of a passed cell
+ return "Cell " + inCell.index; // String
+ },
+
+ // sorting
+ canSort: function(inSortInfo){
+ // summary:
+ // Determines if the grid can be sorted
+ // inSortInfo: Integer
+ // Sort information, 1-based index of column on which to sort, positive for an ascending sort
+ // and negative for a descending sort
+ // returns: Boolean
+ // True if grid can be sorted on the given column in the given direction
+ },
+
+ sort: function(){
+ },
+
+ getSortAsc: function(inSortInfo){
+ // summary:
+ // Returns true if grid is sorted in an ascending direction.
+ inSortInfo = inSortInfo == undefined ? this.sortInfo : inSortInfo;
+ return Boolean(inSortInfo > 0); // Boolean
+ },
+
+ getSortIndex: function(inSortInfo){
+ // summary:
+ // Returns the index of the column on which the grid is sorted
+ inSortInfo = inSortInfo == undefined ? this.sortInfo : inSortInfo;
+ return Math.abs(inSortInfo) - 1; // Integer
+ },
+
+ setSortIndex: function(inIndex, inAsc){
+ // summary:
+ // Sort the grid on a column in a specified direction
+ // inIndex: Integer
+ // Column index on which to sort.
+ // inAsc: Boolean
+ // If true, sort the grid in ascending order, otherwise in descending order
+ var si = inIndex +1;
+ if(inAsc != undefined){
+ si *= (inAsc ? 1 : -1);
+ } else if(this.getSortIndex() == inIndex){
+ si = -this.sortInfo;
+ }
+ this.setSortInfo(si);
+ },
+
+ setSortInfo: function(inSortInfo){
+ if(this.canSort(inSortInfo)){
+ this.sortInfo = inSortInfo;
+ this.sort();
+ this.update();
+ }
+ },
+
+ // DOM event handler
+ doKeyEvent: function(e){
+ e.dispatch = 'do' + e.type;
+ this.onKeyEvent(e);
+ },
+
+ // event dispatch
+ //: protected
+ _dispatch: function(m, e){
+ if(m in this){
+ return this[m](e);
+ }
+ return false;
+ },
+
+ dispatchKeyEvent: function(e){
+ this._dispatch(e.dispatch, e);
+ },
+
+ dispatchContentEvent: function(e){
+ this.edit.dispatchEvent(e) || e.sourceView.dispatchContentEvent(e) || this._dispatch(e.dispatch, e);
+ },
+
+ dispatchHeaderEvent: function(e){
+ e.sourceView.dispatchHeaderEvent(e) || this._dispatch('doheader' + e.type, e);
+ },
+
+ dokeydown: function(e){
+ this.onKeyDown(e);
+ },
+
+ doclick: function(e){
+ if(e.cellNode){
+ this.onCellClick(e);
+ }else{
+ this.onRowClick(e);
+ }
+ },
+
+ dodblclick: function(e){
+ if(e.cellNode){
+ this.onCellDblClick(e);
+ }else{
+ this.onRowDblClick(e);
+ }
+ },
+
+ docontextmenu: function(e){
+ if(e.cellNode){
+ this.onCellContextMenu(e);
+ }else{
+ this.onRowContextMenu(e);
+ }
+ },
+
+ doheaderclick: function(e){
+ if(e.cellNode){
+ this.onHeaderCellClick(e);
+ }else{
+ this.onHeaderClick(e);
+ }
+ },
+
+ doheaderdblclick: function(e){
+ if(e.cellNode){
+ this.onHeaderCellDblClick(e);
+ }else{
+ this.onHeaderDblClick(e);
+ }
+ },
+
+ doheadercontextmenu: function(e){
+ if(e.cellNode){
+ this.onHeaderCellContextMenu(e);
+ }else{
+ this.onHeaderContextMenu(e);
+ }
+ },
+
+ // override to modify editing process
+ doStartEdit: function(inCell, inRowIndex){
+ this.onStartEdit(inCell, inRowIndex);
+ },
+
+ doApplyCellEdit: function(inValue, inRowIndex, inFieldIndex){
+ this.onApplyCellEdit(inValue, inRowIndex, inFieldIndex);
+ },
+
+ doCancelEdit: function(inRowIndex){
+ this.onCancelEdit(inRowIndex);
+ },
+
+ doApplyEdit: function(inRowIndex){
+ this.onApplyEdit(inRowIndex);
+ },
+
+ // row editing
+ addRow: function(){
+ // summary:
+ // Add a row to the grid.
+ this.updateRowCount(this.get('rowCount')+1);
+ },
+
+ removeSelectedRows: function(){
+ // summary:
+ // Remove the selected rows from the grid.
+ if(this.allItemsSelected){
+ this.updateRowCount(0);
+ }else{
+ this.updateRowCount(Math.max(0, this.get('rowCount') - this.selection.getSelected().length));
+ }
+ this.selection.clear();
+ }
+
+ });
+
+ _Grid.markupFactory = function(props, node, ctor, cellFunc){
+ var widthFromAttr = function(n){
+ var w = html.attr(n, "width")||"auto";
+ if((w != "auto")&&(w.slice(-2) != "em")&&(w.slice(-1) != "%")){
+ w = parseInt(w, 10)+"px";
+ }
+ return w;
+ };
+ // if(!props.store){ console.debug("no store!"); }
+ // if a structure isn't referenced, do we have enough
+ // data to try to build one automatically?
+ if( !props.structure &&
+ node.nodeName.toLowerCase() == "table"){
+
+ // try to discover a structure
+ props.structure = query("> colgroup", node).map(function(cg){
+ var sv = html.attr(cg, "span");
+ var v = {
+ noscroll: (html.attr(cg, "noscroll") == "true") ? true : false,
+ __span: (!!sv ? parseInt(sv, 10) : 1),
+ cells: []
+ };
+ if(html.hasAttr(cg, "width")){
+ v.width = widthFromAttr(cg);
+ }
+ return v; // for vendetta
+ });
+ if(!props.structure.length){
+ props.structure.push({
+ __span: Infinity,
+ cells: [] // catch-all view
+ });
+ }
+ // check to see if we're gonna have more than one view
+
+ // for each tr in our th, create a row of cells
+ query("thead > tr", node).forEach(function(tr, tr_idx){
+ var cellCount = 0;
+ var viewIdx = 0;
+ var lastViewIdx;
+ var cView = null;
+ query("> th", tr).map(function(th){
+ // what view will this cell go into?
+
+ // NOTE:
+ // to prevent extraneous iteration, we start counters over
+ // for each row, incrementing over the surface area of the
+ // structure that colgroup processing generates and
+ // creating cell objects for each <th> to place into those
+ // cell groups. There's a lot of state-keepking logic
+ // here, but it is what it has to be.
+ if(!cView){ // current view book keeping
+ lastViewIdx = 0;
+ cView = props.structure[0];
+ }else if(cellCount >= (lastViewIdx+cView.__span)){
+ viewIdx++;
+ // move to allocating things into the next view
+ lastViewIdx += cView.__span;
+ var lastView = cView;
+ cView = props.structure[viewIdx];
+ }
+
+ // actually define the cell from what markup hands us
+ var cell = {
+ name: lang.trim(html.attr(th, "name")||th.innerHTML),
+ colSpan: parseInt(html.attr(th, "colspan")||1, 10),
+ type: lang.trim(html.attr(th, "cellType")||""),
+ id: lang.trim(html.attr(th,"id")||"")
+ };
+ cellCount += cell.colSpan;
+ var rowSpan = html.attr(th, "rowspan");
+ if(rowSpan){
+ cell.rowSpan = rowSpan;
+ }
+ if(html.hasAttr(th, "width")){
+ cell.width = widthFromAttr(th);
+ }
+ if(html.hasAttr(th, "relWidth")){
+ cell.relWidth = window.parseInt(html.attr(th, "relWidth"), 10);
+ }
+ if(html.hasAttr(th, "hidden")){
+ cell.hidden = (html.attr(th, "hidden") == "true" || html.attr(th, "hidden") === true/*always boolean true in Chrome*/);
+ }
+
+ if(cellFunc){
+ cellFunc(th, cell);
+ }
+
+ cell.type = cell.type ? lang.getObject(cell.type) : dojox.grid.cells.Cell;
+
+ if(cell.type && cell.type.markupFactory){
+ cell.type.markupFactory(th, cell);
+ }
+
+ if(!cView.cells[tr_idx]){
+ cView.cells[tr_idx] = [];
+ }
+ cView.cells[tr_idx].push(cell);
+ });
+ });
+ }
+
+ return new ctor(props, node);
+ };
+
+ return _Grid;
+
+}); \ No newline at end of file
diff --git a/js/dojo-1.7.2/dojox/grid/_Layout.js b/js/dojo-1.7.2/dojox/grid/_Layout.js
new file mode 100644
index 0000000..3417168
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/_Layout.js
@@ -0,0 +1,276 @@
+//>>built
+define("dojox/grid/_Layout", [
+ "dojo/_base/kernel",
+ "../main",
+ "dojo/_base/declare",
+ "dojo/_base/array",
+ "dojo/_base/lang",
+ "dojo/dom-geometry",
+ "./cells",
+ "./_RowSelector"
+], function(dojo, dojox, declare, array, lang, domGeometry){
+
+return declare("dojox.grid._Layout", null, {
+ // summary:
+ // Controls grid cell layout. Owned by grid and used internally.
+ constructor: function(inGrid){
+ this.grid = inGrid;
+ },
+ // flat array of grid cells
+ cells: [],
+ // structured array of grid cells
+ structure: null,
+ // default cell width
+ defaultWidth: '6em',
+
+ // methods
+ moveColumn: function(sourceViewIndex, destViewIndex, cellIndex, targetIndex, before){
+ var source_cells = this.structure[sourceViewIndex].cells[0];
+ var dest_cells = this.structure[destViewIndex].cells[0];
+
+ var cell = null;
+ var cell_ri = 0;
+ var target_ri = 0;
+
+ for(var i=0, c; c=source_cells[i]; i++){
+ if(c.index == cellIndex){
+ cell_ri = i;
+ break;
+ }
+ }
+ cell = source_cells.splice(cell_ri, 1)[0];
+ cell.view = this.grid.views.views[destViewIndex];
+
+ for(i=0, c=null; c=dest_cells[i]; i++){
+ if(c.index == targetIndex){
+ target_ri = i;
+ break;
+ }
+ }
+ if(!before){
+ target_ri += 1;
+ }
+ dest_cells.splice(target_ri, 0, cell);
+
+ var sortedCell = this.grid.getCell(this.grid.getSortIndex());
+ if(sortedCell){
+ sortedCell._currentlySorted = this.grid.getSortAsc();
+ }
+
+ this.cells = [];
+ cellIndex = 0;
+ var v;
+ for(i=0; v=this.structure[i]; i++){
+ for(var j=0, cs; cs=v.cells[j]; j++){
+ for(var k=0; c=cs[k]; k++){
+ c.index = cellIndex;
+ this.cells.push(c);
+ if("_currentlySorted" in c){
+ var si = cellIndex + 1;
+ si *= c._currentlySorted ? 1 : -1;
+ this.grid.sortInfo = si;
+ delete c._currentlySorted;
+ }
+ cellIndex++;
+ }
+ }
+ }
+
+ //Fix #9481 - reset idx in cell markup
+ array.forEach(this.cells, function(c){
+ var marks = c.markup[2].split(" ");
+ var oldIdx = parseInt(marks[1].substring(5));//get old "idx"
+ if(oldIdx != c.index){
+ marks[1] = "idx=\"" + c.index + "\"";
+ c.markup[2] = marks.join(" ");
+ }
+ });
+
+ this.grid.setupHeaderMenu();
+ //this.grid.renderOnIdle();
+ },
+
+ setColumnVisibility: function(columnIndex, visible){
+ var cell = this.cells[columnIndex];
+ if(cell.hidden == visible){
+ cell.hidden = !visible;
+ var v = cell.view, w = v.viewWidth;
+ if(w && w != "auto"){
+ v._togglingColumn = domGeometry.getMarginBox(cell.getHeaderNode()).w || 0;
+ }
+ v.update();
+ return true;
+ }else{
+ return false;
+ }
+ },
+
+ addCellDef: function(inRowIndex, inCellIndex, inDef){
+ var self = this;
+ var getCellWidth = function(inDef){
+ var w = 0;
+ if(inDef.colSpan > 1){
+ w = 0;
+ }else{
+ w = inDef.width || self._defaultCellProps.width || self.defaultWidth;
+
+ if(!isNaN(w)){
+ w = w + "em";
+ }
+ }
+ return w;
+ };
+
+ var props = {
+ grid: this.grid,
+ subrow: inRowIndex,
+ layoutIndex: inCellIndex,
+ index: this.cells.length
+ };
+
+ if(inDef && inDef instanceof dojox.grid.cells._Base){
+ var new_cell = lang.clone(inDef);
+ props.unitWidth = getCellWidth(new_cell._props);
+ new_cell = lang.mixin(new_cell, this._defaultCellProps, inDef._props, props);
+ return new_cell;
+ }
+
+ var cell_type = inDef.type || inDef.cellType || this._defaultCellProps.type || this._defaultCellProps.cellType || dojox.grid.cells.Cell;
+ if(lang.isString(cell_type)){
+ cell_type = lang.getObject(cell_type);
+ }
+
+ props.unitWidth = getCellWidth(inDef);
+ return new cell_type(lang.mixin({}, this._defaultCellProps, inDef, props));
+ },
+
+ addRowDef: function(inRowIndex, inDef){
+ var result = [];
+ var relSum = 0, pctSum = 0, doRel = true;
+ for(var i=0, def, cell; (def=inDef[i]); i++){
+ cell = this.addCellDef(inRowIndex, i, def);
+ result.push(cell);
+ this.cells.push(cell);
+ // Check and calculate the sum of all relative widths
+ if(doRel && cell.relWidth){
+ relSum += cell.relWidth;
+ }else if(cell.width){
+ var w = cell.width;
+ if(typeof w == "string" && w.slice(-1) == "%"){
+ pctSum += window.parseInt(w, 10);
+ }else if(w == "auto"){
+ // relative widths doesn't play nice with auto - since we
+ // don't have a way of knowing how much space the auto is
+ // supposed to take up.
+ doRel = false;
+ }
+ }
+ }
+ if(relSum && doRel){
+ // We have some kind of relWidths specified - so change them to %
+ array.forEach(result, function(cell){
+ if(cell.relWidth){
+ cell.width = cell.unitWidth = ((cell.relWidth / relSum) * (100 - pctSum)) + "%";
+ }
+ });
+ }
+ return result;
+
+ },
+
+ addRowsDef: function(inDef){
+ var result = [];
+ if(lang.isArray(inDef)){
+ if(lang.isArray(inDef[0])){
+ for(var i=0, row; inDef && (row=inDef[i]); i++){
+ result.push(this.addRowDef(i, row));
+ }
+ }else{
+ result.push(this.addRowDef(0, inDef));
+ }
+ }
+ return result;
+ },
+
+ addViewDef: function(inDef){
+ this._defaultCellProps = inDef.defaultCell || {};
+ if(inDef.width && inDef.width == "auto"){
+ delete inDef.width;
+ }
+ return lang.mixin({}, inDef, {cells: this.addRowsDef(inDef.rows || inDef.cells)});
+ },
+
+ setStructure: function(inStructure){
+ this.fieldIndex = 0;
+ this.cells = [];
+ var s = this.structure = [];
+
+ if(this.grid.rowSelector){
+ var sel = { type: dojox._scopeName + ".grid._RowSelector" };
+
+ if(lang.isString(this.grid.rowSelector)){
+ var width = this.grid.rowSelector;
+
+ if(width == "false"){
+ sel = null;
+ }else if(width != "true"){
+ sel['width'] = width;
+ }
+ }else{
+ if(!this.grid.rowSelector){
+ sel = null;
+ }
+ }
+
+ if(sel){
+ s.push(this.addViewDef(sel));
+ }
+ }
+
+ var isCell = function(def){
+ return ("name" in def || "field" in def || "get" in def);
+ };
+
+ var isRowDef = function(def){
+ if(lang.isArray(def)){
+ if(lang.isArray(def[0]) || isCell(def[0])){
+ return true;
+ }
+ }
+ return false;
+ };
+
+ var isView = function(def){
+ return (def !== null && lang.isObject(def) &&
+ ("cells" in def || "rows" in def || ("type" in def && !isCell(def))));
+ };
+
+ if(lang.isArray(inStructure)){
+ var hasViews = false;
+ for(var i=0, st; (st=inStructure[i]); i++){
+ if(isView(st)){
+ hasViews = true;
+ break;
+ }
+ }
+ if(!hasViews){
+ s.push(this.addViewDef({ cells: inStructure }));
+ }else{
+ for(i=0; (st=inStructure[i]); i++){
+ if(isRowDef(st)){
+ s.push(this.addViewDef({ cells: st }));
+ }else if(isView(st)){
+ s.push(this.addViewDef(st));
+ }
+ }
+ }
+ }else if(isView(inStructure)){
+ // it's a view object
+ s.push(this.addViewDef(inStructure));
+ }
+
+ this.cellCount = this.cells.length;
+ this.grid.setupHeaderMenu();
+ }
+});
+}); \ No newline at end of file
diff --git a/js/dojo-1.7.2/dojox/grid/_RadioSelector.js b/js/dojo-1.7.2/dojox/grid/_RadioSelector.js
new file mode 100644
index 0000000..9cfd000
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/_RadioSelector.js
@@ -0,0 +1,4 @@
+//>>built
+define("dojox/grid/_RadioSelector", ["../main", "./_Selector"], function(dojox){
+ return dojox.grid._RadioSelector;
+}); \ No newline at end of file
diff --git a/js/dojo-1.7.2/dojox/grid/_RowManager.js b/js/dojo-1.7.2/dojox/grid/_RowManager.js
new file mode 100644
index 0000000..c840464
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/_RowManager.js
@@ -0,0 +1,64 @@
+//>>built
+define("dojox/grid/_RowManager", [
+ "dojo/_base/declare",
+ "dojo/_base/lang",
+ "dojo/dom-class"
+], function(declare, lang, domClass){
+
+ var setStyleText = function(inNode, inStyleText){
+ if(inNode.style.cssText == undefined){
+ inNode.setAttribute("style", inStyleText);
+ }else{
+ inNode.style.cssText = inStyleText;
+ }
+ };
+
+ return declare("dojox.grid._RowManager", null, {
+ // Stores information about grid rows. Owned by grid and used internally.
+ constructor: function(inGrid){
+ this.grid = inGrid;
+ },
+ linesToEms: 2,
+ overRow: -2,
+ // styles
+ prepareStylingRow: function(inRowIndex, inRowNode){
+ return {
+ index: inRowIndex,
+ node: inRowNode,
+ odd: Boolean(inRowIndex&1),
+ selected: !!this.grid.selection.isSelected(inRowIndex),
+ over: this.isOver(inRowIndex),
+ customStyles: "",
+ customClasses: "dojoxGridRow"
+ };
+ },
+ styleRowNode: function(inRowIndex, inRowNode){
+ var row = this.prepareStylingRow(inRowIndex, inRowNode);
+ this.grid.onStyleRow(row);
+ this.applyStyles(row);
+ },
+ applyStyles: function(inRow){
+ var i = inRow;
+
+ i.node.className = i.customClasses;
+ var h = i.node.style.height;
+ setStyleText(i.node, i.customStyles + ';' + (i.node._style||''));
+ i.node.style.height = h;
+ },
+ updateStyles: function(inRowIndex){
+ this.grid.updateRowStyles(inRowIndex);
+ },
+ // states and events
+ setOverRow: function(inRowIndex){
+ var last = this.overRow;
+ this.overRow = inRowIndex;
+ if((last!=this.overRow)&&(lang.isString(last) || last >= 0)){
+ this.updateStyles(last);
+ }
+ this.updateStyles(this.overRow);
+ },
+ isOver: function(inRowIndex){
+ return (this.overRow == inRowIndex && !domClass.contains(this.grid.domNode, "dojoxGridColumnResizing"));
+ }
+ });
+}); \ No newline at end of file
diff --git a/js/dojo-1.7.2/dojox/grid/_RowSelector.js b/js/dojo-1.7.2/dojox/grid/_RowSelector.js
new file mode 100644
index 0000000..68b0c6b
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/_RowSelector.js
@@ -0,0 +1,59 @@
+//>>built
+define("dojox/grid/_RowSelector", [
+ "dojo/_base/declare",
+ "./_View"
+], function(declare, _View){
+
+return declare('dojox.grid._RowSelector', _View, {
+ // summary:
+ // Custom grid view. If used in a grid structure, provides a small selectable region for grid rows.
+ defaultWidth: "2em",
+ noscroll: true,
+ padBorderWidth: 2,
+ buildRendering: function(){
+ this.inherited('buildRendering', arguments);
+ this.scrollboxNode.style.overflow = "hidden";
+ this.headerNode.style.visibility = "hidden";
+ },
+ getWidth: function(){
+ return this.viewWidth || this.defaultWidth;
+ },
+ buildRowContent: function(inRowIndex, inRowNode){
+ var w = this.contentWidth || 0;
+ inRowNode.innerHTML = '<table class="dojoxGridRowbarTable" style="width:' + w + 'px;height:1px;" border="0" cellspacing="0" cellpadding="0" role="presentation"><tr><td class="dojoxGridRowbarInner">&nbsp;</td></tr></table>';
+ },
+ renderHeader: function(){
+ },
+ updateRow: function(){
+ },
+ resize: function(){
+ this.adaptHeight();
+ },
+ adaptWidth: function(){
+ // Only calculate this here - rather than every call to buildRowContent
+ if(!("contentWidth" in this) && this.contentNode){
+ this.contentWidth = this.contentNode.offsetWidth - this.padBorderWidth;
+ }
+ },
+ // styling
+ doStyleRowNode: function(inRowIndex, inRowNode){
+ var n = [ "dojoxGridRowbar dojoxGridNonNormalizedCell" ];
+ if(this.grid.rows.isOver(inRowIndex)){
+ n.push("dojoxGridRowbarOver");
+ }
+ if(this.grid.selection.isSelected(inRowIndex)){
+ n.push("dojoxGridRowbarSelected");
+ }
+ inRowNode.className = n.join(" ");
+ },
+ // event handlers
+ domouseover: function(e){
+ this.grid.onMouseOverRow(e);
+ },
+ domouseout: function(e){
+ if(!this.isIntraRowEvent(e)){
+ this.grid.onMouseOutRow(e);
+ }
+ }
+});
+}); \ No newline at end of file
diff --git a/js/dojo-1.7.2/dojox/grid/_Scroller.js b/js/dojo-1.7.2/dojox/grid/_Scroller.js
new file mode 100644
index 0000000..99eae94
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/_Scroller.js
@@ -0,0 +1,507 @@
+//>>built
+define("dojox/grid/_Scroller", [
+ "dijit/registry",
+ "dojo/_base/declare",
+ "dojo/_base/lang",
+ "./util",
+ "dojo/_base/html"
+], function(dijitRegistry, declare, lang, util, html){
+
+ var indexInParent = function(inNode){
+ var i=0, n, p=inNode.parentNode;
+ while((n = p.childNodes[i++])){
+ if(n == inNode){
+ return i - 1;
+ }
+ }
+ return -1;
+ };
+
+ var cleanNode = function(inNode){
+ if(!inNode){
+ return;
+ }
+ dojo.forEach(dijitRegistry.toArray(), function(w){
+ if(w.domNode && html.isDescendant(w.domNode, inNode, true)){
+ w.destroy();
+ }
+ });
+ };
+
+ var getTagName = function(inNodeOrId){
+ var node = html.byId(inNodeOrId);
+ return (node && node.tagName ? node.tagName.toLowerCase() : '');
+ };
+
+ var nodeKids = function(inNode, inTag){
+ var result = [];
+ var i=0, n;
+ while((n = inNode.childNodes[i])){
+ i++;
+ if(getTagName(n) == inTag){
+ result.push(n);
+ }
+ }
+ return result;
+ };
+
+ var divkids = function(inNode){
+ return nodeKids(inNode, 'div');
+ };
+
+ return declare("dojox.grid._Scroller", null, {
+ constructor: function(inContentNodes){
+ this.setContentNodes(inContentNodes);
+ this.pageHeights = [];
+ this.pageNodes = [];
+ this.stack = [];
+ },
+ // specified
+ rowCount: 0, // total number of rows to manage
+ defaultRowHeight: 32, // default height of a row
+ keepRows: 100, // maximum number of rows that should exist at one time
+ contentNode: null, // node to contain pages
+ scrollboxNode: null, // node that controls scrolling
+ // calculated
+ defaultPageHeight: 0, // default height of a page
+ keepPages: 10, // maximum number of pages that should exists at one time
+ pageCount: 0,
+ windowHeight: 0,
+ firstVisibleRow: 0,
+ lastVisibleRow: 0,
+ averageRowHeight: 0, // the average height of a row
+ // private
+ page: 0,
+ pageTop: 0,
+ // init
+ init: function(inRowCount, inKeepRows, inRowsPerPage){
+ switch(arguments.length){
+ case 3: this.rowsPerPage = inRowsPerPage;
+ case 2: this.keepRows = inKeepRows;
+ case 1: this.rowCount = inRowCount;
+ default: break;
+ }
+ this.defaultPageHeight = this.defaultRowHeight * this.rowsPerPage;
+ this.pageCount = this._getPageCount(this.rowCount, this.rowsPerPage);
+ this.setKeepInfo(this.keepRows);
+ this.invalidate();
+ if(this.scrollboxNode){
+ this.scrollboxNode.scrollTop = 0;
+ this.scroll(0);
+ this.scrollboxNode.onscroll = lang.hitch(this, 'onscroll');
+ }
+ },
+ _getPageCount: function(rowCount, rowsPerPage){
+ return rowCount ? (Math.ceil(rowCount / rowsPerPage) || 1) : 0;
+ },
+ destroy: function(){
+ this.invalidateNodes();
+ delete this.contentNodes;
+ delete this.contentNode;
+ delete this.scrollboxNode;
+ },
+ setKeepInfo: function(inKeepRows){
+ this.keepRows = inKeepRows;
+ this.keepPages = !this.keepRows ? this.keepPages : Math.max(Math.ceil(this.keepRows / this.rowsPerPage), 2);
+ },
+ // nodes
+ setContentNodes: function(inNodes){
+ this.contentNodes = inNodes;
+ this.colCount = (this.contentNodes ? this.contentNodes.length : 0);
+ this.pageNodes = [];
+ for(var i=0; i<this.colCount; i++){
+ this.pageNodes[i] = [];
+ }
+ },
+ getDefaultNodes: function(){
+ return this.pageNodes[0] || [];
+ },
+ // updating
+ invalidate: function(){
+ this._invalidating = true;
+ this.invalidateNodes();
+ this.pageHeights = [];
+ this.height = (this.pageCount ? (this.pageCount - 1)* this.defaultPageHeight + this.calcLastPageHeight() : 0);
+ this.resize();
+ this._invalidating = false;
+ },
+ updateRowCount: function(inRowCount){
+ this.invalidateNodes();
+ this.rowCount = inRowCount;
+ // update page count, adjust document height
+ var oldPageCount = this.pageCount;
+ if(oldPageCount === 0){
+ //We want to have at least 1px in height to keep scroller. Otherwise with an
+ //empty grid you can't scroll to see the header.
+ this.height = 1;
+ }
+ this.pageCount = this._getPageCount(this.rowCount, this.rowsPerPage);
+ if(this.pageCount < oldPageCount){
+ for(var i=oldPageCount-1; i>=this.pageCount; i--){
+ this.height -= this.getPageHeight(i);
+ delete this.pageHeights[i];
+ }
+ }else if(this.pageCount > oldPageCount){
+ this.height += this.defaultPageHeight * (this.pageCount - oldPageCount - 1) + this.calcLastPageHeight();
+ }
+ this.resize();
+ },
+ // implementation for page manager
+ pageExists: function(inPageIndex){
+ return Boolean(this.getDefaultPageNode(inPageIndex));
+ },
+ measurePage: function(inPageIndex){
+ if(this.grid.rowHeight){
+ var height = this.grid.rowHeight + 1;
+ return ((inPageIndex + 1) * this.rowsPerPage > this.rowCount ?
+ this.rowCount - inPageIndex * this.rowsPerPage :
+ this.rowsPerPage) * height;
+
+ }
+ var n = this.getDefaultPageNode(inPageIndex);
+ return (n && n.innerHTML) ? n.offsetHeight : undefined;
+ },
+ positionPage: function(inPageIndex, inPos){
+ for(var i=0; i<this.colCount; i++){
+ this.pageNodes[i][inPageIndex].style.top = inPos + 'px';
+ }
+ },
+ repositionPages: function(inPageIndex){
+ var nodes = this.getDefaultNodes();
+ var last = 0;
+
+ for(var i=0; i<this.stack.length; i++){
+ last = Math.max(this.stack[i], last);
+ }
+ //
+ var n = nodes[inPageIndex];
+ var y = (n ? this.getPageNodePosition(n) + this.getPageHeight(inPageIndex) : 0);
+ for(var p=inPageIndex+1; p<=last; p++){
+ n = nodes[p];
+ if(n){
+ if(this.getPageNodePosition(n) == y){
+ return;
+ }
+ this.positionPage(p, y);
+ }
+ y += this.getPageHeight(p);
+ }
+ },
+ installPage: function(inPageIndex){
+ for(var i=0; i<this.colCount; i++){
+ this.contentNodes[i].appendChild(this.pageNodes[i][inPageIndex]);
+ }
+ },
+ preparePage: function(inPageIndex, inReuseNode){
+ var p = (inReuseNode ? this.popPage() : null);
+ for(var i=0; i<this.colCount; i++){
+ var nodes = this.pageNodes[i];
+ var new_p = (p === null ? this.createPageNode() : this.invalidatePageNode(p, nodes));
+ new_p.pageIndex = inPageIndex;
+ nodes[inPageIndex] = new_p;
+ }
+ },
+ // rendering implementation
+ renderPage: function(inPageIndex){
+ var nodes = [];
+ var i, j;
+ for(i=0; i<this.colCount; i++){
+ nodes[i] = this.pageNodes[i][inPageIndex];
+ }
+ for(i=0, j=inPageIndex*this.rowsPerPage; (i<this.rowsPerPage)&&(j<this.rowCount); i++, j++){
+ this.renderRow(j, nodes);
+ }
+ },
+ removePage: function(inPageIndex){
+ for(var i=0, j=inPageIndex*this.rowsPerPage; i<this.rowsPerPage; i++, j++){
+ this.removeRow(j);
+ }
+ },
+ destroyPage: function(inPageIndex){
+ for(var i=0; i<this.colCount; i++){
+ var n = this.invalidatePageNode(inPageIndex, this.pageNodes[i]);
+ if(n){
+ html.destroy(n);
+ }
+ }
+ },
+ pacify: function(inShouldPacify){
+ },
+ // pacification
+ pacifying: false,
+ pacifyTicks: 200,
+ setPacifying: function(inPacifying){
+ if(this.pacifying != inPacifying){
+ this.pacifying = inPacifying;
+ this.pacify(this.pacifying);
+ }
+ },
+ startPacify: function(){
+ this.startPacifyTicks = new Date().getTime();
+ },
+ doPacify: function(){
+ var result = (new Date().getTime() - this.startPacifyTicks) > this.pacifyTicks;
+ this.setPacifying(true);
+ this.startPacify();
+ return result;
+ },
+ endPacify: function(){
+ this.setPacifying(false);
+ },
+ // default sizing implementation
+ resize: function(){
+ if(this.scrollboxNode){
+ this.windowHeight = this.scrollboxNode.clientHeight;
+ }
+ for(var i=0; i<this.colCount; i++){
+ //We want to have 1px in height min to keep scroller. Otherwise can't scroll
+ //and see header in empty grid.
+ util.setStyleHeightPx(this.contentNodes[i], Math.max(1,this.height));
+ }
+
+ // Calculate the average row height and update the defaults (row and page).
+ var needPage = (!this._invalidating);
+ if(!needPage){
+ var ah = this.grid.get("autoHeight");
+ if(typeof ah == "number" && ah <= Math.min(this.rowsPerPage, this.rowCount)){
+ needPage = true;
+ }
+ }
+ if(needPage){
+ this.needPage(this.page, this.pageTop);
+ }
+ var rowsOnPage = (this.page < this.pageCount - 1) ? this.rowsPerPage : ((this.rowCount % this.rowsPerPage) || this.rowsPerPage);
+ var pageHeight = this.getPageHeight(this.page);
+ this.averageRowHeight = (pageHeight > 0 && rowsOnPage > 0) ? (pageHeight / rowsOnPage) : 0;
+ },
+ calcLastPageHeight: function(){
+ if(!this.pageCount){
+ return 0;
+ }
+ var lastPage = this.pageCount - 1;
+ var lastPageHeight = ((this.rowCount % this.rowsPerPage)||(this.rowsPerPage)) * this.defaultRowHeight;
+ this.pageHeights[lastPage] = lastPageHeight;
+ return lastPageHeight;
+ },
+ updateContentHeight: function(inDh){
+ this.height += inDh;
+ this.resize();
+ },
+ updatePageHeight: function(inPageIndex, fromBuild, fromAsynRendering){
+ if(this.pageExists(inPageIndex)){
+ var oh = this.getPageHeight(inPageIndex);
+ var h = (this.measurePage(inPageIndex));
+ if(h === undefined){
+ h = oh;
+ }
+ this.pageHeights[inPageIndex] = h;
+ if(oh != h){
+ this.updateContentHeight(h - oh);
+ var ah = this.grid.get("autoHeight");
+ if((typeof ah == "number" && ah > this.rowCount)||(ah === true && !fromBuild)){
+ if(!fromAsynRendering){
+ this.grid.sizeChange();
+ }else{//fix #11101 by using fromAsynRendering to avoid deadlock
+ var ns = this.grid.viewsNode.style;
+ ns.height = parseInt(ns.height) + h - oh + 'px';
+ this.repositionPages(inPageIndex);
+ }
+ }else{
+ this.repositionPages(inPageIndex);
+ }
+ }
+ return h;
+ }
+ return 0;
+ },
+ rowHeightChanged: function(inRowIndex, fromAsynRendering){
+ this.updatePageHeight(Math.floor(inRowIndex / this.rowsPerPage), false, fromAsynRendering);
+ },
+ // scroller core
+ invalidateNodes: function(){
+ while(this.stack.length){
+ this.destroyPage(this.popPage());
+ }
+ },
+ createPageNode: function(){
+ var p = document.createElement('div');
+ html.attr(p,"role","presentation");
+ p.style.position = 'absolute';
+ //p.style.width = '100%';
+ p.style[this.grid.isLeftToRight() ? "left" : "right"] = '0';
+ return p;
+ },
+ getPageHeight: function(inPageIndex){
+ var ph = this.pageHeights[inPageIndex];
+ return (ph !== undefined ? ph : this.defaultPageHeight);
+ },
+ // FIXME: this is not a stack, it's a FIFO list
+ pushPage: function(inPageIndex){
+ return this.stack.push(inPageIndex);
+ },
+ popPage: function(){
+ return this.stack.shift();
+ },
+ findPage: function(inTop){
+ var i = 0, h = 0;
+ for(var ph = 0; i<this.pageCount; i++, h += ph){
+ ph = this.getPageHeight(i);
+ if(h + ph >= inTop){
+ break;
+ }
+ }
+ this.page = i;
+ this.pageTop = h;
+ },
+ buildPage: function(inPageIndex, inReuseNode, inPos){
+ this.preparePage(inPageIndex, inReuseNode);
+ this.positionPage(inPageIndex, inPos);
+ // order of operations is key below
+ this.installPage(inPageIndex);
+ this.renderPage(inPageIndex);
+ // order of operations is key above
+ this.pushPage(inPageIndex);
+ },
+ needPage: function(inPageIndex, inPos){
+ var h = this.getPageHeight(inPageIndex), oh = h;
+ if(!this.pageExists(inPageIndex)){
+ this.buildPage(inPageIndex, (!this.grid._autoHeight/*fix #10543*/ && this.keepPages&&(this.stack.length >= this.keepPages)), inPos);
+ h = this.updatePageHeight(inPageIndex, true);
+ }else{
+ this.positionPage(inPageIndex, inPos);
+ }
+ return h;
+ },
+ onscroll: function(){
+ this.scroll(this.scrollboxNode.scrollTop);
+ },
+ scroll: function(inTop){
+ this.grid.scrollTop = inTop;
+ if(this.colCount){
+ this.startPacify();
+ this.findPage(inTop);
+ var h = this.height;
+ var b = this.getScrollBottom(inTop);
+ for(var p=this.page, y=this.pageTop; (p<this.pageCount)&&((b<0)||(y<b)); p++){
+ y += this.needPage(p, y);
+ }
+ this.firstVisibleRow = this.getFirstVisibleRow(this.page, this.pageTop, inTop);
+ this.lastVisibleRow = this.getLastVisibleRow(p - 1, y, b);
+ // indicates some page size has been updated
+ if(h != this.height){
+ this.repositionPages(p-1);
+ }
+ this.endPacify();
+ }
+ },
+ getScrollBottom: function(inTop){
+ return (this.windowHeight >= 0 ? inTop + this.windowHeight : -1);
+ },
+ // events
+ processNodeEvent: function(e, inNode){
+ var t = e.target;
+ while(t && (t != inNode) && t.parentNode && (t.parentNode.parentNode != inNode)){
+ t = t.parentNode;
+ }
+ if(!t || !t.parentNode || (t.parentNode.parentNode != inNode)){
+ return false;
+ }
+ var page = t.parentNode;
+ e.topRowIndex = page.pageIndex * this.rowsPerPage;
+ e.rowIndex = e.topRowIndex + indexInParent(t);
+ e.rowTarget = t;
+ return true;
+ },
+ processEvent: function(e){
+ return this.processNodeEvent(e, this.contentNode);
+ },
+ // virtual rendering interface
+ renderRow: function(inRowIndex, inPageNode){
+ },
+ removeRow: function(inRowIndex){
+ },
+ // page node operations
+ getDefaultPageNode: function(inPageIndex){
+ return this.getDefaultNodes()[inPageIndex];
+ },
+ positionPageNode: function(inNode, inPos){
+ },
+ getPageNodePosition: function(inNode){
+ return inNode.offsetTop;
+ },
+ invalidatePageNode: function(inPageIndex, inNodes){
+ var p = inNodes[inPageIndex];
+ if(p){
+ delete inNodes[inPageIndex];
+ this.removePage(inPageIndex, p);
+ cleanNode(p);
+ p.innerHTML = '';
+ }
+ return p;
+ },
+ // scroll control
+ getPageRow: function(inPage){
+ return inPage * this.rowsPerPage;
+ },
+ getLastPageRow: function(inPage){
+ return Math.min(this.rowCount, this.getPageRow(inPage + 1)) - 1;
+ },
+ getFirstVisibleRow: function(inPage, inPageTop, inScrollTop){
+ if(!this.pageExists(inPage)){
+ return 0;
+ }
+ var row = this.getPageRow(inPage);
+ var nodes = this.getDefaultNodes();
+ var rows = divkids(nodes[inPage]);
+ for(var i=0,l=rows.length; i<l && inPageTop<inScrollTop; i++, row++){
+ inPageTop += rows[i].offsetHeight;
+ }
+ return (row ? row - 1 : row);
+ },
+ getLastVisibleRow: function(inPage, inBottom, inScrollBottom){
+ if(!this.pageExists(inPage)){
+ return 0;
+ }
+ var nodes = this.getDefaultNodes();
+ var row = this.getLastPageRow(inPage);
+ var rows = divkids(nodes[inPage]);
+ for(var i=rows.length-1; i>=0 && inBottom>inScrollBottom; i--, row--){
+ inBottom -= rows[i].offsetHeight;
+ }
+ return row + 1;
+ },
+ findTopRow: function(inScrollTop){
+ var nodes = this.getDefaultNodes();
+ var rows = divkids(nodes[this.page]);
+ for(var i=0,l=rows.length,t=this.pageTop,h; i<l; i++){
+ h = rows[i].offsetHeight;
+ t += h;
+ if(t >= inScrollTop){
+ this.offset = h - (t - inScrollTop);
+ return i + this.page * this.rowsPerPage;
+ }
+ }
+ return -1;
+ },
+ findScrollTop: function(inRow){
+ var rowPage = Math.floor(inRow / this.rowsPerPage);
+ var t = 0;
+ var i, l;
+ for(i=0; i<rowPage; i++){
+ t += this.getPageHeight(i);
+ }
+ this.pageTop = t;
+ this.page = rowPage;//fix #10543
+ this.needPage(rowPage, this.pageTop);
+
+ var nodes = this.getDefaultNodes();
+ var rows = divkids(nodes[rowPage]);
+ var r = inRow - this.rowsPerPage * rowPage;
+ for(i=0,l=rows.length; i<l && i<r; i++){
+ t += rows[i].offsetHeight;
+ }
+ return t;
+ },
+ dummy: 0
+ });
+});
diff --git a/js/dojo-1.7.2/dojox/grid/_SelectionPreserver.js b/js/dojo-1.7.2/dojox/grid/_SelectionPreserver.js
new file mode 100644
index 0000000..c02e92c
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/_SelectionPreserver.js
@@ -0,0 +1,67 @@
+//>>built
+define("dojox/grid/_SelectionPreserver", [
+ "dojo/_base/declare",
+ "dojo/_base/connect",
+ "dojo/_base/lang",
+ "dojo/_base/array"
+], function(declare, connect, lang, array){
+
+return declare("dojox.grid._SelectionPreserver", null, {
+ // summary:
+ // Preserve selections across various user actions.
+ //
+ // description:
+ // When this feature is turned on, Grid will try to preserve selections across actions, e.g. sorting, filtering etc.
+ //
+ // Precondition - Identifier(id) is required for store since id is the only way for differentiating row items.
+ // Known issue - The preserved selections might be inaccurate if some unloaded rows are previously selected by range(e.g.SHIFT + click)
+ //
+ // example:
+ // | //To turn on this - please set 'keepSelection' attribute to true
+ // | <div dojoType="dojox.grid.DataGrid" keepSelection = true .../>
+ // | <div dojoType="dojox.grid.TreeGrid" keepSelection = true .../>
+ // | <div dojoType="dojox.grid.LazyTreeGrid" keepSelection = true .../>
+
+ constructor: function(selection){
+ this.selection = selection;
+ var grid = this.grid = selection.grid;
+ this.reset();
+ this._connects = [
+ connect.connect(grid, '_setStore', this, 'reset'),
+ connect.connect(grid, '_addItem', this, '_reSelectById'),
+ connect.connect(selection, 'addToSelection', lang.hitch(this, '_selectById', true)),
+ connect.connect(selection, 'deselect', lang.hitch(this, '_selectById', false)),
+ connect.connect(selection, 'deselectAll', this, 'reset')
+ ];
+ },
+ destroy: function(){
+ this.reset();
+ array.forEach(this._connects, connect.disconnect);
+ delete this._connects;
+ },
+ reset: function(){
+ this._selectedById = {};
+ },
+ _reSelectById: function(item, index){
+ // summary:
+ // When some rows is fetched, determine whether it should be selected.
+ if(item && this.grid._hasIdentity){
+ this.selection.selected[index] = this._selectedById[this.grid.store.getIdentity(item)];
+ }
+ },
+ _selectById: function(toSelect, inItemOrIndex){
+ // summary:
+ // Record selected rows by ID.
+ if(this.selection.mode == 'none' || !this.grid._hasIdentity){ return; }
+ var item = inItemOrIndex, g = this.grid;
+ if(typeof inItemOrIndex == "number" || typeof inItemOrIndex == "string"){
+ var entry = g._by_idx[inItemOrIndex];
+ item = entry && entry.item;
+ }
+ if(item){
+ this._selectedById[g.store.getIdentity(item)] = !!toSelect;
+ }
+ return item;
+ }
+});
+}); \ No newline at end of file
diff --git a/js/dojo-1.7.2/dojox/grid/_Selector.js b/js/dojo-1.7.2/dojox/grid/_Selector.js
new file mode 100644
index 0000000..142b4d4
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/_Selector.js
@@ -0,0 +1,225 @@
+//>>built
+define("dojox/grid/_Selector", [
+ "../main",
+ "dojo/_base/declare",
+ "dojo/_base/lang",
+ "dojo/query",
+ "dojo/dom-class",
+ "./Selection",
+ "./_View",
+ "./_Builder",
+ "./util"
+], function(dojox, declare, lang, query, domClass, Selection, _View, _Builder, util){
+
+ var _InputSelectorHeaderBuilder = dojox.grid._InputSelectorHeaderBuilder = lang.extend(function(view){
+ _Builder._HeaderBuilder.call(this, view);
+ },_Builder._HeaderBuilder.prototype,{
+ generateHtml: function(){
+ var w = this.view.contentWidth || 0;
+ var selectedCount = this.view.grid.selection.getSelectedCount();
+ var checked = (selectedCount && selectedCount == this.view.grid.rowCount) ? ' dijitCheckBoxChecked dijitChecked' : '';
+ return '<table style="width:' + w + 'px;" ' +
+ 'border="0" cellspacing="0" cellpadding="0" ' +
+ 'role="presentation"><tr><th style="text-align: center;">' +
+ '<div class="dojoxGridCheckSelector dijitReset dijitInline dijitCheckBox' + checked + '"></div></th></tr></table>';
+ },
+ doclick: function(e){
+ var selectedCount = this.view.grid.selection.getSelectedCount();
+
+ this.view._selectionChanging = true;
+ if(selectedCount==this.view.grid.rowCount){
+ this.view.grid.selection.deselectAll();
+ }else{
+ this.view.grid.selection.selectRange(0, this.view.grid.rowCount-1);
+ }
+ this.view._selectionChanging = false;
+ this.view.onSelectionChanged();
+ return true;
+ }
+ });
+
+ var _SelectorContentBuilder = dojox.grid._SelectorContentBuilder = lang.extend(function(view){
+ _Builder._ContentBuilder.call(this, view);
+ },_Builder._ContentBuilder.prototype,{
+ generateHtml: function(inDataIndex, inRowIndex){
+ var w = this.view.contentWidth || 0;
+ return '<table class="dojoxGridRowbarTable" style="width:' + w + 'px;" border="0" ' +
+ 'cellspacing="0" cellpadding="0" role="presentation"><tr>' +
+ '<td style="text-align: center;" class="dojoxGridRowbarInner">' + this.getCellContent(inRowIndex) + '</td></tr></table>';
+ },
+ getCellContent: function(inRowIndex){
+ return '&nbsp;';
+ },
+ findTarget: function(){
+ var t = _Builder._ContentBuilder.prototype.findTarget.apply(this, arguments);
+ return t;
+ },
+ domouseover: function(e){
+ this.view.grid.onMouseOverRow(e);
+ },
+ domouseout: function(e){
+ if(!this.isIntraRowEvent(e)){
+ this.view.grid.onMouseOutRow(e);
+ }
+ },
+ doclick: function(e){
+ var idx = e.rowIndex;
+ var selected = this.view.grid.selection.isSelected(idx);
+ var mode = this.view.grid.selection.mode;
+
+ if(!selected){
+ if(mode == 'single'){
+ this.view.grid.selection.select(idx);
+ }else if(mode != 'none'){
+ this.view.grid.selection.addToSelection(idx);
+ }
+ }else{
+ this.view.grid.selection.deselect(idx);
+ }
+
+ return true;
+ }
+ });
+
+ var _InputSelectorContentBuilder = dojox.grid._InputSelectorContentBuilder = lang.extend(function(view){
+ _SelectorContentBuilder.call(this, view);
+ },_SelectorContentBuilder.prototype,{
+ getCellContent: function(rowIndex){
+ var v = this.view;
+ var type = v.inputType == "checkbox" ? "CheckBox" : "Radio";
+ var checked = !!v.grid.selection.isSelected(rowIndex) ? ' dijit' + type + 'Checked dijitChecked' : '';
+ return '<div class="dojoxGridCheckSelector dijitReset dijitInline dijit' + type + checked + '"></div>';
+ }
+ });
+
+ var _Selector = declare("dojox.grid._Selector", _View, {
+ inputType: '',
+ selectionMode: '',
+
+ // summary:
+ // Custom grid view. If used in a grid structure, provides a small selectable region for grid rows.
+ defaultWidth: "2em",
+ noscroll: true,
+ padBorderWidth: 2,
+
+ _contentBuilderClass: _SelectorContentBuilder,
+
+ postCreate: function(){
+ this.inherited(arguments);
+
+ if(this.selectionMode){
+ this.grid.selection.mode = this.selectionMode;
+ }
+ this.connect(this.grid.selection, 'onSelected', 'onSelected');
+ this.connect(this.grid.selection, 'onDeselected', 'onDeselected');
+ },
+ buildRendering: function(){
+ this.inherited(arguments);
+ this.scrollboxNode.style.overflow = "hidden";
+ },
+ getWidth: function(){
+ return this.viewWidth || this.defaultWidth;
+ },
+ resize: function(){
+ this.adaptHeight();
+ },
+ setStructure: function(s){
+ this.inherited(arguments);
+ if(s.defaultWidth){
+ this.defaultWidth = s.defaultWidth;
+ }
+ },
+ adaptWidth: function(){
+ // Only calculate this here - rather than every call to buildRowContent
+ if(!("contentWidth" in this) && this.contentNode){
+ this.contentWidth = this.contentNode.offsetWidth - this.padBorderWidth;
+ }
+ },
+ // styling
+ doStyleRowNode: function(inRowIndex, inRowNode){
+ var n = [ "dojoxGridRowbar dojoxGridNonNormalizedCell" ];
+ if(this.grid.rows.isOver(inRowIndex)){
+ n.push("dojoxGridRowbarOver");
+ }
+ if(this.grid.selection.isSelected(inRowIndex)){
+ n.push("dojoxGridRowbarSelected");
+ }
+ inRowNode.className = n.join(" ");
+ },
+ // event handlers
+ onSelected: function(inIndex){
+ this.grid.updateRow(inIndex);
+ },
+ onDeselected: function(inIndex){
+ this.grid.updateRow(inIndex);
+ }
+ });
+ if(!_View.prototype._headerBuilderClass &&
+ !_View.prototype._contentBuilderClass){
+ _Selector.prototype.postCreate = function(){
+ this.connect(this.scrollboxNode,"onscroll","doscroll");
+ util.funnelEvents(this.contentNode, this, "doContentEvent", [ 'mouseover', 'mouseout', 'click', 'dblclick', 'contextmenu', 'mousedown' ]);
+ util.funnelEvents(this.headerNode, this, "doHeaderEvent", [ 'dblclick', 'mouseover', 'mouseout', 'mousemove', 'mousedown', 'click', 'contextmenu' ]);
+ if(this._contentBuilderClass){
+ this.content = new this._contentBuilderClass(this);
+ }else{
+ this.content = new _Builder._ContentBuilder(this);
+ }
+ if(this._headerBuilderClass){
+ this.header = new this._headerBuilderClass(this);
+ }else{
+ this.header = new _Builder._HeaderBuilder(this);
+ }
+ //BiDi: in RTL case, style width='9000em' causes scrolling problem in head node
+ if(!this.grid.isLeftToRight()){
+ this.headerNodeContainer.style.width = "";
+ }
+ this.connect(this.grid.selection, 'onSelected', 'onSelected');
+ this.connect(this.grid.selection, 'onDeselected', 'onDeselected');
+ };
+ }
+
+ declare("dojox.grid._RadioSelector", _Selector, {
+ inputType: 'radio',
+ selectionMode: 'single',
+
+ _contentBuilderClass: _InputSelectorContentBuilder,
+
+ buildRendering: function(){
+ this.inherited(arguments);
+ this.headerNode.style.visibility = "hidden";
+ },
+
+ renderHeader: function(){}
+ });
+
+ declare("dojox.grid._CheckBoxSelector", _Selector, {
+ inputType: 'checkbox',
+ _headerBuilderClass: _InputSelectorHeaderBuilder,
+ _contentBuilderClass: _InputSelectorContentBuilder,
+ postCreate: function(){
+ this.inherited(arguments);
+ this.connect(this.grid, 'onSelectionChanged', 'onSelectionChanged');
+ this.connect(this.grid, 'updateRowCount', '_updateVisibility');
+ },
+ renderHeader: function(){
+ this.inherited(arguments);
+ this._updateVisibility(this.grid.rowCount);
+ },
+ _updateVisibility: function(rowCount){
+ this.headerNode.style.visibility = rowCount ? "" : "hidden";
+ },
+ onSelectionChanged: function(){
+ if(this._selectionChanging){ return; }
+ var inputDiv = query('.dojoxGridCheckSelector', this.headerNode)[0];
+ var g = this.grid;
+ var s = (g.rowCount && g.rowCount == g.selection.getSelectedCount());
+ g.allItemsSelected = s||false;
+ domClass.toggle(inputDiv, "dijitChecked", g.allItemsSelected);
+ domClass.toggle(inputDiv, "dijitCheckBoxChecked", g.allItemsSelected);
+ }
+ });
+
+ return _Selector;
+
+}); \ No newline at end of file
diff --git a/js/dojo-1.7.2/dojox/grid/_TreeView.js b/js/dojo-1.7.2/dojox/grid/_TreeView.js
new file mode 100644
index 0000000..8cf24fd
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/_TreeView.js
@@ -0,0 +1,467 @@
+//>>built
+require({cache:{
+'url:dojox/grid/resources/Expando.html':"<div class=\"dojoxGridExpando\"\n\t><div class=\"dojoxGridExpandoNode\" dojoAttachEvent=\"onclick:onToggle\"\n\t\t><div class=\"dojoxGridExpandoNodeInner\" dojoAttachPoint=\"expandoInner\"></div\n\t></div\n></div>\n"}});
+define("dojox/grid/_TreeView", [
+ "dijit/registry",
+ "../main",
+ "dojo/_base/declare",
+ "dojo/_base/array",
+ "dojo/_base/lang",
+ "dojo/_base/event",
+ "dojo/dom-attr",
+ "dojo/dom-class",
+ "dojo/dom-style",
+ "dojo/dom-construct",
+ "dojo/query",
+ "dojo/parser",
+ "dojo/text!./resources/Expando.html",
+ "dijit/_Widget",
+ "dijit/_TemplatedMixin",
+ "./_View",
+ "./_Builder",
+ "./util"
+], function(dijit, dojox, declare, array, lang, event, domAttr, domClass,
+ domStyle, domCtr, query, parser, template, _Widget, _TemplatedMixin, _View, _Builder, util){
+
+declare("dojox.grid._Expando", [ _Widget, _TemplatedMixin ], {
+ open: false,
+ toggleClass: "",
+ itemId: "",
+ cellIdx: -1,
+ view: null,
+ rowNode: null,
+ rowIdx: -1,
+ expandoCell: null,
+ level: 0,
+ templateString: template,
+ _toggleRows: function(toggleClass, open){
+ if(!toggleClass || !this.rowNode){ return; }
+ if(query("table.dojoxGridRowTableNeedsRowUpdate").length){
+ if(this._initialized){
+ this.view.grid.updateRow(this.rowIdx);
+ }
+ return;
+ }
+ var self = this;
+ var g = this.view.grid;
+ if(g.treeModel){
+ var p = this._tableRow ? domAttr.get(this._tableRow, "dojoxTreeGridPath") : "";
+ if(p){
+ query("tr[dojoxTreeGridPath^=\"" + p + "/\"]", this.rowNode).forEach(function(n){
+ var en = query(".dojoxGridExpando", n)[0];
+ if(en && en.parentNode && en.parentNode.parentNode &&
+ !domClass.contains(en.parentNode.parentNode, "dojoxGridNoChildren")){
+ var ew = dijit.byNode(en);
+ if(ew){
+ ew._toggleRows(toggleClass, ew.open&&open);
+ }
+ }
+ n.style.display = open ? "" : "none";
+ });
+ }
+ }else{
+ query("tr." + toggleClass, this.rowNode).forEach(function(n){
+ if(domClass.contains(n, "dojoxGridExpandoRow")){
+ var en = query(".dojoxGridExpando", n)[0];
+ if(en){
+ var ew = dijit.byNode(en);
+ var toggleClass = ew ? ew.toggleClass : en.getAttribute("toggleClass");
+ var wOpen = ew ? ew.open : self.expandoCell.getOpenState(en.getAttribute("itemId"));
+ self._toggleRows(toggleClass, wOpen&&open);
+ }
+ }
+ n.style.display = open ? "" : "none";
+ });
+ }
+ },
+ setOpen: function(open){
+ if(open && domClass.contains(this.domNode, "dojoxGridExpandoLoading")){
+ open = false;
+ }
+ var view = this.view;
+ var grid = view.grid;
+ var store = grid.store;
+ var treeModel = grid.treeModel;
+ var d = this;
+ var idx = this.rowIdx;
+ var me = grid._by_idx[idx];
+ if(!me){ return; }
+ if(treeModel && !this._loadedChildren){
+ if(open){
+ // Do this to make sure our children are fully-loaded
+ var itm = grid.getItem(domAttr.get(this._tableRow, "dojoxTreeGridPath"));
+ if(itm){
+ this.expandoInner.innerHTML = "o";
+ domClass.add(this.domNode, "dojoxGridExpandoLoading");
+ treeModel.getChildren(itm, function(items){
+ d._loadedChildren = true;
+ d._setOpen(open);
+ });
+ }else{
+ this._setOpen(open);
+ }
+ }else{
+ this._setOpen(open);
+ }
+ }else if(!treeModel && store){
+ if(open){
+ var data = grid._by_idx[this.rowIdx];
+ if(data&&!store.isItemLoaded(data.item)){
+ this.expandoInner.innerHTML = "o";
+ domClass.add(this.domNode, "dojoxGridExpandoLoading");
+ store.loadItem({
+ item: data.item,
+ onItem: lang.hitch(this, function(i){
+ var idty = store.getIdentity(i);
+ grid._by_idty[idty] = grid._by_idx[this.rowIdx] = { idty: idty, item: i };
+ this._setOpen(open);
+ })
+ });
+ }else{
+ this._setOpen(open);
+ }
+ }else{
+ this._setOpen(open);
+ }
+ }else{
+ this._setOpen(open);
+ }
+ },
+ _setOpen: function(open){
+ if(open && this._tableRow && domClass.contains(this._tableRow, "dojoxGridNoChildren")){
+ this._setOpen(false);
+ return;
+ }
+ this.expandoInner.innerHTML = open ? "-" : "+";
+ domClass.remove(this.domNode, "dojoxGridExpandoLoading");
+ domClass.toggle(this.domNode, "dojoxGridExpandoOpened", open);
+ if(this._tableRow){
+ domClass.toggle(this._tableRow, "dojoxGridRowCollapsed", !open);
+ var base = domAttr.get(this._tableRow, "dojoxTreeGridBaseClasses");
+ var new_base = "";
+ if(open){
+ new_base = lang.trim((" " + base + " ").replace(" dojoxGridRowCollapsed ", " "));
+ }else{
+ if((" " + base + " ").indexOf(' dojoxGridRowCollapsed ') < 0){
+ new_base = base + (base ? ' ' : '' ) + 'dojoxGridRowCollapsed';
+ }else{
+ new_base = base;
+ }
+ }
+ domAttr.set(this._tableRow, 'dojoxTreeGridBaseClasses', new_base);
+ }
+ var changed = (this.open !== open);
+ this.open = open;
+ if(this.expandoCell && this.itemId){
+ this.expandoCell.openStates[this.itemId] = open;
+ }
+ var v = this.view;
+ var g = v.grid;
+ if(this.toggleClass && changed){
+ if(!this._tableRow || !this._tableRow.style.display){
+ this._toggleRows(this.toggleClass, open);
+ }
+ }
+ if(v && this._initialized && this.rowIdx >= 0){
+ g.rowHeightChanged(this.rowIdx);
+ g.postresize();
+ v.hasVScrollbar(true);
+ }
+ this._initialized = true;
+ },
+ onToggle: function(e){
+ this.setOpen(!this.open);
+ event.stop(e);
+ },
+ setRowNode: function(rowIdx, rowNode, view){
+ if(this.cellIdx < 0 || !this.itemId){ return false; }
+ this._initialized = false;
+ this.view = view;
+ this.rowNode = rowNode;
+ this.rowIdx = rowIdx;
+ this.expandoCell = view.structure.cells[0][this.cellIdx];
+ var d = this.domNode;
+ if(d && d.parentNode && d.parentNode.parentNode){
+ this._tableRow = d.parentNode.parentNode;
+ }
+ this.open = this.expandoCell.getOpenState(this.itemId);
+ if(view.grid.treeModel){
+ // TODO: Rather than hard-code the 18px and 3px, we should probably
+ // calculate them based off css or something... However, all the
+ // themes that we support use these values.
+ domStyle.set(this.domNode , "marginLeft" , (this.level * 18) + "px");
+ if(this.domNode.parentNode){
+ domStyle.set(this.domNode.parentNode, "backgroundPosition", ((this.level * 18) + (3)) + "px");
+ }
+ }
+ this.setOpen(this.open);
+ return true;
+ }
+});
+
+var _TreeContentBuilder = declare("dojox.grid._TreeContentBuilder", _Builder._ContentBuilder, {
+ generateHtml: function(inDataIndex, inRowIndex){
+ var
+ html = this.getTableArray(),
+ v = this.view,
+ row = v.structure.cells[0],
+ item = this.grid.getItem(inRowIndex),
+ grid = this.grid,
+ store = this.grid.store;
+
+ util.fire(this.view, "onBeforeRow", [inRowIndex, [row]]);
+
+ var createRow = function(level, rowItem, summaryRow, toggleClasses, rowStack, shown){
+ if(!shown){
+ if(html[0].indexOf('dojoxGridRowTableNeedsRowUpdate') == -1){
+ html[0] = html[0].replace("dojoxGridRowTable", "dojoxGridRowTable dojoxGridRowTableNeedsRowUpdate");
+ }
+ return;
+ }
+ var rowNodeIdx = html.length;
+ toggleClasses = toggleClasses || [];
+ var tcJoin = toggleClasses.join('|');
+ var tcString = toggleClasses[toggleClasses.length - 1];
+ var clString = tcString + (summaryRow ? " dojoxGridSummaryRow" : "");
+ var sString = "";
+ if(grid.treeModel && rowItem && !grid.treeModel.mayHaveChildren(rowItem)){
+ clString += " dojoxGridNoChildren";
+ }
+ html.push('<tr style="' + sString + '" class="' + clString + '" dojoxTreeGridPath="' + rowStack.join('/') + '" dojoxTreeGridBaseClasses="' + clString + '">');
+ var nextLevel = level + 1;
+ var parentCell = null;
+ for(var i=0, cell; (cell=row[i]); i++){
+ var m = cell.markup, cc = cell.customClasses = [], cs = cell.customStyles = [];
+ // content (format can fill in cc and cs as side-effects)
+ m[5] = cell.formatAtLevel(rowStack, rowItem, level, summaryRow, tcString, cc);
+ // classes
+ m[1] = cc.join(' ');
+ // styles
+ m[3] = cs.join(';');
+ // in-place concat
+ html.push.apply(html, m);
+ if(!parentCell && cell.level === nextLevel && cell.parentCell){
+ parentCell = cell.parentCell;
+ }
+ }
+ html.push('</tr>');
+ if(rowItem && store && store.isItem(rowItem)){
+ var idty = store.getIdentity(rowItem);
+ if(typeof grid._by_idty_paths[idty] == "undefined"){
+ grid._by_idty_paths[idty] = rowStack.join('/');
+ }
+ }
+ var expandoCell;
+ var parentOpen;
+ var path;
+ var values;
+ var iStack = rowStack.concat([]);
+ if(grid.treeModel && rowItem){
+ if(grid.treeModel.mayHaveChildren(rowItem)){
+ expandoCell = v.structure.cells[0][grid.expandoCell||0];
+ parentOpen = expandoCell.getOpenState(rowItem) && shown;
+ path = new dojox.grid.TreePath(rowStack.join('/'), grid);
+ values = path.children(true)||[];
+ array.forEach(values, function(cItm, idx){
+ var nToggle = tcJoin.split('|');
+ nToggle.push(nToggle[nToggle.length - 1] + "-" + idx);
+ iStack.push(idx);
+ createRow(nextLevel, cItm, false, nToggle, iStack, parentOpen);
+ iStack.pop();
+ });
+ }
+ }else if(rowItem && parentCell && !summaryRow){
+ expandoCell = v.structure.cells[0][parentCell.level];
+ parentOpen = expandoCell.getOpenState(rowItem) && shown;
+ if(store.hasAttribute(rowItem, parentCell.field)){
+ var tToggle = tcJoin.split('|');
+ tToggle.pop();
+ path = new dojox.grid.TreePath(rowStack.join('/'), grid);
+ values = path.children(true)||[];
+ if(values.length){
+ html[rowNodeIdx] = '<tr class="' + tToggle.join(' ') +' dojoxGridExpandoRow" dojoxTreeGridPath="' + rowStack.join('/') + '">';
+ array.forEach(values, function(cItm, idx){
+ var nToggle = tcJoin.split('|');
+ nToggle.push(nToggle[nToggle.length - 1] + "-" + idx);
+ iStack.push(idx);
+ createRow(nextLevel, cItm, false, nToggle, iStack, parentOpen);
+ iStack.pop();
+ });
+ iStack.push(values.length);
+ createRow(level, rowItem, true, toggleClasses, iStack, parentOpen);
+ }else{
+ html[rowNodeIdx] = '<tr class="' + tcString + ' dojoxGridNoChildren" dojoxTreeGridPath="' + rowStack.join('/') + '">';
+ }
+ }else{
+ if(!store.isItemLoaded(rowItem)){
+ html[0] = html[0].replace("dojoxGridRowTable", "dojoxGridRowTable dojoxGridRowTableNeedsRowUpdate");
+ }else{
+ html[rowNodeIdx] = '<tr class="' + tcString + ' dojoxGridNoChildren" dojoxTreeGridPath="' + rowStack.join('/') + '">';
+ }
+ }
+ }else if(rowItem && !summaryRow && toggleClasses.length > 1){
+ html[rowNodeIdx] = '<tr class="' + toggleClasses[toggleClasses.length - 2] + '" dojoxTreeGridPath="' + rowStack.join('/') + '">';
+ }
+ };
+ createRow(0, item, false, ["dojoxGridRowToggle-" + inRowIndex], [inRowIndex], true);
+ html.push('</table>');
+ return html.join(''); // String
+ },
+ findTarget: function(inSource, inTag){
+ var n = inSource;
+ while(n && (n!=this.domNode)){
+ if(n.tagName && n.tagName.toLowerCase() == 'tr'){
+ break;
+ }
+ n = n.parentNode;
+ }
+ return (n != this.domNode) ? n : null;
+ },
+ getCellNode: function(inRowNode, inCellIndex){
+ var node = query("td[idx='" + inCellIndex + "']", inRowNode)[0];
+ if(node&&node.parentNode&&!domClass.contains(node.parentNode, "dojoxGridSummaryRow")){
+ return node;
+ }
+ },
+ decorateEvent: function(e){
+ e.rowNode = this.findRowTarget(e.target);
+ if(!e.rowNode){return false;}
+ e.rowIndex = domAttr.get(e.rowNode, 'dojoxTreeGridPath');
+ this.baseDecorateEvent(e);
+ e.cell = this.grid.getCell(e.cellIndex);
+ return true; // Boolean
+ }
+});
+
+return declare("dojox.grid._TreeView", _View, {
+ _contentBuilderClass: _TreeContentBuilder,
+ _onDndDrop: function(source, nodes, copy){
+ if(this.grid && this.grid.aggregator){
+ this.grid.aggregator.clearSubtotalCache();
+ }
+ this.inherited(arguments);
+ },
+ postCreate: function(){
+ this.inherited(arguments);
+ this.connect(this.grid, '_cleanupExpandoCache', '_cleanupExpandoCache');
+ },
+ _cleanupExpandoCache: function(index, identity, item){
+ if(index == -1){
+ return;
+ }
+ array.forEach(this.grid.layout.cells, function(cell){
+ if(typeof cell['openStates'] != 'undefined'){
+ if(identity in cell.openStates){
+ delete cell.openStates[identity];
+ }
+ }
+ });
+ if(typeof index == "string" && index.indexOf('/') > -1){
+ var path = new dojox.grid.TreePath(index, this.grid);
+ var ppath = path.parent();
+ while(ppath){
+ path = ppath;
+ ppath = path.parent();
+ }
+ var pitem = path.item();
+ if(!pitem){
+ return;
+ }
+ var idty = this.grid.store.getIdentity(pitem);
+ if(typeof this._expandos[idty] != 'undefined'){
+ for(var i in this._expandos[idty]){
+ var exp = this._expandos[idty][i];
+ if(exp){
+ exp.destroy();
+ }
+ delete this._expandos[idty][i];
+ }
+ delete this._expandos[idty];
+ }
+ }else{
+ for(var i in this._expandos){
+ if(typeof this._expandos[i] != 'undefined'){
+ for(var j in this._expandos[i]){
+ var exp = this._expandos[i][j];
+ if(exp){
+ exp.destroy();
+ }
+ }
+ }
+ }
+ this._expandos = {};
+ }
+ },
+ postMixInProperties: function(){
+ this.inherited(arguments);
+ this._expandos = {};
+ },
+ onBeforeRow: function(inRowIndex, cells){
+ // Save off our expando if we have one so we don't have to create it
+ // again
+ var g = this.grid;
+ if(g._by_idx && g._by_idx[inRowIndex] && g._by_idx[inRowIndex].idty){
+ var idty = g._by_idx[inRowIndex].idty;
+ this._expandos[idty] = this._expandos[idty] || {};
+ }
+ this.inherited(arguments);
+ },
+ onAfterRow: function(inRowIndex, cells, inRowNode){
+ array.forEach(query("span.dojoxGridExpando", inRowNode), function(n){
+ if(n && n.parentNode){
+ // Either create our expando or put the existing expando back
+ // into place
+ var tc = n.getAttribute("toggleClass");
+ var idty;
+ var expando;
+ var g = this.grid;
+ if(g._by_idx && g._by_idx[inRowIndex] && g._by_idx[inRowIndex].idty){
+ idty = g._by_idx[inRowIndex].idty;
+ expando = this._expandos[idty][tc];
+ }
+ if(expando){
+ domCtr.place(expando.domNode, n, "replace");
+ expando.itemId = n.getAttribute("itemId");
+ expando.cellIdx = parseInt(n.getAttribute("cellIdx"), 10);
+ if(isNaN(expando.cellIdx)){
+ expando.cellIdx = -1;
+ }
+ }else{
+ if(idty){
+ expando = parser.parse(n.parentNode)[0];
+ this._expandos[idty][tc] = expando;
+ }
+ }
+ if(expando && !expando.setRowNode(inRowIndex, inRowNode, this)){
+ expando.domNode.parentNode.removeChild(expando.domNode);
+ }
+ }
+ }, this);
+ var alt = false;
+ var self = this;
+ query("tr[dojoxTreeGridPath]", inRowNode).forEach(function(n){
+ domClass.toggle(n, "dojoxGridSubRowAlt", alt);
+ domAttr.set(n, "dojoxTreeGridBaseClasses", n.className);
+ alt = !alt;
+ self.grid.rows.styleRowNode(domAttr.get(n, 'dojoxTreeGridPath'), n);
+ });
+ this.inherited(arguments);
+ },
+ updateRowStyles: function(inRowIndex){
+ var rowNodes = query("tr[dojoxTreeGridPath='" + inRowIndex + "']", this.domNode);
+ if(rowNodes.length){
+ this.styleRowNode(inRowIndex, rowNodes[0]);
+ }
+ },
+ getCellNode: function(inRowIndex, inCellIndex){
+ var row = query("tr[dojoxTreeGridPath='" + inRowIndex + "']", this.domNode)[0];
+ if(row){
+ return this.content.getCellNode(row, inCellIndex);
+ }
+ },
+ destroy: function(){
+ this._cleanupExpandoCache();
+ this.inherited(arguments);
+ }
+});
+}); \ No newline at end of file
diff --git a/js/dojo-1.7.2/dojox/grid/_View.js b/js/dojo-1.7.2/dojox/grid/_View.js
new file mode 100644
index 0000000..f7d5937
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/_View.js
@@ -0,0 +1,854 @@
+//>>built
+require({cache:{
+'url:dojox/grid/resources/View.html':"<div class=\"dojoxGridView\" role=\"presentation\">\n\t<div class=\"dojoxGridHeader\" dojoAttachPoint=\"headerNode\" role=\"presentation\">\n\t\t<div dojoAttachPoint=\"headerNodeContainer\" style=\"width:9000em\" role=\"presentation\">\n\t\t\t<div dojoAttachPoint=\"headerContentNode\" role=\"row\"></div>\n\t\t</div>\n\t</div>\n\t<input type=\"checkbox\" class=\"dojoxGridHiddenFocus\" dojoAttachPoint=\"hiddenFocusNode\" role=\"presentation\" />\n\t<input type=\"checkbox\" class=\"dojoxGridHiddenFocus\" role=\"presentation\" />\n\t<div class=\"dojoxGridScrollbox\" dojoAttachPoint=\"scrollboxNode\" role=\"presentation\">\n\t\t<div class=\"dojoxGridContent\" dojoAttachPoint=\"contentNode\" hidefocus=\"hidefocus\" role=\"presentation\"></div>\n\t</div>\n</div>\n"}});
+define("dojox/grid/_View", [
+ "dojo",
+ "dijit/registry",
+ "../main",
+ "dojo/_base/declare",
+ "dojo/_base/array",
+ "dojo/_base/lang",
+ "dojo/_base/connect",
+ "dojo/_base/sniff",
+ "dojo/query",
+ "dojo/_base/window",
+ "dojo/text!./resources/View.html",
+ "dojo/dnd/Source",
+ "dijit/_Widget",
+ "dijit/_TemplatedMixin",
+ "dojox/html/metrics",
+ "./util",
+ "dojo/_base/html",
+ "./_Builder",
+ "dojo/dnd/Avatar",
+ "dojo/dnd/Manager"
+], function(dojo, dijit, dojox, declare, array, lang, connect, has, query,
+ win, template, Source, _Widget, _TemplatedMixin, metrics, util, html, _Builder, Avatar){
+
+ // a private function
+ var getStyleText = function(inNode, inStyleText){
+ return inNode.style.cssText == undefined ? inNode.getAttribute("style") : inNode.style.cssText;
+ };
+
+ // some public functions
+ var _View = declare('dojox.grid._View', [_Widget, _TemplatedMixin], {
+ // summary:
+ // A collection of grid columns. A grid is comprised of a set of views that stack horizontally.
+ // Grid creates views automatically based on grid's layout structure.
+ // Users should typically not need to access individual views directly.
+ //
+ // defaultWidth: String
+ // Default width of the view
+ defaultWidth: "18em",
+
+ // viewWidth: String
+ // Width for the view, in valid css unit
+ viewWidth: "",
+
+ templateString: template,
+
+ themeable: false,
+ classTag: 'dojoxGrid',
+ marginBottom: 0,
+ rowPad: 2,
+
+ // _togglingColumn: int
+ // Width of the column being toggled (-1 for none)
+ _togglingColumn: -1,
+
+ // _headerBuilderClass: Object
+ // The class to use for our header builder
+ _headerBuilderClass: _Builder._HeaderBuilder,
+
+ // _contentBuilderClass: Object
+ // The class to use for our content builder
+ _contentBuilderClass: _Builder._ContentBuilder,
+
+ postMixInProperties: function(){
+ this.rowNodes = {};
+ },
+
+ postCreate: function(){
+ this.connect(this.scrollboxNode,"onscroll","doscroll");
+ util.funnelEvents(this.contentNode, this, "doContentEvent", [ 'mouseover', 'mouseout', 'click', 'dblclick', 'contextmenu', 'mousedown' ]);
+ util.funnelEvents(this.headerNode, this, "doHeaderEvent", [ 'dblclick', 'mouseover', 'mouseout', 'mousemove', 'mousedown', 'click', 'contextmenu' ]);
+ this.content = new this._contentBuilderClass(this);
+ this.header = new this._headerBuilderClass(this);
+ //BiDi: in RTL case, style width='9000em' causes scrolling problem in head node
+ if(!this.grid.isLeftToRight()){
+ this.headerNodeContainer.style.width = "";
+ }
+ },
+
+ destroy: function(){
+ html.destroy(this.headerNode);
+ delete this.headerNode;
+ for(var i in this.rowNodes){
+ this._cleanupRowWidgets(this.rowNodes[i]);
+ html.destroy(this.rowNodes[i]);
+ }
+ this.rowNodes = {};
+ if(this.source){
+ this.source.destroy();
+ }
+ this.inherited(arguments);
+ },
+
+ // focus
+ focus: function(){
+ if(has("ie") || has("webkit") || has("opera")){
+ this.hiddenFocusNode.focus();
+ }else{
+ this.scrollboxNode.focus();
+ }
+ },
+
+ setStructure: function(inStructure){
+ var vs = (this.structure = inStructure);
+ // FIXME: similar logic is duplicated in layout
+ if(vs.width && !isNaN(vs.width)){
+ this.viewWidth = vs.width + 'em';
+ }else{
+ this.viewWidth = vs.width || (vs.noscroll ? 'auto' : this.viewWidth); //|| this.defaultWidth;
+ }
+ this._onBeforeRow = vs.onBeforeRow||function(){};
+ this._onAfterRow = vs.onAfterRow||function(){};
+ this.noscroll = vs.noscroll;
+ if(this.noscroll){
+ this.scrollboxNode.style.overflow = "hidden";
+ }
+ this.simpleStructure = Boolean(vs.cells.length == 1);
+ // bookkeeping
+ this.testFlexCells();
+ // accomodate new structure
+ this.updateStructure();
+ },
+
+ _cleanupRowWidgets: function(inRowNode){
+ // Summary:
+ // Cleans up the widgets for the given row node so that
+ // we can reattach them if needed
+ if(inRowNode){
+ array.forEach(query("[widgetId]", inRowNode).map(dijit.byNode), function(w){
+ if(w._destroyOnRemove){
+ w.destroy();
+ delete w;
+ }else if(w.domNode && w.domNode.parentNode){
+ w.domNode.parentNode.removeChild(w.domNode);
+ }
+ });
+ }
+ },
+
+ onBeforeRow: function(inRowIndex, cells){
+ this._onBeforeRow(inRowIndex, cells);
+ if(inRowIndex >= 0){
+ this._cleanupRowWidgets(this.getRowNode(inRowIndex));
+ }
+ },
+
+ onAfterRow: function(inRowIndex, cells, inRowNode){
+ this._onAfterRow(inRowIndex, cells, inRowNode);
+ var g = this.grid;
+ array.forEach(query(".dojoxGridStubNode", inRowNode), function(n){
+ if(n && n.parentNode){
+ var lw = n.getAttribute("linkWidget");
+ var cellIdx = window.parseInt(html.attr(n, "cellIdx"), 10);
+ var cellDef = g.getCell(cellIdx);
+ var w = dijit.byId(lw);
+ if(w){
+ n.parentNode.replaceChild(w.domNode, n);
+ if(!w._started){
+ w.startup();
+ }
+ dojo.destroy(n);
+ }else{
+ n.innerHTML = "";
+ }
+ }
+ }, this);
+ },
+
+ testFlexCells: function(){
+ // FIXME: cheater, this function does double duty as initializer and tester
+ this.flexCells = false;
+ for(var j=0, row; (row=this.structure.cells[j]); j++){
+ for(var i=0, cell; (cell=row[i]); i++){
+ cell.view = this;
+ this.flexCells = this.flexCells || cell.isFlex();
+ }
+ }
+ return this.flexCells;
+ },
+
+ updateStructure: function(){
+ // header builder needs to update table map
+ this.header.update();
+ // content builder needs to update markup cache
+ this.content.update();
+ },
+
+ getScrollbarWidth: function(){
+ var hasScrollSpace = this.hasVScrollbar();
+ var overflow = html.style(this.scrollboxNode, "overflow");
+ if(this.noscroll || !overflow || overflow == "hidden"){
+ hasScrollSpace = false;
+ }else if(overflow == "scroll"){
+ hasScrollSpace = true;
+ }
+ return (hasScrollSpace ? metrics.getScrollbar().w : 0); // Integer
+ },
+
+ getColumnsWidth: function(){
+ var h = this.headerContentNode;
+ return h && h.firstChild ? h.firstChild.offsetWidth : 0; // Integer
+ },
+
+ setColumnsWidth: function(width){
+ this.headerContentNode.firstChild.style.width = width + 'px';
+ if(this.viewWidth){
+ this.viewWidth = width + 'px';
+ }
+ },
+
+ getWidth: function(){
+ return this.viewWidth || (this.getColumnsWidth()+this.getScrollbarWidth()) +'px'; // String
+ },
+
+ getContentWidth: function(){
+ return Math.max(0, html._getContentBox(this.domNode).w - this.getScrollbarWidth()) + 'px'; // String
+ },
+
+ render: function(){
+ this.scrollboxNode.style.height = '';
+ this.renderHeader();
+ if(this._togglingColumn >= 0){
+ this.setColumnsWidth(this.getColumnsWidth() - this._togglingColumn);
+ this._togglingColumn = -1;
+ }
+ var cells = this.grid.layout.cells;
+ var getSibling = lang.hitch(this, function(node, before){
+ !this.grid.isLeftToRight() && (before = !before);
+ var inc = before?-1:1;
+ var idx = this.header.getCellNodeIndex(node) + inc;
+ var cell = cells[idx];
+ while(cell && cell.getHeaderNode() && cell.getHeaderNode().style.display == "none"){
+ idx += inc;
+ cell = cells[idx];
+ }
+ if(cell){
+ return cell.getHeaderNode();
+ }
+ return null;
+ });
+ if(this.grid.columnReordering && this.simpleStructure){
+ if(this.source){
+ this.source.destroy();
+ }
+
+ // Create the top and bottom markers
+ var bottomMarkerId = "dojoxGrid_bottomMarker";
+ var topMarkerId = "dojoxGrid_topMarker";
+ if(this.bottomMarker){
+ html.destroy(this.bottomMarker);
+ }
+ this.bottomMarker = html.byId(bottomMarkerId);
+ if(this.topMarker){
+ html.destroy(this.topMarker);
+ }
+ this.topMarker = html.byId(topMarkerId);
+ if (!this.bottomMarker) {
+ this.bottomMarker = html.create("div", {
+ "id": bottomMarkerId,
+ "class": "dojoxGridColPlaceBottom"
+ }, win.body());
+ this._hide(this.bottomMarker);
+
+
+ this.topMarker = html.create("div", {
+ "id": topMarkerId,
+ "class": "dojoxGridColPlaceTop"
+ }, win.body());
+ this._hide(this.topMarker);
+ }
+ this.arrowDim = html.contentBox(this.bottomMarker);
+
+ var headerHeight = html.contentBox(this.headerContentNode.firstChild.rows[0]).h;
+
+ this.source = new Source(this.headerContentNode.firstChild.rows[0], {
+ horizontal: true,
+ accept: [ "gridColumn_" + this.grid.id ],
+ viewIndex: this.index,
+ generateText: false,
+ onMouseDown: lang.hitch(this, function(e){
+ this.header.decorateEvent(e);
+ if((this.header.overRightResizeArea(e) || this.header.overLeftResizeArea(e)) &&
+ this.header.canResize(e) && !this.header.moveable){
+ this.header.beginColumnResize(e);
+ }else{
+ if(this.grid.headerMenu){
+ this.grid.headerMenu.onCancel(true);
+ }
+ // IE reports a left click as 1, where everything else reports 0
+ if(e.button === (has("ie") < 9 ? 1 : 0)){
+ Source.prototype.onMouseDown.call(this.source, e);
+ }
+ }
+ }),
+ onMouseOver: lang.hitch(this, function(e){
+ var src = this.source;
+ if(src._getChildByEvent(e)){
+ Source.prototype.onMouseOver.apply(src, arguments);
+ }
+ }),
+ _markTargetAnchor: lang.hitch(this, function(before){
+ var src = this.source;
+ if(src.current == src.targetAnchor && src.before == before){ return; }
+ if(src.targetAnchor && getSibling(src.targetAnchor, src.before)){
+ src._removeItemClass(getSibling(src.targetAnchor, src.before), src.before ? "After" : "Before");
+ }
+ Source.prototype._markTargetAnchor.call(src, before);
+
+ var target = before ? src.targetAnchor : getSibling(src.targetAnchor, src.before);
+ var endAdd = 0;
+
+ if (!target) {
+ target = src.targetAnchor;
+ endAdd = html.contentBox(target).w + this.arrowDim.w/2 + 2;
+ }
+
+ var pos = html.position(target, true);
+ var left = Math.floor(pos.x - this.arrowDim.w/2 + endAdd);
+
+ html.style(this.bottomMarker, "visibility", "visible");
+ html.style(this.topMarker, "visibility", "visible");
+ html.style(this.bottomMarker, {
+ "left": left + "px",
+ "top" : (headerHeight + pos.y) + "px"
+ });
+
+ html.style(this.topMarker, {
+ "left": left + "px",
+ "top" : (pos.y - this.arrowDim.h) + "px"
+ });
+
+ if(src.targetAnchor && getSibling(src.targetAnchor, src.before)){
+ src._addItemClass(getSibling(src.targetAnchor, src.before), src.before ? "After" : "Before");
+ }
+ }),
+ _unmarkTargetAnchor: lang.hitch(this, function(){
+ var src = this.source;
+ if(!src.targetAnchor){ return; }
+ if(src.targetAnchor && getSibling(src.targetAnchor, src.before)){
+ src._removeItemClass(getSibling(src.targetAnchor, src.before), src.before ? "After" : "Before");
+ }
+ this._hide(this.bottomMarker);
+ this._hide(this.topMarker);
+ Source.prototype._unmarkTargetAnchor.call(src);
+ }),
+ destroy: lang.hitch(this, function(){
+ connect.disconnect(this._source_conn);
+ connect.unsubscribe(this._source_sub);
+ Source.prototype.destroy.call(this.source);
+ if(this.bottomMarker){
+ html.destroy(this.bottomMarker);
+ delete this.bottomMarker;
+ }
+ if(this.topMarker){
+ html.destroy(this.topMarker);
+ delete this.topMarker;
+ }
+ }),
+ onDndCancel: lang.hitch(this, function(){
+ Source.prototype.onDndCancel.call(this.source);
+ this._hide(this.bottomMarker);
+ this._hide(this.topMarker);
+ })
+ });
+
+ this._source_conn = connect.connect(this.source, "onDndDrop", this, "_onDndDrop");
+ this._source_sub = connect.subscribe("/dnd/drop/before", this, "_onDndDropBefore");
+ this.source.startup();
+ }
+ },
+
+ _hide: function(node){
+ html.style(node, {
+ top: "-10000px",
+ "visibility": "hidden"
+ });
+ },
+
+ _onDndDropBefore: function(source, nodes, copy){
+ if(dojo.dnd.manager().target !== this.source){
+ return;
+ }
+ this.source._targetNode = this.source.targetAnchor;
+ this.source._beforeTarget = this.source.before;
+ var views = this.grid.views.views;
+ var srcView = views[source.viewIndex];
+ var tgtView = views[this.index];
+ if(tgtView != srcView){
+ srcView.convertColPctToFixed();
+ tgtView.convertColPctToFixed();
+ }
+ },
+
+ _onDndDrop: function(source, nodes, copy){
+ if(dojo.dnd.manager().target !== this.source){
+ if(dojo.dnd.manager().source === this.source){
+ this._removingColumn = true;
+ }
+ return;
+ }
+ this._hide(this.bottomMarker);
+ this._hide(this.topMarker);
+
+ var getIdx = function(n){
+ return n ? html.attr(n, "idx") : null;
+ };
+ var w = html.marginBox(nodes[0]).w;
+ if(source.viewIndex !== this.index){
+ var views = this.grid.views.views;
+ var srcView = views[source.viewIndex];
+ var tgtView = views[this.index];
+ if(srcView.viewWidth && srcView.viewWidth != "auto"){
+ srcView.setColumnsWidth(srcView.getColumnsWidth() - w);
+ }
+ if(tgtView.viewWidth && tgtView.viewWidth != "auto"){
+ tgtView.setColumnsWidth(tgtView.getColumnsWidth());
+ }
+ }
+ var stn = this.source._targetNode;
+ var stb = this.source._beforeTarget;
+ !this.grid.isLeftToRight() && (stb = !stb);
+ var layout = this.grid.layout;
+ var idx = this.index;
+ delete this.source._targetNode;
+ delete this.source._beforeTarget;
+
+ layout.moveColumn(
+ source.viewIndex,
+ idx,
+ getIdx(nodes[0]),
+ getIdx(stn),
+ stb);
+ },
+
+ renderHeader: function(){
+ this.headerContentNode.innerHTML = this.header.generateHtml(this._getHeaderContent);
+ if(this.flexCells){
+ this.contentWidth = this.getContentWidth();
+ this.headerContentNode.firstChild.style.width = this.contentWidth;
+ }
+ util.fire(this, "onAfterRow", [-1, this.structure.cells, this.headerContentNode]);
+ },
+
+ // note: not called in 'view' context
+ _getHeaderContent: function(inCell){
+ var n = inCell.name || inCell.grid.getCellName(inCell);
+ if(/^\s+$/.test(n)){
+ n = '&nbsp;'//otherwise arrow styles will be messed up
+ }
+ var ret = [ '<div class="dojoxGridSortNode' ];
+
+ if(inCell.index != inCell.grid.getSortIndex()){
+ ret.push('">');
+ }else{
+ ret = ret.concat([ ' ',
+ inCell.grid.sortInfo > 0 ? 'dojoxGridSortUp' : 'dojoxGridSortDown',
+ '"><div class="dojoxGridArrowButtonChar">',
+ inCell.grid.sortInfo > 0 ? '&#9650;' : '&#9660;',
+ '</div><div class="dojoxGridArrowButtonNode" role="presentation"></div>',
+ '<div class="dojoxGridColCaption">']);
+ }
+ ret = ret.concat([n, '</div></div>']);
+ return ret.join('');
+ },
+
+ resize: function(){
+ this.adaptHeight();
+ this.adaptWidth();
+ },
+
+ hasHScrollbar: function(reset){
+ var hadScroll = this._hasHScroll||false;
+ if(this._hasHScroll == undefined || reset){
+ if(this.noscroll){
+ this._hasHScroll = false;
+ }else{
+ var style = html.style(this.scrollboxNode, "overflow");
+ if(style == "hidden"){
+ this._hasHScroll = false;
+ }else if(style == "scroll"){
+ this._hasHScroll = true;
+ }else{
+ this._hasHScroll = (this.scrollboxNode.offsetWidth - this.getScrollbarWidth() < this.contentNode.offsetWidth );
+ }
+ }
+ }
+ if(hadScroll !== this._hasHScroll){
+ this.grid.update();
+ }
+ return this._hasHScroll; // Boolean
+ },
+
+ hasVScrollbar: function(reset){
+ var hadScroll = this._hasVScroll||false;
+ if(this._hasVScroll == undefined || reset){
+ if(this.noscroll){
+ this._hasVScroll = false;
+ }else{
+ var style = html.style(this.scrollboxNode, "overflow");
+ if(style == "hidden"){
+ this._hasVScroll = false;
+ }else if(style == "scroll"){
+ this._hasVScroll = true;
+ }else{
+ this._hasVScroll = (this.scrollboxNode.scrollHeight > this.scrollboxNode.clientHeight);
+ }
+ }
+ }
+ if(hadScroll !== this._hasVScroll){
+ this.grid.update();
+ }
+ return this._hasVScroll; // Boolean
+ },
+
+ convertColPctToFixed: function(){
+ // Fix any percentage widths to be pixel values
+ var hasPct = false;
+ this.grid.initialWidth = "";
+ var cellNodes = query("th", this.headerContentNode);
+ var fixedWidths = array.map(cellNodes, function(c, vIdx){
+ var w = c.style.width;
+ html.attr(c, "vIdx", vIdx);
+ if(w && w.slice(-1) == "%"){
+ hasPct = true;
+ }else if(w && w.slice(-2) == "px"){
+ return window.parseInt(w, 10);
+ }
+ return html.contentBox(c).w;
+ });
+ if(hasPct){
+ array.forEach(this.grid.layout.cells, function(cell, idx){
+ if(cell.view == this){
+ var cellNode = cell.view.getHeaderCellNode(cell.index);
+ if(cellNode && html.hasAttr(cellNode, "vIdx")){
+ var vIdx = window.parseInt(html.attr(cellNode, "vIdx"));
+ this.setColWidth(idx, fixedWidths[vIdx]);
+ html.removeAttr(cellNode, "vIdx");
+ }
+ }
+ }, this);
+ return true;
+ }
+ return false;
+ },
+
+ adaptHeight: function(minusScroll){
+ if(!this.grid._autoHeight){
+ var h = (this.domNode.style.height && parseInt(this.domNode.style.height.replace(/px/,''), 10)) || this.domNode.clientHeight;
+ var self = this;
+ var checkOtherViewScrollers = function(){
+ var v;
+ for(var i in self.grid.views.views){
+ v = self.grid.views.views[i];
+ if(v !== self && v.hasHScrollbar()){
+ return true;
+ }
+ }
+ return false;
+ };
+ if(minusScroll || (this.noscroll && checkOtherViewScrollers())){
+ h -= metrics.getScrollbar().h;
+ }
+ util.setStyleHeightPx(this.scrollboxNode, h);
+ }
+ this.hasVScrollbar(true);
+ },
+
+ adaptWidth: function(){
+ if(this.flexCells){
+ // the view content width
+ this.contentWidth = this.getContentWidth();
+ this.headerContentNode.firstChild.style.width = this.contentWidth;
+ }
+ // FIXME: it should be easier to get w from this.scrollboxNode.clientWidth,
+ // but clientWidth seemingly does not include scrollbar width in some cases
+ var w = this.scrollboxNode.offsetWidth - this.getScrollbarWidth();
+ if(!this._removingColumn){
+ w = Math.max(w, this.getColumnsWidth()) + 'px';
+ }else{
+ w = Math.min(w, this.getColumnsWidth()) + 'px';
+ this._removingColumn = false;
+ }
+ var cn = this.contentNode;
+ cn.style.width = w;
+ this.hasHScrollbar(true);
+ },
+
+ setSize: function(w, h){
+ var ds = this.domNode.style;
+ var hs = this.headerNode.style;
+
+ if(w){
+ ds.width = w;
+ hs.width = w;
+ }
+ ds.height = (h >= 0 ? h + 'px' : '');
+ },
+
+ renderRow: function(inRowIndex){
+ var rowNode = this.createRowNode(inRowIndex);
+ this.buildRow(inRowIndex, rowNode);
+ //this.grid.edit.restore(this, inRowIndex);
+ return rowNode;
+ },
+
+ createRowNode: function(inRowIndex){
+ var node = document.createElement("div");
+ node.className = this.classTag + 'Row';
+ if (this instanceof dojox.grid._RowSelector){
+ html.attr(node,"role","presentation");
+ }else{
+ html.attr(node,"role","row");
+ if (this.grid.selectionMode != "none") {
+ node.setAttribute("aria-selected", "false"); //rows can be selected so add aria-selected prop
+ }
+ }
+ node[util.gridViewTag] = this.id;
+ node[util.rowIndexTag] = inRowIndex;
+ this.rowNodes[inRowIndex] = node;
+ return node;
+ },
+
+ buildRow: function(inRowIndex, inRowNode){
+
+ this.buildRowContent(inRowIndex, inRowNode);
+
+ this.styleRow(inRowIndex, inRowNode);
+
+
+ },
+
+ buildRowContent: function(inRowIndex, inRowNode){
+ inRowNode.innerHTML = this.content.generateHtml(inRowIndex, inRowIndex);
+ if(this.flexCells && this.contentWidth){
+ // FIXME: accessing firstChild here breaks encapsulation
+ inRowNode.firstChild.style.width = this.contentWidth;
+ }
+ util.fire(this, "onAfterRow", [inRowIndex, this.structure.cells, inRowNode]);
+ },
+
+ rowRemoved:function(inRowIndex){
+ if(inRowIndex >= 0){
+ this._cleanupRowWidgets(this.getRowNode(inRowIndex));
+ }
+ this.grid.edit.save(this, inRowIndex);
+ delete this.rowNodes[inRowIndex];
+ },
+
+ getRowNode: function(inRowIndex){
+ return this.rowNodes[inRowIndex];
+ },
+
+ getCellNode: function(inRowIndex, inCellIndex){
+ var row = this.getRowNode(inRowIndex);
+ if(row){
+ return this.content.getCellNode(row, inCellIndex);
+ }
+ },
+
+ getHeaderCellNode: function(inCellIndex){
+ if(this.headerContentNode){
+ return this.header.getCellNode(this.headerContentNode, inCellIndex);
+ }
+ },
+
+ // styling
+ styleRow: function(inRowIndex, inRowNode){
+ inRowNode._style = getStyleText(inRowNode);
+ this.styleRowNode(inRowIndex, inRowNode);
+ },
+
+ styleRowNode: function(inRowIndex, inRowNode){
+ if(inRowNode){
+ this.doStyleRowNode(inRowIndex, inRowNode);
+ }
+ },
+
+ doStyleRowNode: function(inRowIndex, inRowNode){
+ this.grid.styleRowNode(inRowIndex, inRowNode);
+ },
+
+ // updating
+ updateRow: function(inRowIndex){
+ var rowNode = this.getRowNode(inRowIndex);
+ if(rowNode){
+ rowNode.style.height = '';
+ this.buildRow(inRowIndex, rowNode);
+ }
+ return rowNode;
+ },
+
+ updateRowStyles: function(inRowIndex){
+ this.styleRowNode(inRowIndex, this.getRowNode(inRowIndex));
+ },
+
+ // scrolling
+ lastTop: 0,
+ firstScroll:0,
+
+ doscroll: function(inEvent){
+ //var s = dojo.marginBox(this.headerContentNode.firstChild);
+ var isLtr = this.grid.isLeftToRight();
+ if(this.firstScroll < 2){
+ if((!isLtr && this.firstScroll == 1) || (isLtr && this.firstScroll === 0)){
+ var s = html.marginBox(this.headerNodeContainer);
+ if(has("ie")){
+ this.headerNodeContainer.style.width = s.w + this.getScrollbarWidth() + 'px';
+ }else if(has("mozilla")){
+ //TODO currently only for FF, not sure for safari and opera
+ this.headerNodeContainer.style.width = s.w - this.getScrollbarWidth() + 'px';
+ //this.headerNodeContainer.style.width = s.w + 'px';
+ //set scroll to right in FF
+ this.scrollboxNode.scrollLeft = isLtr ?
+ this.scrollboxNode.clientWidth - this.scrollboxNode.scrollWidth :
+ this.scrollboxNode.scrollWidth - this.scrollboxNode.clientWidth;
+ }
+ }
+ this.firstScroll++;
+ }
+ this.headerNode.scrollLeft = this.scrollboxNode.scrollLeft;
+ // 'lastTop' is a semaphore to prevent feedback-loop with setScrollTop below
+ var top = this.scrollboxNode.scrollTop;
+ if(top !== this.lastTop){
+ this.grid.scrollTo(top);
+ }
+ },
+
+ setScrollTop: function(inTop){
+ // 'lastTop' is a semaphore to prevent feedback-loop with doScroll above
+ this.lastTop = inTop;
+ this.scrollboxNode.scrollTop = inTop;
+ return this.scrollboxNode.scrollTop;
+ },
+
+ // event handlers (direct from DOM)
+ doContentEvent: function(e){
+ if(this.content.decorateEvent(e)){
+ this.grid.onContentEvent(e);
+ }
+ },
+
+ doHeaderEvent: function(e){
+ if(this.header.decorateEvent(e)){
+ this.grid.onHeaderEvent(e);
+ }
+ },
+
+ // event dispatch(from Grid)
+ dispatchContentEvent: function(e){
+ return this.content.dispatchEvent(e);
+ },
+
+ dispatchHeaderEvent: function(e){
+ return this.header.dispatchEvent(e);
+ },
+
+ // column resizing
+ setColWidth: function(inIndex, inWidth){
+ this.grid.setCellWidth(inIndex, inWidth + 'px');
+ },
+
+ update: function(){
+ if(!this.domNode){
+ return;
+ }
+ this.content.update();
+ this.grid.update();
+ //get scroll after update or scroll left setting goes wrong on IE.
+ //See trac: #8040
+ var left = this.scrollboxNode.scrollLeft;
+ this.scrollboxNode.scrollLeft = left;
+ this.headerNode.scrollLeft = left;
+ }
+ });
+
+ var _GridAvatar = declare("dojox.grid._GridAvatar", Avatar, {
+ construct: function(){
+ var dd = win.doc;
+
+ var a = dd.createElement("table");
+ a.cellPadding = a.cellSpacing = "0";
+ a.className = "dojoxGridDndAvatar";
+ a.style.position = "absolute";
+ a.style.zIndex = 1999;
+ a.style.margin = "0px"; // to avoid dojo.marginBox() problems with table's margins
+ var b = dd.createElement("tbody");
+ var tr = dd.createElement("tr");
+ var td = dd.createElement("td");
+ var img = dd.createElement("td");
+ tr.className = "dojoxGridDndAvatarItem";
+ img.className = "dojoxGridDndAvatarItemImage";
+ img.style.width = "16px";
+ var source = this.manager.source, node;
+ if(source.creator){
+ // create an avatar representation of the node
+ node = source._normalizedCreator(source.getItem(this.manager.nodes[0].id).data, "avatar").node;
+ }else{
+ // or just clone the node and hope it works
+ node = this.manager.nodes[0].cloneNode(true);
+ var table, tbody;
+ if(node.tagName.toLowerCase() == "tr"){
+ // insert extra table nodes
+ table = dd.createElement("table");
+ tbody = dd.createElement("tbody");
+ tbody.appendChild(node);
+ table.appendChild(tbody);
+ node = table;
+ }else if(node.tagName.toLowerCase() == "th"){
+ // insert extra table nodes
+ table = dd.createElement("table");
+ tbody = dd.createElement("tbody");
+ var r = dd.createElement("tr");
+ table.cellPadding = table.cellSpacing = "0";
+ r.appendChild(node);
+ tbody.appendChild(r);
+ table.appendChild(tbody);
+ node = table;
+ }
+ }
+ node.id = "";
+ td.appendChild(node);
+ tr.appendChild(img);
+ tr.appendChild(td);
+ html.style(tr, "opacity", 0.9);
+ b.appendChild(tr);
+
+ a.appendChild(b);
+ this.node = a;
+
+ var m = dojo.dnd.manager();
+ this.oldOffsetY = m.OFFSET_Y;
+ m.OFFSET_Y = 1;
+ },
+ destroy: function(){
+ dojo.dnd.manager().OFFSET_Y = this.oldOffsetY;
+ this.inherited(arguments);
+ }
+ });
+
+ var oldMakeAvatar = dojo.dnd.manager().makeAvatar;
+ dojo.dnd.manager().makeAvatar = function(){
+ var src = this.source;
+ if(src.viewIndex !== undefined && !html.hasClass(win.body(),"dijit_a11y")){
+ return new _GridAvatar(this);
+ }
+ return oldMakeAvatar.call(dojo.dnd.manager());
+ };
+
+ return _View;
+
+}); \ No newline at end of file
diff --git a/js/dojo-1.7.2/dojox/grid/_ViewManager.js b/js/dojo-1.7.2/dojox/grid/_ViewManager.js
new file mode 100644
index 0000000..b9e06b7
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/_ViewManager.js
@@ -0,0 +1,307 @@
+//>>built
+define("dojox/grid/_ViewManager", [
+ "dojo/_base/declare",
+ "dojo/_base/sniff",
+ "dojo/dom-class"
+], function(declare, has, domClass){
+
+return declare('dojox.grid._ViewManager', null, {
+ // summary:
+ // A collection of grid views. Owned by grid and used internally for managing grid views.
+ // description:
+ // Grid creates views automatically based on grid's layout structure.
+ // Users should typically not need to access individual views or the views collection directly.
+ constructor: function(inGrid){
+ this.grid = inGrid;
+ },
+
+ defaultWidth: 200,
+
+ views: [],
+
+ // operations
+ resize: function(){
+ this.onEach("resize");
+ },
+
+ render: function(){
+ this.onEach("render");
+ },
+
+ // views
+ addView: function(inView){
+ inView.idx = this.views.length;
+ this.views.push(inView);
+ },
+
+ destroyViews: function(){
+ for(var i=0, v; v=this.views[i]; i++){
+ v.destroy();
+ }
+ this.views = [];
+ },
+
+ getContentNodes: function(){
+ var nodes = [];
+ for(var i=0, v; v=this.views[i]; i++){
+ nodes.push(v.contentNode);
+ }
+ return nodes;
+ },
+
+ forEach: function(inCallback){
+ for(var i=0, v; v=this.views[i]; i++){
+ inCallback(v, i);
+ }
+ },
+
+ onEach: function(inMethod, inArgs){
+ inArgs = inArgs || [];
+ for(var i=0, v; v=this.views[i]; i++){
+ if(inMethod in v){
+ v[inMethod].apply(v, inArgs);
+ }
+ }
+ },
+
+ // layout
+ normalizeHeaderNodeHeight: function(){
+ var rowNodes = [];
+ for(var i=0, v; (v=this.views[i]); i++){
+ if(v.headerContentNode.firstChild){
+ rowNodes.push(v.headerContentNode);
+ }
+ }
+ this.normalizeRowNodeHeights(rowNodes);
+ },
+
+ normalizeRowNodeHeights: function(inRowNodes){
+ var h = 0;
+ var currHeights = [];
+ if(this.grid.rowHeight){
+ h = this.grid.rowHeight;
+ }else{
+ if(inRowNodes.length <= 1){
+ // no need to normalize if we are the only one...
+ return;
+ }
+ for(var i=0, n; (n=inRowNodes[i]); i++){
+ // We only care about the height - so don't use marginBox. This
+ // depends on the container not having any margin (which it shouldn't)
+ // Also - we only look up the height if the cell doesn't have the
+ // dojoxGridNonNormalizedCell class (like for row selectors)
+ if(!domClass.contains(n, "dojoxGridNonNormalizedCell")){
+ currHeights[i] = n.firstChild.offsetHeight;
+ h = Math.max(h, currHeights[i]);
+ }
+ }
+ h = (h >= 0 ? h : 0);
+
+ //Work around odd FF3 rendering bug: #8864.
+ //A one px increase fixes FireFox 3's rounding bug for fractional font sizes.
+ if((has("mozilla") || has("ie") > 8 ) && h){h++;}
+ }
+ for(i=0; (n=inRowNodes[i]); i++){
+ if(currHeights[i] != h){
+ n.firstChild.style.height = h + "px";
+ }
+ }
+ },
+
+ resetHeaderNodeHeight: function(){
+ for(var i=0, v, n; (v=this.views[i]); i++){
+ n = v.headerContentNode.firstChild;
+ if(n){
+ n.style.height = "";
+ }
+ }
+ },
+
+ renormalizeRow: function(inRowIndex){
+ var rowNodes = [];
+ for(var i=0, v, n; (v=this.views[i])&&(n=v.getRowNode(inRowIndex)); i++){
+ n.firstChild.style.height = '';
+ rowNodes.push(n);
+ }
+ this.normalizeRowNodeHeights(rowNodes);
+ },
+
+ getViewWidth: function(inIndex){
+ return this.views[inIndex].getWidth() || this.defaultWidth;
+ },
+
+ // must be called after view widths are properly set or height can be miscalculated
+ // if there are flex columns
+ measureHeader: function(){
+ // need to reset view header heights so they are properly measured.
+ this.resetHeaderNodeHeight();
+ this.forEach(function(inView){
+ inView.headerContentNode.style.height = '';
+ });
+ var h = 0;
+ // calculate maximum view header height
+ this.forEach(function(inView){
+ h = Math.max(inView.headerNode.offsetHeight, h);
+ });
+ return h;
+ },
+
+ measureContent: function(){
+ var h = 0;
+ this.forEach(function(inView){
+ h = Math.max(inView.domNode.offsetHeight, h);
+ });
+ return h;
+ },
+
+ findClient: function(inAutoWidth){
+ // try to use user defined client
+ var c = this.grid.elasticView || -1;
+ // attempt to find implicit client
+ if(c < 0){
+ for(var i=1, v; (v=this.views[i]); i++){
+ if(v.viewWidth){
+ for(i=1; (v=this.views[i]); i++){
+ if(!v.viewWidth){
+ c = i;
+ break;
+ }
+ }
+ break;
+ }
+ }
+ }
+ // client is in the middle by default
+ if(c < 0){
+ c = Math.floor(this.views.length / 2);
+ }
+ return c;
+ },
+
+ arrange: function(l, w){
+ var i, v, vw, len = this.views.length, self = this;
+ // find the client
+ var c = (w <= 0 ? len : this.findClient());
+ // layout views
+ var setPosition = function(v, l){
+ var ds = v.domNode.style;
+ var hs = v.headerNode.style;
+
+ if(!self.grid.isLeftToRight()){
+ ds.right = l + 'px';
+ // fixed rtl, the scrollbar is on the right side in FF or WebKit
+ if (has("ff") < 4 || has("webkit")){
+ hs.right = l + v.getScrollbarWidth() + 'px';
+ hs.width = parseInt(hs.width, 10) - v.getScrollbarWidth() + 'px';
+ }else{
+ hs.right = l + 'px';
+ }
+ }else{
+ ds.left = l + 'px';
+ hs.left = l + 'px';
+ }
+ ds.top = 0 + 'px';
+ hs.top = 0;
+ };
+ // for views left of the client
+ //BiDi TODO: The left and right should not appear in BIDI environment. Should be replaced with
+ //leading and tailing concept.
+ for(i=0; (v=this.views[i])&&(i<c); i++){
+ // get width
+ vw = this.getViewWidth(i);
+ // process boxes
+ v.setSize(vw, 0);
+ setPosition(v, l);
+ if(v.headerContentNode && v.headerContentNode.firstChild){
+ vw = v.getColumnsWidth()+v.getScrollbarWidth();
+ }else{
+ vw = v.domNode.offsetWidth;
+ }
+ // update position
+ l += vw;
+ }
+ // next view (is the client, i++ == c)
+ i++;
+ // start from the right edge
+ var r = w;
+ // for views right of the client (iterated from the right)
+ for(var j=len-1; (v=this.views[j])&&(i<=j); j--){
+ // get width
+ vw = this.getViewWidth(j);
+ // set size
+ v.setSize(vw, 0);
+ // measure in pixels
+ vw = v.domNode.offsetWidth;
+ // update position
+ r -= vw;
+ // set position
+ setPosition(v, r);
+ }
+ if(c<len){
+ v = this.views[c];
+ // position the client box between left and right boxes
+ vw = Math.max(1, r-l);
+ // set size
+ v.setSize(vw + 'px', 0);
+ setPosition(v, l);
+ }
+ return l;
+ },
+
+ // rendering
+ renderRow: function(inRowIndex, inNodes, skipRenorm){
+ var rowNodes = [];
+ for(var i=0, v, n, rowNode; (v=this.views[i])&&(n=inNodes[i]); i++){
+ rowNode = v.renderRow(inRowIndex);
+ n.appendChild(rowNode);
+ rowNodes.push(rowNode);
+ }
+ if(!skipRenorm){
+ this.normalizeRowNodeHeights(rowNodes);
+ }
+ },
+
+ rowRemoved: function(inRowIndex){
+ this.onEach("rowRemoved", [ inRowIndex ]);
+ },
+
+ // updating
+ updateRow: function(inRowIndex, skipRenorm){
+ for(var i=0, v; v=this.views[i]; i++){
+ v.updateRow(inRowIndex);
+ }
+ if(!skipRenorm){
+ this.renormalizeRow(inRowIndex);
+ }
+ },
+
+ updateRowStyles: function(inRowIndex){
+ this.onEach("updateRowStyles", [ inRowIndex ]);
+ },
+
+ // scrolling
+ setScrollTop: function(inTop){
+ var top = inTop;
+ for(var i=0, v; v=this.views[i]; i++){
+ top = v.setScrollTop(inTop);
+ // Work around IE not firing scroll events that cause header offset
+ // issues to occur.
+ if(has("ie") && v.headerNode && v.scrollboxNode){
+ v.headerNode.scrollLeft = v.scrollboxNode.scrollLeft;
+ }
+ }
+ return top;
+ //this.onEach("setScrollTop", [ inTop ]);
+ },
+
+ getFirstScrollingView: function(){
+ // summary: Returns the first grid view with a scroll bar
+ for(var i=0, v; (v=this.views[i]); i++){
+ if(v.hasHScrollbar() || v.hasVScrollbar()){
+ return v;
+ }
+ }
+ return null;
+ }
+});
+}); \ No newline at end of file
diff --git a/js/dojo-1.7.2/dojox/grid/cells.js b/js/dojo-1.7.2/dojox/grid/cells.js
new file mode 100644
index 0000000..2c2a502
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/cells.js
@@ -0,0 +1,4 @@
+//>>built
+define("dojox/grid/cells", ["../main", "./cells/_base"], function(dojox){
+ return dojox.grid.cells;
+}); \ No newline at end of file
diff --git a/js/dojo-1.7.2/dojox/grid/cells/_base.js b/js/dojo-1.7.2/dojox/grid/cells/_base.js
new file mode 100644
index 0000000..a1731ef
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/cells/_base.js
@@ -0,0 +1,477 @@
+//>>built
+define("dojox/grid/cells/_base", [
+ "dojo/_base/kernel",
+ "dojo/_base/declare",
+ "dojo/_base/lang",
+ "dojo/_base/event",
+ "dojo/_base/connect",
+ "dojo/_base/array",
+ "dojo/_base/sniff",
+ "dojo/dom",
+ "dojo/dom-attr",
+ "dojo/dom-construct",
+ "dijit/_Widget",
+ "../util"
+], function(dojo, declare, lang, event, connect, array, has, dom, domAttr, domConstruct, _Widget, util){
+
+ var _DeferredTextWidget = declare("dojox.grid._DeferredTextWidget", _Widget, {
+ deferred: null,
+ _destroyOnRemove: true,
+ postCreate: function(){
+ if(this.deferred){
+ this.deferred.addBoth(lang.hitch(this, function(text){
+ if(this.domNode){
+ this.domNode.innerHTML = text;
+ }
+ }));
+ }
+ }
+ });
+
+ var focusSelectNode = function(inNode){
+ try{
+ util.fire(inNode, "focus");
+ util.fire(inNode, "select");
+ }catch(e){// IE sux bad
+ }
+ };
+
+ var whenIdle = function(/*inContext, inMethod, args ...*/){
+ setTimeout(lang.hitch.apply(dojo, arguments), 0);
+ };
+
+ var BaseCell = declare("dojox.grid.cells._Base", null, {
+ // summary:
+ // Respresents a grid cell and contains information about column options and methods
+ // for retrieving cell related information.
+ // Each column in a grid layout has a cell object and most events and many methods
+ // provide access to these objects.
+ styles: '',
+ classes: '',
+ editable: false,
+ alwaysEditing: false,
+ formatter: null,
+ defaultValue: '...',
+ value: null,
+ hidden: false,
+ noresize: false,
+ draggable: true,
+ //private
+ _valueProp: "value",
+ _formatPending: false,
+
+ constructor: function(inProps){
+ this._props = inProps || {};
+ lang.mixin(this, inProps);
+ if(this.draggable === undefined){
+ this.draggable = true;
+ }
+ },
+
+ _defaultFormat: function(inValue, callArgs){
+ var s = this.grid.formatterScope || this;
+ var f = this.formatter;
+ if(f && s && typeof f == "string"){
+ f = this.formatter = s[f];
+ }
+ var v = (inValue != this.defaultValue && f) ? f.apply(s, callArgs) : inValue;
+ if(typeof v == "undefined"){
+ return this.defaultValue;
+ }
+ if(v && v.addBoth){
+ // Check if it's a deferred
+ v = new _DeferredTextWidget({deferred: v},
+ domConstruct.create("span", {innerHTML: this.defaultValue}));
+ }
+ if(v && v.declaredClass && v.startup){
+ return "<div class='dojoxGridStubNode' linkWidget='" +
+ v.id +
+ "' cellIdx='" +
+ this.index +
+ "'>" +
+ this.defaultValue +
+ "</div>";
+ }
+ return v;
+ },
+
+ // data source
+ format: function(inRowIndex, inItem){
+ // summary:
+ // provides the html for a given grid cell.
+ // inRowIndex: int
+ // grid row index
+ // returns: html for a given grid cell
+ var f, i=this.grid.edit.info, d=this.get ? this.get(inRowIndex, inItem) : (this.value || this.defaultValue);
+ d = (d && d.replace && this.grid.escapeHTMLInData) ? d.replace(/&/g, '&amp;').replace(/</g, '&lt;') : d;
+ if(this.editable && (this.alwaysEditing || (i.rowIndex==inRowIndex && i.cell==this))){
+ return this.formatEditing(d, inRowIndex);
+ }else{
+ return this._defaultFormat(d, [d, inRowIndex, this]);
+ }
+ },
+ formatEditing: function(inDatum, inRowIndex){
+ // summary:
+ // formats the cell for editing
+ // inDatum: anything
+ // cell data to edit
+ // inRowIndex: int
+ // grid row index
+ // returns: string of html to place in grid cell
+ },
+ // utility
+ getNode: function(inRowIndex){
+ // summary:
+ // gets the dom node for a given grid cell.
+ // inRowIndex: int
+ // grid row index
+ // returns: dom node for a given grid cell
+ return this.view.getCellNode(inRowIndex, this.index);
+ },
+ getHeaderNode: function(){
+ return this.view.getHeaderCellNode(this.index);
+ },
+ getEditNode: function(inRowIndex){
+ return (this.getNode(inRowIndex) || 0).firstChild || 0;
+ },
+ canResize: function(){
+ var uw = this.unitWidth;
+ return uw && (uw!=='auto');
+ },
+ isFlex: function(){
+ var uw = this.unitWidth;
+ return uw && lang.isString(uw) && (uw=='auto' || uw.slice(-1)=='%');
+ },
+ // edit support
+ applyEdit: function(inValue, inRowIndex){
+ this.grid.edit.applyCellEdit(inValue, this, inRowIndex);
+ },
+ cancelEdit: function(inRowIndex){
+ this.grid.doCancelEdit(inRowIndex);
+ },
+ _onEditBlur: function(inRowIndex){
+ if(this.grid.edit.isEditCell(inRowIndex, this.index)){
+ //console.log('editor onblur', e);
+ this.grid.edit.apply();
+ }
+ },
+ registerOnBlur: function(inNode, inRowIndex){
+ if(this.commitOnBlur){
+ connect.connect(inNode, "onblur", function(e){
+ // hack: if editor still thinks this editor is current some ms after it blurs, assume we've focused away from grid
+ setTimeout(lang.hitch(this, "_onEditBlur", inRowIndex), 250);
+ });
+ }
+ },
+ //protected
+ needFormatNode: function(inDatum, inRowIndex){
+ this._formatPending = true;
+ whenIdle(this, "_formatNode", inDatum, inRowIndex);
+ },
+ cancelFormatNode: function(){
+ this._formatPending = false;
+ },
+ //private
+ _formatNode: function(inDatum, inRowIndex){
+ if(this._formatPending){
+ this._formatPending = false;
+ // make cell selectable
+ if(!has("ie")){
+ dom.setSelectable(this.grid.domNode, true);
+ }
+ this.formatNode(this.getEditNode(inRowIndex), inDatum, inRowIndex);
+ }
+ },
+ //protected
+ formatNode: function(inNode, inDatum, inRowIndex){
+ // summary:
+ // format the editing dom node. Use when editor is a widget.
+ // inNode: dom node
+ // dom node for the editor
+ // inDatum: anything
+ // cell data to edit
+ // inRowIndex: int
+ // grid row index
+ if(has("ie")){
+ // IE sux bad
+ whenIdle(this, "focus", inRowIndex, inNode);
+ }else{
+ this.focus(inRowIndex, inNode);
+ }
+ },
+ dispatchEvent: function(m, e){
+ if(m in this){
+ return this[m](e);
+ }
+ },
+ //public
+ getValue: function(inRowIndex){
+ // summary:
+ // returns value entered into editor
+ // inRowIndex: int
+ // grid row index
+ // returns:
+ // value of editor
+ return this.getEditNode(inRowIndex)[this._valueProp];
+ },
+ setValue: function(inRowIndex, inValue){
+ // summary:
+ // set the value of the grid editor
+ // inRowIndex: int
+ // grid row index
+ // inValue: anything
+ // value of editor
+ var n = this.getEditNode(inRowIndex);
+ if(n){
+ n[this._valueProp] = inValue;
+ }
+ },
+ focus: function(inRowIndex, inNode){
+ // summary:
+ // focus the grid editor
+ // inRowIndex: int
+ // grid row index
+ // inNode: dom node
+ // editor node
+ focusSelectNode(inNode || this.getEditNode(inRowIndex));
+ },
+ save: function(inRowIndex){
+ // summary:
+ // save editor state
+ // inRowIndex: int
+ // grid row index
+ this.value = this.value || this.getValue(inRowIndex);
+ //console.log("save", this.value, inCell.index, inRowIndex);
+ },
+ restore: function(inRowIndex){
+ // summary:
+ // restore editor state
+ // inRowIndex: int
+ // grid row index
+ this.setValue(inRowIndex, this.value);
+ //console.log("restore", this.value, inCell.index, inRowIndex);
+ },
+ //protected
+ _finish: function(inRowIndex){
+ // summary:
+ // called when editing is completed to clean up editor
+ // inRowIndex: int
+ // grid row index
+ dom.setSelectable(this.grid.domNode, false);
+ this.cancelFormatNode();
+ },
+ //public
+ apply: function(inRowIndex){
+ // summary:
+ // apply edit from cell editor
+ // inRowIndex: int
+ // grid row index
+ this.applyEdit(this.getValue(inRowIndex), inRowIndex);
+ this._finish(inRowIndex);
+ },
+ cancel: function(inRowIndex){
+ // summary:
+ // cancel cell edit
+ // inRowIndex: int
+ // grid row index
+ this.cancelEdit(inRowIndex);
+ this._finish(inRowIndex);
+ }
+ });
+ BaseCell.markupFactory = function(node, cellDef){
+ var formatter = lang.trim(domAttr.get(node, "formatter")||"");
+ if(formatter){
+ cellDef.formatter = lang.getObject(formatter)||formatter;
+ }
+ var get = lang.trim(domAttr.get(node, "get")||"");
+ if(get){
+ cellDef.get = lang.getObject(get);
+ }
+ var getBoolAttr = function(attr, cell, cellAttr){
+ var value = lang.trim(domAttr.get(node, attr)||"");
+ if(value){ cell[cellAttr||attr] = !(value.toLowerCase()=="false"); }
+ };
+ getBoolAttr("sortDesc", cellDef);
+ getBoolAttr("editable", cellDef);
+ getBoolAttr("alwaysEditing", cellDef);
+ getBoolAttr("noresize", cellDef);
+ getBoolAttr("draggable", cellDef);
+
+ var value = lang.trim(domAttr.get(node, "loadingText")||domAttr.get(node, "defaultValue")||"");
+ if(value){
+ cellDef.defaultValue = value;
+ }
+
+ var getStrAttr = function(attr, cell, cellAttr){
+ var value = lang.trim(domAttr.get(node, attr)||"")||undefined;
+ if(value){ cell[cellAttr||attr] = value; }
+ };
+ getStrAttr("styles", cellDef);
+ getStrAttr("headerStyles", cellDef);
+ getStrAttr("cellStyles", cellDef);
+ getStrAttr("classes", cellDef);
+ getStrAttr("headerClasses", cellDef);
+ getStrAttr("cellClasses", cellDef);
+ };
+
+ var Cell = declare("dojox.grid.cells.Cell", BaseCell, {
+ // summary
+ // grid cell that provides a standard text input box upon editing
+ constructor: function(){
+ this.keyFilter = this.keyFilter;
+ },
+ // keyFilter: RegExp
+ // optional regex for disallowing keypresses
+ keyFilter: null,
+ formatEditing: function(inDatum, inRowIndex){
+ this.needFormatNode(inDatum, inRowIndex);
+ return '<input class="dojoxGridInput" type="text" value="' + inDatum + '">';
+ },
+ formatNode: function(inNode, inDatum, inRowIndex){
+ this.inherited(arguments);
+ // FIXME: feels too specific for this interface
+ this.registerOnBlur(inNode, inRowIndex);
+ },
+ doKey: function(e){
+ if(this.keyFilter){
+ var key = String.fromCharCode(e.charCode);
+ if(key.search(this.keyFilter) == -1){
+ event.stop(e);
+ }
+ }
+ },
+ _finish: function(inRowIndex){
+ this.inherited(arguments);
+ var n = this.getEditNode(inRowIndex);
+ try{
+ util.fire(n, "blur");
+ }catch(e){}
+ }
+ });
+ Cell.markupFactory = function(node, cellDef){
+ BaseCell.markupFactory(node, cellDef);
+ var keyFilter = lang.trim(domAttr.get(node, "keyFilter")||"");
+ if(keyFilter){
+ cellDef.keyFilter = new RegExp(keyFilter);
+ }
+ };
+
+ var RowIndex = declare("dojox.grid.cells.RowIndex", Cell, {
+ name: 'Row',
+
+ postscript: function(){
+ this.editable = false;
+ },
+ get: function(inRowIndex){
+ return inRowIndex + 1;
+ }
+ });
+ RowIndex.markupFactory = function(node, cellDef){
+ Cell.markupFactory(node, cellDef);
+ };
+
+ var Select = declare("dojox.grid.cells.Select", Cell, {
+ // summary:
+ // grid cell that provides a standard select for editing
+
+ // options: Array
+ // text of each item
+ options: null,
+
+ // values: Array
+ // value for each item
+ values: null,
+
+ // returnIndex: Integer
+ // editor returns only the index of the selected option and not the value
+ returnIndex: -1,
+
+ constructor: function(inCell){
+ this.values = this.values || this.options;
+ },
+ formatEditing: function(inDatum, inRowIndex){
+ this.needFormatNode(inDatum, inRowIndex);
+ var h = [ '<select class="dojoxGridSelect">' ];
+ for (var i=0, o, v; ((o=this.options[i]) !== undefined)&&((v=this.values[i]) !== undefined); i++){
+ v = v.replace ? v.replace(/&/g, '&amp;').replace(/</g, '&lt;') : v;
+ o = o.replace ? o.replace(/&/g, '&amp;').replace(/</g, '&lt;') : o;
+ h.push("<option", (inDatum==v ? ' selected' : ''), ' value="' + v + '"', ">", o, "</option>");
+ }
+ h.push('</select>');
+ return h.join('');
+ },
+ _defaultFormat: function(inValue, callArgs){
+ var v = this.inherited(arguments);
+ // when 'values' and 'options' both provided and there is no cutomized formatter,
+ // then we use 'options' as label in order to be consistent
+ if(!this.formatter && this.values && this.options){
+ var i = array.indexOf(this.values, v);
+ if(i >= 0){
+ v = this.options[i];
+ }
+ }
+ return v;
+ },
+ getValue: function(inRowIndex){
+ var n = this.getEditNode(inRowIndex);
+ if(n){
+ var i = n.selectedIndex, o = n.options[i];
+ return this.returnIndex > -1 ? i : o.value || o.innerHTML;
+ }
+ }
+ });
+ Select.markupFactory = function(node, cell){
+ Cell.markupFactory(node, cell);
+ var options = lang.trim(domAttr.get(node, "options")||"");
+ if(options){
+ var o = options.split(',');
+ if(o[0] != options){
+ cell.options = o;
+ }
+ }
+ var values = lang.trim(domAttr.get(node, "values")||"");
+ if(values){
+ var v = values.split(',');
+ if(v[0] != values){
+ cell.values = v;
+ }
+ }
+ };
+
+ var AlwaysEdit = declare("dojox.grid.cells.AlwaysEdit", Cell, {
+ // summary:
+ // grid cell that is always in an editable state, regardless of grid editing state
+ alwaysEditing: true,
+ _formatNode: function(inDatum, inRowIndex){
+ this.formatNode(this.getEditNode(inRowIndex), inDatum, inRowIndex);
+ },
+ applyStaticValue: function(inRowIndex){
+ var e = this.grid.edit;
+ e.applyCellEdit(this.getValue(inRowIndex), this, inRowIndex);
+ e.start(this, inRowIndex, true);
+ }
+ });
+ AlwaysEdit.markupFactory = function(node, cell){
+ Cell.markupFactory(node, cell);
+ };
+
+ var Bool = declare("dojox.grid.cells.Bool", AlwaysEdit, {
+ // summary:
+ // grid cell that provides a standard checkbox that is always on for editing
+ _valueProp: "checked",
+ formatEditing: function(inDatum, inRowIndex){
+ return '<input class="dojoxGridInput" type="checkbox"' + (inDatum ? ' checked="checked"' : '') + ' style="width: auto" />';
+ },
+ doclick: function(e){
+ if(e.target.tagName == 'INPUT'){
+ this.applyStaticValue(e.rowIndex);
+ }
+ }
+ });
+ Bool.markupFactory = function(node, cell){
+ AlwaysEdit.markupFactory(node, cell);
+ };
+
+ return BaseCell;
+
+}); \ No newline at end of file
diff --git a/js/dojo-1.7.2/dojox/grid/cells/dijit.js b/js/dojo-1.7.2/dojox/grid/cells/dijit.js
new file mode 100644
index 0000000..502c4d2
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/cells/dijit.js
@@ -0,0 +1,256 @@
+//>>built
+define("dojox/grid/cells/dijit", [
+ "dojo/_base/kernel",
+ "../../main",
+ "dojo/_base/declare",
+ "dojo/_base/array",
+ "dojo/_base/lang",
+ "dojo/_base/json",
+ "dojo/_base/connect",
+ "dojo/_base/sniff",
+ "dojo/dom",
+ "dojo/dom-attr",
+ "dojo/dom-construct",
+ "dojo/dom-geometry",
+ "dojo/data/ItemFileReadStore",
+ "dijit/form/DateTextBox",
+ "dijit/form/TimeTextBox",
+ "dijit/form/ComboBox",
+ "dijit/form/CheckBox",
+ "dijit/form/TextBox",
+ "dijit/form/NumberSpinner",
+ "dijit/form/NumberTextBox",
+ "dijit/form/CurrencyTextBox",
+ "dijit/form/HorizontalSlider",
+ "dijit/Editor",
+ "../util",
+ "./_base"
+], function(dojo, dojox, declare, array, lang, json, connect, has, dom, domAttr, domConstruct,
+ domGeometry, ItemFileReadStore, DateTextBox, TimeTextBox, ComboBox, CheckBox, TextBox,
+ NumberSpinner, NumberTextBox, CurrencyTextBox, HorizontalSlider, Editor, util, BaseCell){
+
+// TODO: shouldn't it be the test file's job to require these modules,
+// if it is using them? Most of these modules aren't referenced by this file.
+
+ var _Widget = declare("dojox.grid.cells._Widget", BaseCell, {
+ widgetClass: TextBox,
+ constructor: function(inCell){
+ this.widget = null;
+ if(typeof this.widgetClass == "string"){
+ dojo.deprecated("Passing a string to widgetClass is deprecated", "pass the widget class object instead", "2.0");
+ this.widgetClass = lang.getObject(this.widgetClass);
+ }
+ },
+ formatEditing: function(inDatum, inRowIndex){
+ this.needFormatNode(inDatum, inRowIndex);
+ return "<div></div>";
+ },
+ getValue: function(inRowIndex){
+ return this.widget.get('value');
+ },
+ _unescapeHTML: function(value){
+ return (value && value.replace && this.grid.escapeHTMLInData) ?
+ value.replace(/&lt;/g, '<').replace(/&amp;/g, '&') : value;
+ },
+ setValue: function(inRowIndex, inValue){
+ if(this.widget&&this.widget.set){
+ inValue = this._unescapeHTML(inValue);
+ //Look for lazy-loading editor and handle it via its deferred.
+ if(this.widget.onLoadDeferred){
+ var self = this;
+ this.widget.onLoadDeferred.addCallback(function(){
+ self.widget.set("value",inValue===null?"":inValue);
+ });
+ }else{
+ this.widget.set("value", inValue);
+ }
+ }else{
+ this.inherited(arguments);
+ }
+ },
+ getWidgetProps: function(inDatum){
+ return lang.mixin(
+ {
+ dir: this.dir,
+ lang: this.lang
+ },
+ this.widgetProps||{},
+ {
+ constraints: lang.mixin({}, this.constraint) || {}, //TODO: really just for ValidationTextBoxes
+ value: this._unescapeHTML(inDatum)
+ }
+ );
+ },
+ createWidget: function(inNode, inDatum, inRowIndex){
+ return new this.widgetClass(this.getWidgetProps(inDatum), inNode);
+ },
+ attachWidget: function(inNode, inDatum, inRowIndex){
+ inNode.appendChild(this.widget.domNode);
+ this.setValue(inRowIndex, inDatum);
+ },
+ formatNode: function(inNode, inDatum, inRowIndex){
+ if(!this.widgetClass){
+ return inDatum;
+ }
+ if(!this.widget){
+ this.widget = this.createWidget.apply(this, arguments);
+ }else{
+ this.attachWidget.apply(this, arguments);
+ }
+ this.sizeWidget.apply(this, arguments);
+ this.grid.views.renormalizeRow(inRowIndex);
+ this.grid.scroller.rowHeightChanged(inRowIndex, true/*fix #11101*/);
+ this.focus();
+ return undefined;
+ },
+ sizeWidget: function(inNode, inDatum, inRowIndex){
+ var
+ p = this.getNode(inRowIndex),
+ box = dojo.contentBox(p);
+ dojo.marginBox(this.widget.domNode, {w: box.w});
+ },
+ focus: function(inRowIndex, inNode){
+ if(this.widget){
+ setTimeout(lang.hitch(this.widget, function(){
+ util.fire(this, "focus");
+ }), 0);
+ }
+ },
+ _finish: function(inRowIndex){
+ this.inherited(arguments);
+ util.removeNode(this.widget.domNode);
+ if(has("ie")){
+ dom.setSelectable(this.widget.domNode, true);
+ }
+ }
+ });
+ _Widget.markupFactory = function(node, cell){
+ BaseCell.markupFactory(node, cell);
+ var widgetProps = lang.trim(domAttr.get(node, "widgetProps")||"");
+ var constraint = lang.trim(domAttr.get(node, "constraint")||"");
+ var widgetClass = lang.trim(domAttr.get(node, "widgetClass")||"");
+ if(widgetProps){
+ cell.widgetProps = json.fromJson(widgetProps);
+ }
+ if(constraint){
+ cell.constraint = json.fromJson(constraint);
+ }
+ if(widgetClass){
+ cell.widgetClass = lang.getObject(widgetClass);
+ }
+ };
+
+ var ComboBox = declare("dojox.grid.cells.ComboBox", _Widget, {
+ widgetClass: ComboBox,
+ getWidgetProps: function(inDatum){
+ var items=[];
+ array.forEach(this.options, function(o){
+ items.push({name: o, value: o});
+ });
+ var store = new ItemFileReadStore({data: {identifier:"name", items: items}});
+ return lang.mixin({}, this.widgetProps||{}, {
+ value: inDatum,
+ store: store
+ });
+ },
+ getValue: function(){
+ var e = this.widget;
+ // make sure to apply the displayed value
+ e.set('displayedValue', e.get('displayedValue'));
+ return e.get('value');
+ }
+ });
+ ComboBox.markupFactory = function(node, cell){
+ _Widget.markupFactory(node, cell);
+ var options = lang.trim(domAttr.get(node, "options")||"");
+ if(options){
+ var o = options.split(',');
+ if(o[0] != options){
+ cell.options = o;
+ }
+ }
+ };
+
+ var DateTextBox = declare("dojox.grid.cells.DateTextBox", _Widget, {
+ widgetClass: DateTextBox,
+ setValue: function(inRowIndex, inValue){
+ if(this.widget){
+ this.widget.set('value', new Date(inValue));
+ }else{
+ this.inherited(arguments);
+ }
+ },
+ getWidgetProps: function(inDatum){
+ return lang.mixin(this.inherited(arguments), {
+ value: new Date(inDatum)
+ });
+ }
+ });
+ DateTextBox.markupFactory = function(node, cell){
+ _Widget.markupFactory(node, cell);
+ };
+
+ var CheckBox = declare("dojox.grid.cells.CheckBox", _Widget, {
+ widgetClass: CheckBox,
+ getValue: function(){
+ return this.widget.checked;
+ },
+ setValue: function(inRowIndex, inValue){
+ if(this.widget&&this.widget.attributeMap.checked){
+ this.widget.set("checked", inValue);
+ }else{
+ this.inherited(arguments);
+ }
+ },
+ sizeWidget: function(inNode, inDatum, inRowIndex){
+ return;
+ }
+ });
+ CheckBox.markupFactory = function(node, cell){
+ _Widget.markupFactory(node, cell);
+ };
+
+ var Editor = declare("dojox.grid.cells.Editor", _Widget, {
+ widgetClass: Editor,
+ getWidgetProps: function(inDatum){
+ return lang.mixin({}, this.widgetProps||{}, {
+ height: this.widgetHeight || "100px"
+ });
+ },
+ createWidget: function(inNode, inDatum, inRowIndex){
+ // widget needs its value set after creation
+ var widget = new this.widgetClass(this.getWidgetProps(inDatum), inNode);
+ connect.connect(widget, 'onLoad', lang.hitch(this, 'populateEditor'));
+ return widget;
+ },
+ formatNode: function(inNode, inDatum, inRowIndex){
+ this.content = inDatum;
+ this.inherited(arguments);
+ if(has("mozilla")){
+ // FIXME: seem to need to reopen the editor and display the toolbar
+ var e = this.widget;
+ e.open();
+ if(this.widgetToolbar){
+ domConstruct.place(e.toolbar.domNode, e.editingArea, "before");
+ }
+ }
+ },
+ populateEditor: function(){
+ this.widget.set('value', this.content);
+ this.widget.placeCursorAtEnd();
+ }
+ });
+ Editor.markupFactory = function(node, cell){
+ _Widget.markupFactory(node, cell);
+ var h = lang.trim(domAttr.get(node, "widgetHeight")||"");
+ if(h){
+ if((h != "auto")&&(h.substr(-2) != "em")){
+ h = parseInt(h, 10)+"px";
+ }
+ cell.widgetHeight = h;
+ }
+ };
+
+ return dojox.grid.cells.dijit;
+
+}); \ No newline at end of file
diff --git a/js/dojo-1.7.2/dojox/grid/cells/tree.js b/js/dojo-1.7.2/dojox/grid/cells/tree.js
new file mode 100644
index 0000000..7974a8a
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/cells/tree.js
@@ -0,0 +1,75 @@
+//>>built
+define("dojox/grid/cells/tree", [
+ "dojo/_base/kernel",
+ "../../main",
+ "dojo/_base/lang",
+ "../cells"
+], function(dojo, dojox, lang){
+
+dojox.grid.cells.TreeCell = {
+ formatAggregate: function(inItem, level, inRowIndexes){
+ var f, g=this.grid, i=g.edit.info,
+ d=g.aggregator ? g.aggregator.getForCell(this, level, inItem, level === this.level ? "cnt" : this.parentCell.aggregate) : (this.value || this.defaultValue);
+ return this._defaultFormat(d, [d, level - this.level, inRowIndexes, this]);
+ },
+ formatIndexes: function(inRowIndexes, inItem){
+ var f, g=this.grid, i=g.edit.info,
+ d=this.get ? this.get(inRowIndexes[0], inItem, inRowIndexes) : (this.value || this.defaultValue);
+ if(this.editable && (this.alwaysEditing || (i.rowIndex==inRowIndexes[0] && i.cell==this))){
+ return this.formatEditing(d, inRowIndexes[0], inRowIndexes);
+ }else{
+ return this._defaultFormat(d, [d, inRowIndexes[0], inRowIndexes, this]);
+ }
+ },
+ getOpenState: function(itemId){
+ var grid = this.grid, store = grid.store, itm = null;
+ if(store.isItem(itemId)){
+ itm = itemId;
+ itemId = store.getIdentity(itemId);
+ }
+ if(!this.openStates){ this.openStates = {}; }
+ if(typeof itemId != "string" || !(itemId in this.openStates)){
+ this.openStates[itemId] = grid.getDefaultOpenState(this, itm);
+ }
+ return this.openStates[itemId];
+ },
+ formatAtLevel: function(inRowIndexes, inItem, level, summaryRow, toggleClass, cellClasses){
+ if(!lang.isArray(inRowIndexes)){
+ inRowIndexes = [inRowIndexes];
+ }
+ var result = "";
+ if(level > this.level || (level === this.level && summaryRow)){
+ cellClasses.push("dojoxGridSpacerCell");
+ if(level === this.level){
+ cellClasses.push("dojoxGridTotalCell");
+ }
+ result = '<span></span>';
+ }else if(level < this.level){
+ cellClasses.push("dojoxGridSummaryCell");
+ result = '<span class="dojoxGridSummarySpan">' + this.formatAggregate(inItem, level, inRowIndexes) + '</span>';
+ }else{
+ var ret = "";
+ if(this.isCollapsable){
+ var store = this.grid.store, id = "";
+ if(store.isItem(inItem)){
+ id = store.getIdentity(inItem);
+ }
+ cellClasses.push("dojoxGridExpandoCell");
+ ret = '<span ' + dojo._scopeName + 'Type="dojox.grid._Expando" level="' + level + '" class="dojoxGridExpando"' +
+ '" toggleClass="' + toggleClass + '" itemId="' + id + '" cellIdx="' + this.index + '"></span>';
+ }
+ result = ret + this.formatIndexes(inRowIndexes, inItem);
+ }
+
+ if(this.grid.focus.cell && this.index == this.grid.focus.cell.index &&
+ inRowIndexes.join('/') == this.grid.focus.rowIndex){
+ cellClasses.push(this.grid.focus.focusClass);
+ }
+
+ return result;
+ }
+};
+
+return dojox.grid.cells.TreeCell;
+
+}); \ No newline at end of file
diff --git a/js/dojo-1.7.2/dojox/grid/compatGrid.tar.gz b/js/dojo-1.7.2/dojox/grid/compatGrid.tar.gz
new file mode 100644
index 0000000..87c39c8
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/compatGrid.tar.gz
Binary files differ
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/_Events.js b/js/dojo-1.7.2/dojox/grid/enhanced/_Events.js
new file mode 100644
index 0000000..c461531
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/_Events.js
@@ -0,0 +1,215 @@
+//>>built
+define("dojox/grid/enhanced/_Events", [
+ "dojo/_base/kernel",
+ "dojo/_base/declare",
+ "dojo/keys",
+ "dojo/_base/html",
+ "dojo/_base/event",
+ "dojox/grid/_Events"
+], function(dojo, declare, keys, html, event, _Events){
+
+return declare("dojox.grid.enhanced._Events", null, {
+ // summary:
+ // Overwrite some default events of DataGrid
+ //
+ // description:
+ // Methods are copied or replaced for overwriting, this might be refined once
+ // an overall plugin architecture is set up for DataGrid.
+
+ //_events: Object
+ // Method map cached from dojox.grid._Events().
+ _events: null,
+
+ // headerCellActiveClass: String
+ // css class to apply to grid header cells when activated(mouse down)
+ headerCellActiveClass: 'dojoxGridHeaderActive',
+
+ // cellActiveClass: String
+ // css class to apply to grid content cells when activated(mouse down)
+ cellActiveClass: 'dojoxGridCellActive',
+
+ // rowActiveClass: String
+ // css class to apply to grid rows when activated(mouse down)
+ rowActiveClass: 'dojoxGridRowActive',
+
+ constructor: function(inGrid){
+ //TODO - extend dojox.grid._Events rather than mixin for 1.8
+ this._events = new _Events();
+ //mixin "this" to Grid
+ inGrid.mixin(inGrid, this);
+ },
+ dokeyup: function(e){
+ // summary:
+ // Grid key up event handler.
+ // e: Event
+ // Un-decorated event object
+ this.focus.currentArea().keyup(e);
+ },
+ onKeyDown: function(e){
+ // summary:
+ // Overwritten, see dojox.grid._Events.onKeyDown();
+ if(e.altKey || e.metaKey){ return; }
+ var focus = this.focus;
+ var editing = this.edit.isEditing();
+ switch(e.keyCode){
+ case keys.TAB:
+ if(e.ctrlKey){ return; }
+ focus.tab(e.shiftKey ? -1:1,e);
+ break;
+ case keys.UP_ARROW:
+ case keys.DOWN_ARROW:
+ if(editing){ return; }
+ focus.currentArea().move(e.keyCode == keys.UP_ARROW ? -1 : 1, 0, e);
+ break;
+ case keys.LEFT_ARROW:
+ case keys.RIGHT_ARROW:
+ if(editing){ return; }
+ var offset = (e.keyCode == keys.LEFT_ARROW) ? 1 : -1;
+ if(html._isBodyLtr()){ offset *= -1; }
+ focus.currentArea().move(0, offset, e);
+ break;
+ case keys.F10:
+ if(this.menus && e.shiftKey){
+ this.onRowContextMenu(e);
+ }
+ break;
+ default:
+ focus.currentArea().keydown(e);
+ break;
+ }
+ },
+ //TODO - make the following events more reasonalble - e.g. more accurate conditions
+ //events for row selectors
+ domouseup: function(e){
+ if(e.cellNode){
+ this.onMouseUp(e);
+ }else{
+ this.onRowSelectorMouseUp(e);
+ }
+ },
+ domousedown: function(e){
+ if(!e.cellNode){
+ this.onRowSelectorMouseDown(e);
+ }
+ },
+ onMouseUp: function(e){
+ // summary:
+ // New - Event fired when mouse is up inside grid.
+ // e: Event
+ // Decorated event object that contains reference to grid, cell, and rowIndex
+ this[e.rowIndex == -1 ? "onHeaderCellMouseUp" : "onCellMouseUp"](e);
+ },
+ onCellMouseDown: function(e){
+ // summary:
+ // Overwritten, see dojox.grid._Events.onCellMouseDown()
+ html.addClass(e.cellNode, this.cellActiveClass);
+ html.addClass(e.rowNode, this.rowActiveClass);
+ },
+ onCellMouseUp: function(e){
+ // summary:
+ // New - Event fired when mouse is up inside content cell.
+ // e: Event
+ // Decorated event object that contains reference to grid, cell, and rowIndex
+ html.removeClass(e.cellNode, this.cellActiveClass);
+ html.removeClass(e.rowNode, this.rowActiveClass);
+ },
+ onCellClick: function(e){
+ // summary:
+ // Overwritten, see dojox.grid._Events.onCellClick()
+
+ //invoke dojox.grid._Events.onCellClick()
+ this._events.onCellClick.call(this, e);
+ //move mouse events to the focus manager.
+ this.focus.contentMouseEvent(e);//TODO
+ },
+ onCellDblClick: function(e){
+ // summary:
+ // Overwritten, see dojox.grid._Events.onCellDblClick()
+ if(this.pluginMgr.isFixedCell(e.cell)){ return; }
+ if(this._click.length > 1 && (!this._click[0] || !this._click[1])){
+ this._click[0] = this._click[1] = e;
+ }
+ //invoke dojox.grid._Events.onCellDblClick()
+ this._events.onCellDblClick.call(this, e);
+ },
+ onRowClick: function(e){
+ // summary:
+ // Overwritten, see dojox.grid._Events.onRowClick()
+ this.edit.rowClick(e);
+ if(!e.cell || !this.plugin('indirectSelection')){
+ this.selection.clickSelectEvent(e);
+ }
+ },
+ onRowContextMenu: function(e){
+ // summary:
+ // Overwritten, see dojox.grid._Events.onRowContextMenu()
+ if(!this.edit.isEditing() && this.menus){
+ this.showMenu(e);
+ }
+ },
+ onSelectedRegionContextMenu: function(e){
+ // summary:
+ // New - Event fired when a selected region context menu is accessed via mouse right click.
+ // e: Event
+ // Decorated event object which contains reference to grid and info of selected
+ // regions(selection type - row|column, selected index - [...])
+ if(this.selectedRegionMenu){
+ this.selectedRegionMenu._openMyself({
+ target: e.target,
+ coords: e.keyCode !== keys.F10 && "pageX" in e ? {
+ x: e.pageX,
+ y: e.pageY
+ } : null
+ });
+ event.stop(e);
+ }
+ },
+ onHeaderCellMouseOut: function(e){
+ // summary:
+ // Overwritten, see dojox.grid._Events.onHeaderCellMouseOut()
+ if(e.cellNode){
+ html.removeClass(e.cellNode, this.cellOverClass);
+ html.removeClass(e.cellNode, this.headerCellActiveClass);
+ }
+ },
+ onHeaderCellMouseDown: function(e){
+ // summary:
+ // Overwritten, see dojox.grid._Events.onHeaderCellMouseDown()
+ if(e.cellNode){//TBD - apply to selection region for nested sorting?
+ html.addClass(e.cellNode, this.headerCellActiveClass);
+ }
+ },
+ onHeaderCellMouseUp: function(e){
+ // summary:
+ // New event
+ if(e.cellNode){
+ html.removeClass(e.cellNode, this.headerCellActiveClass);
+ }
+ },
+ onHeaderCellClick: function(e){
+ // summary:
+ // Overwritten, see dojox.grid._Events.onHeaderCellClick()
+ //move focus to header.
+ this.focus.currentArea("header");
+ //invoke dojox.grid._Events.onHeaderCellClick()
+ if(!e.cell.isRowSelector){
+ this._events.onHeaderCellClick.call(this, e);
+ }
+ //move mouse events to the focus manager.
+ this.focus.headerMouseEvent(e);
+ },
+ onRowSelectorMouseDown: function(e){
+ this.focus.focusArea("rowHeader", e);
+ },
+
+ onRowSelectorMouseUp: function(e){},
+
+ //triggered in _View, see Selector plugin
+ onMouseUpRow: function(e){
+ if(e.rowIndex != -1){
+ this.onRowMouseUp(e);
+ }
+ },
+ onRowMouseUp: function(e){}
+});
+}); \ No newline at end of file
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/_FocusManager.js b/js/dojo-1.7.2/dojox/grid/enhanced/_FocusManager.js
new file mode 100644
index 0000000..872d089
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/_FocusManager.js
@@ -0,0 +1,774 @@
+//>>built
+define("dojox/grid/enhanced/_FocusManager", [
+ "dojo/_base/kernel",
+ "dojo/_base/lang",
+ "dojo/_base/declare",
+ "dojo/_base/array",
+ "dojo/_base/connect",
+ "dojo/_base/event",
+ "dojo/_base/sniff",
+ "dojo/_base/html",
+ "dojo/keys",
+ "dijit/a11y",
+ "dijit/focus",
+ "../_FocusManager"
+], function(dojo, lang, declare, array, connect, event, has, html, keys, dijitA11y, dijitFocus, _FocusManager){
+
+var _FocusArea = declare("dojox.grid.enhanced._FocusArea", null, {
+ // summary:
+ // This is a friend class of _FocusManager
+/*=====
+ // name: string
+ // Name of this area.
+ name: "",
+
+ // onFocus: function(event, step)
+ // Called when this area logically gets focus.
+ // event: Event object
+ // May be unavailable, should check before use.
+ // step: Integer
+ // The distance in the tab sequence from last focused area to this area.
+ // returns:
+ // whether this area is successfully focused. If not, the next area will get focus.
+ onFocus: function(event, step){return true;},
+
+ // onBlur: function(event, step)
+ // Called when this area logically loses focus.
+ // event: Event object
+ // May be unavailable, should check before use.
+ // step: Integer
+ // The distance in the tab sequence from this area to the area to focus.
+ // returns:
+ // If Boolean, means whether this area has successfully blurred. If not, the next area to focus is still this one.
+ // If String, means the next area to focus is given by this returned name.
+ onBlur: function(event, step){return true;},
+
+ // onMove: function(rowStep, colStep, event)
+ // Called when focus is moving around within this area.
+ // rowStep: Integer
+ // colStep: Integer
+ // event: Event object
+ // May be unavailable, should check before use.
+ onMove: function(rowStep, colStep, event){},
+
+ // onKey: function(event, isBubble)
+ // Called when some key is pressed when focus is logically in this area.
+ // event: Event object
+ // isBubble: Boolean
+ // Whether is in bubble stage (true) or catch stage (false).
+ // returns:
+ // If you do NOT want the event to propagate any further along the area stack, return exactly false.
+ // So if you return nothing (undefined), this event is still propagating.
+ onKey: function(event, isBubble){return true},
+
+ // getRegions: function()
+ // Define the small regions (dom nodes) in this area.
+ // returns: Array of dom nodes.
+ getRegions: function(){},
+
+ // onRegionFocus: function(event)
+ // Connected to the onfocus event of the defined regions (if any)
+ onRegionFocus: function(event){},
+
+ // onRegionBlur: function(event)
+ // Connected to the onblur event of the defined regions (if any)
+ onRegionBlur: function(event){},
+=====*/
+ constructor: function(area, focusManager){
+ this._fm = focusManager;
+ this._evtStack = [area.name];
+ var dummy = function(){return true;};
+ area.onFocus = area.onFocus || dummy;
+ area.onBlur = area.onBlur || dummy;
+ area.onMove = area.onMove || dummy;
+ area.onKeyUp = area.onKeyUp || dummy;
+ area.onKeyDown = area.onKeyDown || dummy;
+ lang.mixin(this, area);
+ },
+ move: function(rowStep, colStep, evt){
+ if(this.name){
+ var i, len = this._evtStack.length;
+ for(i = len - 1; i >= 0; --i){
+ if(this._fm._areas[this._evtStack[i]].onMove(rowStep, colStep, evt) === false){
+ return false;
+ }
+ }
+ }
+ return true;
+ },
+ _onKeyEvent: function(evt, funcName){
+ if(this.name){
+ var i, len = this._evtStack.length;
+ for(i = len - 1; i >= 0; --i){
+ if(this._fm._areas[this._evtStack[i]][funcName](evt, false) === false){
+ return false;
+ }
+ }
+ for(i = 0; i < len; ++i){
+ if(this._fm._areas[this._evtStack[i]][funcName](evt, true) === false){
+ return false;
+ }
+ }
+ }
+ return true;
+ },
+ keydown: function(evt){
+ return this._onKeyEvent(evt, "onKeyDown");
+ },
+ keyup: function(evt){
+ return this._onKeyEvent(evt, "onKeyUp");
+ },
+ contentMouseEventPlanner: function(){
+ return 0;
+ },
+ headerMouseEventPlanner: function(){
+ return 0;
+ }
+});
+
+return declare("dojox.grid.enhanced._FocusManager", _FocusManager, {
+ _stopEvent: function(evt){
+ try{
+ if(evt && evt.preventDefault){
+ event.stop(evt);
+ }
+ }catch(e){}
+ },
+
+ constructor: function(grid){
+ this.grid = grid;
+ this._areas = {};
+ this._areaQueue = [];
+ this._contentMouseEventHandlers = [];
+ this._headerMouseEventHandlers = [];
+ this._currentAreaIdx = -1;
+ this._gridBlured = true;
+ this._connects.push(connect.connect(grid, "onBlur", this, "_doBlur"));
+ this._connects.push(connect.connect(grid.scroller, "renderPage", this, "_delayedCellFocus"));
+
+ this.addArea({
+ name: "header",
+ onFocus: lang.hitch(this, this.focusHeader),
+ onBlur: lang.hitch(this, this._blurHeader),
+ onMove: lang.hitch(this, this._navHeader),
+ getRegions: lang.hitch(this, this._findHeaderCells),
+ onRegionFocus: lang.hitch(this, this.doColHeaderFocus),
+ onRegionBlur: lang.hitch(this, this.doColHeaderBlur),
+ onKeyDown: lang.hitch(this, this._onHeaderKeyDown)
+ });
+ this.addArea({
+ name: "content",
+ onFocus: lang.hitch(this, this._focusContent),
+ onBlur: lang.hitch(this, this._blurContent),
+ onMove: lang.hitch(this, this._navContent),
+ onKeyDown: lang.hitch(this, this._onContentKeyDown)
+ });
+ this.addArea({
+ name: "editableCell",
+ onFocus: lang.hitch(this, this._focusEditableCell),
+ onBlur: lang.hitch(this, this._blurEditableCell),
+ onKeyDown: lang.hitch(this, this._onEditableCellKeyDown),
+ onContentMouseEvent: lang.hitch(this, this._onEditableCellMouseEvent),
+ contentMouseEventPlanner: function(evt, areas){ return -1; }
+ });
+ this.placeArea("header");
+ this.placeArea("content");
+ this.placeArea("editableCell");
+ this.placeArea("editableCell","above","content");
+ },
+ destroy: function(){
+ for(var name in this._areas){
+ var area = this._areas[name];
+ array.forEach(area._connects, connect.disconnect);
+ area._connects = null;
+ if(area.uninitialize){
+ area.uninitialize();
+ }
+ }
+ this.inherited(arguments);
+ },
+ addArea: function(area){
+ if(area.name && lang.isString(area.name)){
+ if(this._areas[area.name]){
+ //Just replace the original area, instead of remove it, so the position does not change.
+ array.forEach(area._connects, connect.disconnect);
+ }
+ this._areas[area.name] = new _FocusArea(area, this);
+ if(area.onHeaderMouseEvent){
+ this._headerMouseEventHandlers.push(area.name);
+ }
+ if(area.onContentMouseEvent){
+ this._contentMouseEventHandlers.push(area.name);
+ }
+ }
+ },
+ getArea: function(areaName){
+ return this._areas[areaName];
+ },
+ _bindAreaEvents: function(){
+ var area, hdl, areas = this._areas;
+ array.forEach(this._areaQueue, function(name){
+ area = areas[name];
+ if(!area._initialized && lang.isFunction(area.initialize)){
+ area.initialize();
+ area._initialized = true;
+ }
+ if(area.getRegions){
+ area._regions = area.getRegions() || [];
+ array.forEach(area._connects || [], connect.disconnect);
+ area._connects = [];
+ array.forEach(area._regions, function(r){
+ if(area.onRegionFocus){
+ hdl = connect.connect(r, "onfocus", area.onRegionFocus);
+ area._connects.push(hdl);
+ }
+ if(area.onRegionBlur){
+ hdl = connect.connect(r, "onblur", area.onRegionBlur);
+ area._connects.push(hdl);
+ }
+ });
+ }
+ });
+ },
+ removeArea: function(areaName){
+ var area = this._areas[areaName];
+ if(area){
+ this.ignoreArea(areaName);
+ var i = array.indexOf(this._contentMouseEventHandlers, areaName);
+ if(i >= 0){
+ this._contentMouseEventHandlers.splice(i, 1);
+ }
+ i = array.indexOf(this._headerMouseEventHandlers, areaName);
+ if(i >= 0){
+ this._headerMouseEventHandlers.splice(i, 1);
+ }
+ array.forEach(area._connects, connect.disconnect);
+ if(area.uninitialize){
+ area.uninitialize();
+ }
+ delete this._areas[areaName];
+ }
+ },
+ currentArea: function(areaName, toBlurOld){
+ // summary:
+ // Set current area to the one areaName refers.
+ // areaName: String
+ var idx, cai = this._currentAreaIdx;
+ if(lang.isString(areaName) && (idx = array.indexOf(this._areaQueue, areaName)) >= 0){
+ if(cai != idx){
+ this.tabbingOut = false;
+ if(toBlurOld && cai >= 0 && cai < this._areaQueue.length){
+ this._areas[this._areaQueue[cai]].onBlur();
+ }
+ this._currentAreaIdx = idx;
+ }
+ }else{
+ return (cai < 0 || cai >= this._areaQueue.length) ?
+ new _FocusArea({}, this) :
+ this._areas[this._areaQueue[this._currentAreaIdx]];
+ }
+ return null;
+ },
+ placeArea: function(name, pos, otherAreaName){
+ // summary:
+ // Place the area refered by *name* at some logical position relative to an existing area.
+ // example:
+ // placeArea("myarea","before"|"after",...)
+ // placeArea("myarea","below"|"above",...)
+ if(!this._areas[name]){ return; }
+ var idx = array.indexOf(this._areaQueue,otherAreaName);
+ switch(pos){
+ case "after":
+ if(idx >= 0){ ++idx; }
+ //intentional drop through
+ case "before":
+ if(idx >= 0){
+ this._areaQueue.splice(idx,0,name);
+ break;
+ }
+ //intentional drop through
+ default:
+ this._areaQueue.push(name);
+ break;
+ case "above":
+ var isAbove = true;
+ //intentional drop through
+ case "below":
+ var otherArea = this._areas[otherAreaName];
+ if(otherArea){
+ if(isAbove){
+ otherArea._evtStack.push(name);
+ }else{
+ otherArea._evtStack.splice(0,0,name);
+ }
+ }
+ }
+ },
+ ignoreArea: function(name){
+ this._areaQueue = array.filter(this._areaQueue,function(areaName){
+ return areaName != name;
+ });
+ },
+ focusArea: function(/* int|string|areaObj */areaId,evt){
+ var idx;
+ if(typeof areaId == "number"){
+ idx = areaId < 0 ? this._areaQueue.length + areaId : areaId;
+ }else{
+ idx = array.indexOf(this._areaQueue,
+ lang.isString(areaId) ? areaId : (areaId && areaId.name));
+ }
+ if(idx < 0){ idx = 0; }
+ var step = idx - this._currentAreaIdx;
+ this._gridBlured = false;
+ if(step){
+ this.tab(step, evt);
+ }else{
+ this.currentArea().onFocus(evt, step);
+ }
+ },
+ tab: function(step,evt){
+ //console.log("===========tab",step,"curArea",this._currentAreaIdx,"areaCnt",this._areaQueue.length);
+ this._gridBlured = false;
+ this.tabbingOut = false;
+ if(step === 0){
+ return;
+ }
+ var cai = this._currentAreaIdx;
+ var dir = step > 0 ? 1:-1;
+ if(cai < 0 || cai >= this._areaQueue.length){
+ cai = (this._currentAreaIdx += step);
+ }else{
+ var nextArea = this._areas[this._areaQueue[cai]].onBlur(evt,step);
+ if(nextArea === true){
+ cai = (this._currentAreaIdx += step);
+ }else if(lang.isString(nextArea) && this._areas[nextArea]){
+ cai = this._currentAreaIdx = array.indexOf(this._areaQueue,nextArea);
+ }
+ }
+ //console.log("target area:",cai);
+ for(; cai >= 0 && cai < this._areaQueue.length; cai += dir){
+ this._currentAreaIdx = cai;
+ if(this._areaQueue[cai] && this._areas[this._areaQueue[cai]].onFocus(evt,step)){
+ //console.log("final target area:",this._currentAreaIdx);
+ return;
+ }
+ }
+ //console.log("tab out");
+ this.tabbingOut = true;
+ if(step < 0){
+ this._currentAreaIdx = -1;
+ dijitFocus.focus(this.grid.domNode);
+ }else{
+ this._currentAreaIdx = this._areaQueue.length;
+ dijitFocus.focus(this.grid.lastFocusNode);
+ }
+ },
+ _onMouseEvent: function(type, evt){
+ var lowercase = type.toLowerCase(),
+ handlers = this["_" + lowercase + "MouseEventHandlers"],
+ res = array.map(handlers, function(areaName){
+ return {
+ "area": areaName,
+ "idx": this._areas[areaName][lowercase + "MouseEventPlanner"](evt, handlers)
+ };
+ }, this).sort(function(a, b){
+ return b.idx - a.idx;
+ }),
+ resHandlers = array.map(res, function(handler){
+ return res.area;
+ }),
+ i = res.length;
+ while(--i >= 0){
+ if(this._areas[res[i].area]["on" + type + "MouseEvent"](evt, resHandlers) === false){
+ return;
+ }
+ }
+ },
+ contentMouseEvent: function(evt){
+ this._onMouseEvent("Content", evt);
+ },
+ headerMouseEvent: function(evt){
+ this._onMouseEvent("Header", evt);
+ },
+ initFocusView: function(){
+ // summary:
+ // Overwritten
+ this.focusView = this.grid.views.getFirstScrollingView() || this.focusView || this.grid.views.views[0];
+ this._bindAreaEvents();
+ },
+ isNavHeader: function(){
+ // summary:
+ // Overwritten
+ // Check whether currently navigating among column headers.
+ // return:
+ // true - focus is on a certain column header | false otherwise
+ return this._areaQueue[this._currentAreaIdx] == "header";
+ },
+ previousKey: function(e){
+ // summary:
+ // Overwritten
+ this.tab(-1,e);
+ },
+ nextKey: function(e){
+ // summary:
+ // Overwritten
+ this.tab(1,e);
+ },
+ setFocusCell: function(/* Object */inCell, /* Integer */inRowIndex){
+ // summary:
+ // Overwritten - focuses the given grid cell
+ if(inCell){
+ this.currentArea(this.grid.edit.isEditing() ? "editableCell" : "content", true);
+ //This is very slow when selecting cells!
+ //this.focusGridView();
+ this._focusifyCellNode(false);
+ this.cell = inCell;
+ this.rowIndex = inRowIndex;
+ this._focusifyCellNode(true);
+ }
+ this.grid.onCellFocus(this.cell, this.rowIndex);
+ },
+ doFocus: function(e){
+ // summary:
+ // Overwritten
+ // trap focus only for grid dom node
+ // do not focus for scrolling if grid is about to blur
+ if(e && e.target == e.currentTarget && !this.tabbingOut){
+ if(this._gridBlured){
+ this._gridBlured = false;
+ if(this._currentAreaIdx < 0 || this._currentAreaIdx >= this._areaQueue.length){
+ this.focusArea(0, e);
+ }else{
+ this.focusArea(this._currentAreaIdx, e);
+ }
+ }
+ }else{
+ this.tabbingOut = false;
+ }
+ event.stop(e);
+ },
+ _doBlur: function(){
+ this._gridBlured = true;
+ },
+ doLastNodeFocus: function(e){
+ // summary:
+ // Overwritten
+ if(this.tabbingOut){
+ this.tabbingOut = false;
+ }else{
+ this.focusArea(-1, e);
+ }
+ },
+ _delayedHeaderFocus: function(){
+ // summary:
+ // Overwritten
+ if(this.isNavHeader()){
+ this.focusHeader();
+ }
+ },
+ _delayedCellFocus: function(){
+ // summary:
+ // Overwritten
+ this.currentArea("header", true);
+ this.focusArea(this._currentAreaIdx);
+ },
+ _changeMenuBindNode: function(oldBindNode, newBindNode){
+ var hm = this.grid.headerMenu;
+ if(hm && this._contextMenuBindNode == oldBindNode){
+ hm.unBindDomNode(oldBindNode);
+ hm.bindDomNode(newBindNode);
+ this._contextMenuBindNode = newBindNode;
+ }
+ },
+ //---------------Header Area------------------------------------------
+ focusHeader: function(evt, step){ //need a further look why these changes to parent's
+ // summary:
+ // Overwritten
+ var didFocus = false;
+ this.inherited(arguments);
+ if(this._colHeadNode && html.style(this._colHeadNode, 'display') != "none"){
+ dijitFocus.focus(this._colHeadNode);
+ this._stopEvent(evt);
+ didFocus = true;
+ }
+ return didFocus;
+ },
+ _blurHeader: function(evt,step){
+ // summary:
+ // Overwritten
+ if(this._colHeadNode){
+ html.removeClass(this._colHeadNode, this.focusClass);
+ }
+ html.removeAttr(this.grid.domNode,"aria-activedescendant");
+ // reset contextMenu onto viewsHeaderNode so right mouse on header will invoke (see focusHeader)
+ this._changeMenuBindNode(this.grid.domNode,this.grid.viewsHeaderNode);
+ //moved here from nextKey
+ this._colHeadNode = this._colHeadFocusIdx = null;
+ return true;
+ },
+ _navHeader: function(rowStep, colStep, evt){
+ var colDir = colStep < 0 ? -1 : 1,
+ savedIdx = array.indexOf(this._findHeaderCells(), this._colHeadNode);
+ if(savedIdx >= 0 && (evt.shiftKey && evt.ctrlKey)){
+ this.colSizeAdjust(evt, savedIdx, colDir * 5);
+ return;
+ }
+ this.move(rowStep, colStep);
+ },
+ _onHeaderKeyDown: function(e, isBubble){
+ if(isBubble){
+ var dk = keys;
+ switch(e.keyCode){
+ case dk.ENTER:
+ case dk.SPACE:
+ var colIdx = this.getHeaderIndex();
+ if(colIdx >= 0 && !this.grid.pluginMgr.isFixedCell(e.cell)/*TODO*/){
+ this.grid.setSortIndex(colIdx, null, e);
+ event.stop(e);
+ }
+ break;
+ }
+ }
+ return true;
+ },
+ _setActiveColHeader: function(){
+ // summary:
+ // Overwritten
+ this.inherited(arguments);
+ //EDG now will decorate event on header key events, if no focus, the cell will be wrong
+ dijitFocus.focus(this._colHeadNode);
+ },
+ //---------------Content Area------------------------------------------
+ findAndFocusGridCell: function(){
+ // summary:
+ // Overwritten
+ this._focusContent();
+ },
+ _focusContent: function(evt,step){
+ var didFocus = true;
+ var isEmpty = (this.grid.rowCount === 0); // If grid is empty this.grid.rowCount == 0
+ if(this.isNoFocusCell() && !isEmpty){
+ //skip all the hidden cells
+ for(var i = 0, cell = this.grid.getCell(0); cell && cell.hidden; cell = this.grid.getCell(++i)){}
+ this.setFocusIndex(0, cell ? i : 0);
+ }else if(this.cell && !isEmpty){
+ if(this.focusView && !this.focusView.rowNodes[this.rowIndex]){
+ // if rowNode for current index is undefined (likely as a result of a sort and because of #7304)
+ // scroll to that row
+ this.grid.scrollToRow(this.rowIndex);
+ this.focusGrid();
+ }else{
+ this.setFocusIndex(this.rowIndex, this.cell.index);
+ }
+ }else{
+ didFocus = false;
+ }
+ if(didFocus){ this._stopEvent(evt); }
+ return didFocus;
+ },
+ _blurContent: function(evt,step){
+ this._focusifyCellNode(false);
+ return true;
+ },
+ _navContent: function(rowStep, colStep, evt){
+ if((this.rowIndex === 0 && rowStep < 0) || (this.rowIndex === this.grid.rowCount - 1 && rowStep > 0)){
+ return;
+ }
+ this._colHeadNode = null;
+ this.move(rowStep, colStep, evt);
+ if(evt){
+ event.stop(evt);
+ }
+ },
+ _onContentKeyDown: function(e, isBubble){
+ if(isBubble){
+ var dk = keys, s = this.grid.scroller;
+ switch(e.keyCode){
+ case dk.ENTER:
+ case dk.SPACE:
+ var g = this.grid;
+ if(g.indirectSelection){ break; }
+ g.selection.clickSelect(this.rowIndex, connect.isCopyKey(e), e.shiftKey);
+ g.onRowClick(e);
+ event.stop(e);
+ break;
+ case dk.PAGE_UP:
+ if(this.rowIndex !== 0){
+ if(this.rowIndex != s.firstVisibleRow + 1){
+ this._navContent(s.firstVisibleRow - this.rowIndex, 0);
+ }else{
+ this.grid.setScrollTop(s.findScrollTop(this.rowIndex - 1));
+ this._navContent(s.firstVisibleRow - s.lastVisibleRow + 1, 0);
+ }
+ event.stop(e);
+ }
+ break;
+ case dk.PAGE_DOWN:
+ if(this.rowIndex + 1 != this.grid.rowCount){
+ event.stop(e);
+ if(this.rowIndex != s.lastVisibleRow - 1){
+ this._navContent(s.lastVisibleRow - this.rowIndex - 1, 0);
+ }else{
+ this.grid.setScrollTop(s.findScrollTop(this.rowIndex + 1));
+ this._navContent(s.lastVisibleRow - s.firstVisibleRow - 1, 0);
+ }
+ event.stop(e);
+ }
+ break;
+ }
+ }
+ return true;
+ },
+ //------------------editable content area-------------------------
+ _blurFromEditableCell: false,
+ _isNavigating: false,
+ _navElems: null,
+ _focusEditableCell: function(evt,step){
+ var didFocus = false;
+ if(this._isNavigating){
+ didFocus = true;
+ }else if(this.grid.edit.isEditing() && this.cell){
+ if(this._blurFromEditableCell || !this._blurEditableCell(evt, step)){
+ this.setFocusIndex(this.rowIndex,this.cell.index);
+ didFocus = true;
+ }
+ this._stopEvent(evt);
+ }
+ return didFocus;
+ },
+ _applyEditableCell: function(){
+ try{
+ this.grid.edit.apply();
+ }catch(e){
+ console.warn("_FocusManager._applyEditableCell() error:", e);
+ }
+ },
+ _blurEditableCell: function(evt,step){
+ this._blurFromEditableCell = false;
+ if(this._isNavigating){
+ var toBlur = true;
+ if(evt){
+ var elems = this._navElems;
+ var firstElem = elems.lowest || elems.first;
+ var lastElem = elems.last || elems.highest || firstElem;
+ var target = has("ie") ? evt.srcElement : evt.target;
+ toBlur = target == (step > 0 ? lastElem : firstElem);
+ }
+ if(toBlur){
+ this._isNavigating = false;
+ html.setSelectable(this.cell.getNode(this.rowIndex), false);
+ return "content";
+ }
+ return false;
+ }else if(this.grid.edit.isEditing() && this.cell){
+ if(!step || typeof step != "number"){ return false; }
+ var dir = step > 0 ? 1 : -1;
+ var cc = this.grid.layout.cellCount;
+ for(var cell, col = this.cell.index + dir; col >= 0 && col < cc; col += dir){
+ cell = this.grid.getCell(col);
+ if(cell.editable){
+ this.cell = cell;
+ this._blurFromEditableCell = true;
+ return false;
+ }
+ }
+ if((this.rowIndex > 0 || dir == 1) && (this.rowIndex < this.grid.rowCount || dir == -1)){
+ this.rowIndex += dir;
+ //this.cell = this.grid.getCell(0); //There must be an editable cell, so this is not necessary.
+ for(col = dir > 0 ? 0 : cc - 1; col >= 0 && col < cc; col += dir){
+ cell = this.grid.getCell(col);
+ if(cell.editable){
+ this.cell = cell;
+ break;
+ }
+ }
+ this._applyEditableCell();
+ return "content";
+ }
+ }
+ return true;
+ },
+ _initNavigatableElems: function(){
+ this._navElems = dijitA11y._getTabNavigable(this.cell.getNode(this.rowIndex));
+ },
+ _onEditableCellKeyDown: function(e, isBubble){
+ var dk = keys,
+ g = this.grid,
+ edit = g.edit,
+ editApplied = false,
+ toPropagate = true;
+ switch(e.keyCode){
+ case dk.ENTER:
+ if(isBubble && edit.isEditing()){
+ this._applyEditableCell();
+ editApplied = true;
+ event.stop(e);
+ }
+ //intentional drop through
+ case dk.SPACE:
+ if(!isBubble && this._isNavigating){
+ toPropagate = false;
+ break;
+ }
+ if(isBubble){
+ if(!this.cell.editable && this.cell.navigatable){
+ this._initNavigatableElems();
+ var toFocus = this._navElems.lowest || this._navElems.first;
+ if(toFocus){
+ this._isNavigating = true;
+ html.setSelectable(this.cell.getNode(this.rowIndex), true);
+ dijitFocus.focus(toFocus);
+ event.stop(e);
+ this.currentArea("editableCell", true);
+ break;
+ }
+ }
+ if(!editApplied && !edit.isEditing() && !g.pluginMgr.isFixedCell(this.cell)){
+ edit.setEditCell(this.cell, this.rowIndex);
+ }
+ if(editApplied){
+ this.currentArea("content", true);
+ }else if(this.cell.editable && g.canEdit()){
+ this.currentArea("editableCell", true);
+ }
+ }
+ break;
+ case dk.PAGE_UP:
+ case dk.PAGE_DOWN:
+ if(!isBubble && edit.isEditing()){
+ //prevent propagating to content area
+ toPropagate = false;
+ }
+ break;
+ case dk.ESCAPE:
+ if(!isBubble){
+ edit.cancel();
+ this.currentArea("content", true);
+ }
+ }
+ return toPropagate;
+ },
+ _onEditableCellMouseEvent: function(evt){
+ if(evt.type == "click"){
+ var cell = this.cell || evt.cell;
+ if(cell && !cell.editable && cell.navigatable){
+ this._initNavigatableElems();
+ if(this._navElems.lowest || this._navElems.first){
+ var target = has("ie") ? evt.srcElement : evt.target;
+ if(target != cell.getNode(evt.rowIndex)){
+ this._isNavigating = true;
+ this.focusArea("editableCell", evt);
+ html.setSelectable(cell.getNode(evt.rowIndex), true);
+ dijitFocus.focus(target);
+ return false;
+ }
+ }
+ }else if(this.grid.singleClickEdit){
+ this.currentArea("editableCell");
+ return false;
+ }
+ }
+ return true;
+ }
+});
+}); \ No newline at end of file
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/_Plugin.js b/js/dojo-1.7.2/dojox/grid/enhanced/_Plugin.js
new file mode 100644
index 0000000..b0a4969
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/_Plugin.js
@@ -0,0 +1,172 @@
+//>>built
+define("dojox/grid/enhanced/_Plugin", [
+ "dojo/_base/kernel",
+ "dojo/_base/lang",
+ "dojo/_base/declare",
+ "dojo/_base/array",
+ "dojo/_base/connect",
+ "../EnhancedGrid"
+], function(dojo, lang, declare, array, connect){
+
+return declare("dojox.grid.enhanced._Plugin", null, {
+ // summary:
+ // Base class for all plugins.
+ //
+ // description:
+ // Provides common plugin functionality and basic life cycle management.
+ //
+ // Each concrete plugin must have a name field and is responsible for registering itself to the global plugin registry
+ // e.g. for dnd plugin:
+ // | dojox.grid.EnhancedGrid.registerPlugin("dnd" /*plugin name*/,
+ // | dojox.grid.enhanced.plugins.DnD /*full class name of a plugin*/
+ // | {"preInit": false, "dependency": ["nestedSorting"]} /*properties*/);
+ //
+ // [Keywords] of plugin properties(case sensitive)
+ // - "preInit": boolean, whether a plugin should be created before EnhancedGrid.postCreate(),
+ // false by default(plugins are created after EnhancedGrid.postCreate()).
+ // - "dependency": array or string, plugin(s) indicated by "dependency" will be created before the current one.
+ // Note: recursive cycle dependencies are not supported e.g. following dependency is invalid:
+ // pluginA -> pluginB -> pluginA
+ //
+ // example:
+ // 1. Customize default DnD plugin
+ // | dojo.declare("mygrid.MyDnD", dojox.grid.enhanced.plugins.DnD, {
+ // | name:"dnd" //still reuse the plugin name
+ // | constructor: function(inGrid, option){ ... }
+ // | });
+ // | dojox.grid.EnhancedGrid.registerPlugin("dnd", mygrid.MyDnD);
+ //
+ // 2. Add new plugin - PluginA
+ // | dojo.declare("mygrid.PluginA", dojox.grid.enhanced._Plugin, {
+ // | name: "pA",
+ // | constructor: function(inGrid, option){ ... }
+ // | });
+ // | dojox.grid.EnhancedGrid.registerPlugin("pA",mygrid.PluginA);
+ //
+ // 3. Use plugins
+ // | dojo.require("mygrid.MyDnD");
+ // | dojo.require("mygrid.PluginA");
+
+ // | <script type="text/javascript">
+ // | var grid = new dojox.grid.EnhancedGrid(
+ // | {plugins: {dnd:true, pA:true}, ... }, dojo.byId("gridDiv"));
+ // | grid.startup();
+ // | </script>
+
+ //name: String
+ // Plugin name, e.g. 'nestedSorting', 'dnd'...
+ name: 'plugin',
+
+ //grid: Object
+ // Grid that the plugin belongs to
+ grid: null,
+
+ //option: Object
+ // Plugin properties - leveraged with default and user specified properties.
+ // e.g. for dnd plugin, it may look like {"class": dojox.grid.enhanced.plugins.DnD, "dependency": ["nestedSorting"], ...}
+ option: {},
+
+ //_connects: Array
+ // List of all connections.
+ _connects: [],
+
+ //_subscribes: Array
+ // List of all subscribes.
+ _subscribes: [],
+
+ //privates: Object
+ // Private properties/methods shouldn't be mixin-ed anytime.
+ privates: {},
+
+ constructor: function(inGrid, option){
+ this.grid = inGrid;
+ this.option = option;
+ this._connects = [];
+ this._subscribes = [];
+ this.privates = lang.mixin({},dojox.grid.enhanced._Plugin.prototype);
+ this.init();
+ },
+
+ init: function(){},
+
+ onPreInit: function(){},
+
+ onPostInit: function(){},
+
+ onStartUp: function(){},
+
+ connect: function(obj, event, method){
+ // summary:
+ // Connects specified obj/event to specified method of this object.
+ // example:
+ // | var plugin = new dojox.grid.enhanced._Plugin(grid,"myPlugin",{...});
+ // | // when foo.bar() is called, call the listener in the scope of plugin
+ // | plugin.connect(foo, "bar", function(){
+ // | console.debug(this.xxx());//"this" - plugin scope
+ // | });
+ var conn = connect.connect(obj, event, this, method);
+ this._connects.push(conn);
+ return conn;
+ },
+ disconnect: function(handle){
+ // summary:
+ // Disconnects handle and removes it from connection list.
+ array.some(this._connects, function(conn, i, conns){
+ if(conn == handle){
+ connect.disconnect(handle);
+ conns.splice(i, 1);
+ return true;
+ }
+ return false;
+ });
+ },
+ subscribe: function(topic, method){
+ // summary:
+ // Subscribes to the specified topic and calls the specified method
+ // of this object.
+ // example:
+ // | var plugin = new dojox.grid.enhanced._Plugin(grid,"myPlugin",{...});
+ // | // when /my/topic is published, call the subscriber in the scope of plugin
+ // | // with passed parameter - "v"
+ // | plugin.subscribe("/my/topic", function(v){
+ // | console.debug(this.xxx(v));//"this" - plugin scope
+ // | });
+ var subscribe = connect.subscribe(topic, this, method);
+ this._subscribes.push(subscribe);
+ return subscribe;
+ },
+ unsubscribe: function(handle){
+ // summary:
+ // Un-subscribes handle and removes it from subscriptions list.
+ array.some(this._subscribes, function(subscribe, i, subscribes){
+ if(subscribe == handle){
+ connect.unsubscribe(handle);
+ subscribes.splice(i, 1);
+ return true;
+ }
+ return false;
+ });
+ },
+ onSetStore: function(store){
+ // summary:
+ // Called when store is changed.
+ },
+ destroy: function(){
+ // summary:
+ // Destroy all resources.
+ array.forEach(this._connects, connect.disconnect);
+ array.forEach(this._subscribes, connect.unsubscribe);
+ delete this._connects;
+ delete this._subscribes;
+ delete this.option;
+ delete this.privates;
+ //console.log('Plugin [', this.name, '].destroy() executed!');
+ }
+});
+
+//Each plugin is responsible for registering itself
+// e.g. for DnD plugin(name:'dnd'):
+// | dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.DnD/*class*/,
+// | {"dependency": ["nestedSorting"]}/*Optional - properties*/);
+
+}); \ No newline at end of file
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/_PluginManager.js b/js/dojo-1.7.2/dojox/grid/enhanced/_PluginManager.js
new file mode 100644
index 0000000..20e6e91
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/_PluginManager.js
@@ -0,0 +1,275 @@
+//>>built
+define("dojox/grid/enhanced/_PluginManager", [
+ "dojo/_base/kernel",
+ "dojo/_base/lang",
+ "dojo/_base/declare",
+ "dojo/_base/array",
+ "dojo/_base/connect",
+ "./_Events",
+ "./_FocusManager",
+ "../util"
+], function(dojo, lang, declare, array, connect, _Events, _FocusManager, util){
+
+var _PluginManager = declare("dojox.grid.enhanced._PluginManager", null, {
+ // summary:
+ // Singleton plugin manager
+ //
+ // description:
+ // Plugin manager is responsible for
+ // 1. Loading required plugins
+ // 2. Handling collaborat ion and dependencies among plugins
+ //
+ // Some plugin dependencies:
+ // - "columnReordering" attribute won't work when either DnD or Indirect Selections plugin is on.
+
+ //_options: Object
+ // Normalized plugin options
+ _options: null,
+
+ //_plugins: Array
+ // Plugin list
+ _plugins: null,
+
+ //_connects: Array
+ // Connection list
+ _connects: null,
+
+ constructor: function(inGrid){
+ this.grid = inGrid;
+ this._store = inGrid.store;
+ this._options = {};
+ this._plugins = [];
+ this._connects = [];
+ this._parseProps(this.grid.plugins);
+
+ inGrid.connect(inGrid, "_setStore", lang.hitch(this, function(store){
+ if(this._store !== store){
+ this.forEach('onSetStore', [store, this._store]);
+ this._store = store;
+ }
+ }));
+ },
+ startup: function(){
+ this.forEach('onStartUp');
+ },
+ preInit: function(){
+ // summary:
+ // Load appropriate plugins before DataGrid.postCreate().
+ // See EnhancedGrid.postCreate()
+ this.grid.focus.destroy();
+ this.grid.focus = new _FocusManager(this.grid);
+ new _Events(this.grid);//overwrite some default events of DataGrid
+ this._init(true);
+ this.forEach('onPreInit');
+ },
+ postInit: function(){
+ // summary:
+ // Load plugins after DataGrid.postCreate() - the default phase when plugins are created
+ // See EnhancedGrid.postCreate()
+ this._init(false);
+
+ array.forEach(this.grid.views.views, this._initView, this);
+ this._connects.push(connect.connect(this.grid.views, 'addView', lang.hitch(this, this._initView)));
+
+ if(this._plugins.length > 0){
+ var edit = this.grid.edit;
+ if(edit){ edit.styleRow = function(inRow){}; }
+ }
+ this.forEach('onPostInit');
+ },
+ forEach: function(func, args){
+ array.forEach(this._plugins, function(p){
+ if(!p || !p[func]){ return; }
+ p[func].apply(p, args ? args : []);
+ });
+ },
+ _parseProps: function(plugins){
+ // summary:
+ // Parse plugins properties
+ // plugins: Object
+ // Plugin properties defined by user
+ if(!plugins){ return; }
+
+ var p, loading = {}, options = this._options, grid = this.grid;
+ var registry = _PluginManager.registry;//global plugin registry
+ for(p in plugins){
+ if(plugins[p]){//filter out boolean false e.g. {p:false}
+ this._normalize(p, plugins, registry, loading);
+ }
+ }
+ //"columnReordering" attribute won't work when either DnD or Indirect Selections plugin is used.
+ if(options.dnd || options.indirectSelection){
+ options.columnReordering = false;
+ }
+
+ //mixin all plugin properties into Grid
+ lang.mixin(grid, options);
+ },
+ _normalize: function(p, plugins, registry, loading){
+ // summary:
+ // Normalize plugin properties especially the dependency chain
+ // p: String
+ // Plugin name
+ // plugins: Object
+ // Plugin properties set by user
+ // registry: Object
+ // The global plugin registry
+ // loading: Object
+ // Map for checking process state
+ if(!registry[p]){ throw new Error('Plugin ' + p + ' is required.');}
+
+ if(loading[p]){ throw new Error('Recursive cycle dependency is not supported.'); }
+
+ var options = this._options;
+ if(options[p]){ return options[p]; }
+
+ loading[p] = true;
+ //TBD - more strict conditions?
+ options[p] = lang.mixin({}, registry[p], lang.isObject(plugins[p]) ? plugins[p] : {});
+
+ var dependencies = options[p]['dependency'];
+ if(dependencies){
+ if(!lang.isArray(dependencies)){
+ dependencies = options[p]['dependency'] = [dependencies];
+ }
+ array.forEach(dependencies, function(dependency){
+ if(!this._normalize(dependency, plugins, registry, loading)){
+ throw new Error('Plugin ' + dependency + ' is required.');
+ }
+ }, this);
+ }
+ delete loading[p];
+ return options[p];
+ },
+ _init: function(pre){
+ // summary:
+ // Find appropriate plugins and load them
+ // pre: Boolean
+ // True - preInit | False - postInit(by default)
+ var p, preInit, options = this._options;
+ for(p in options){
+ preInit = options[p]['preInit'];
+ if((pre ? preInit : !preInit) && options[p]['class'] && !this.pluginExisted(p)){
+ this.loadPlugin(p);
+ }
+ }
+ },
+ loadPlugin: function(name){
+ // summary:
+ // Load required plugin("name")
+ // name: String
+ // Plugin name
+ // return: Object
+ // The newly loaded plugin
+ var option = this._options[name];
+ if(!option){ return null; } //return if no plugin option
+
+ var plugin = this.getPlugin(name);
+ if(plugin){ return plugin; } //return if plugin("name") already existed
+
+ var dependencies = option['dependency'];
+ array.forEach(dependencies, function(dependency){
+ if(!this.loadPlugin(dependency)){
+ throw new Error('Plugin ' + dependency + ' is required.');
+ }
+ }, this);
+ var cls = option['class'];
+ delete option['class'];//remove it for safety
+ plugin = new this.getPluginClazz(cls)(this.grid, option);
+ this._plugins.push(plugin);
+ return plugin;
+ },
+ _initView: function(view){
+ // summary:
+ // Overwrite several default behavior for each views(including _RowSelector view)
+ if(!view){ return; }
+ //add more events handler - _View
+ util.funnelEvents(view.contentNode, view, "doContentEvent", ['mouseup', 'mousemove']);
+ util.funnelEvents(view.headerNode, view, "doHeaderEvent", ['mouseup']);
+ },
+ pluginExisted: function(name){
+ // summary:
+ // Check if plugin("name") existed
+ // name: String
+ // Plugin name
+ // return: Boolean
+ // True - existed | False - not existed
+ return !!this.getPlugin(name);
+ },
+ getPlugin: function(name){
+ // summary:
+ // Get plugin("name")
+ // name: String
+ // Plugin name
+ // return: Object
+ // Plugin instance
+ var plugins = this._plugins;
+ name = name.toLowerCase();
+ for(var i = 0, len = plugins.length; i < len; i++){
+ if(name == plugins[i]['name'].toLowerCase()){
+ return plugins[i];
+ }
+ }
+ return null;
+ },
+ getPluginClazz: function(clazz){
+ // summary:
+ // Load target plugin which must be already required (require(..))
+ // clazz: class | String
+ // Plugin class
+ if(lang.isFunction(clazz)){
+ return clazz;//return if it's already a clazz
+ }
+ var errorMsg = 'Please make sure Plugin "' + clazz + '" is existed.';
+ try{
+ var cls = lang.getObject(clazz);
+ if(!cls){ throw new Error(errorMsg); }
+ return cls;
+ }catch(e){
+ throw new Error(errorMsg);
+ }
+ },
+ isFixedCell: function(cell){
+ // summary:
+ // See if target cell(column) is fixed or not.
+ // cell: Object
+ // Target cell(column)
+ // return: Boolean
+ // True - fixed| False - not fixed
+
+ //target cell can use Boolean attributes named "isRowSelector" or "fixedPos" to mark it's a fixed cell(column)
+ return cell && (cell.isRowSelector || cell.fixedPos);
+ },
+ destroy: function(){
+ // summary:
+ // Destroy all resources
+ array.forEach(this._connects, connect.disconnect);
+ this.forEach('destroy');
+ if(this.grid.unwrap){
+ this.grid.unwrap();
+ }
+ delete this._connects;
+ delete this._plugins;
+ delete this._options;
+ }
+});
+
+_PluginManager.registerPlugin = function(clazz, props){
+ // summary:
+ // Register plugins - TODO, a better way rather than global registry?
+ // clazz: String
+ // Full class name, e.g. "dojox.grid.enhanced.plugins.DnD"
+ // props: Object - Optional
+ // Plugin properties e.g. {"dependency": ["nestedSorting"], ...}
+ if(!clazz){
+ console.warn("Failed to register plugin, class missed!");
+ return;
+ }
+ var cls = _PluginManager;
+ cls.registry = cls.registry || {};
+ cls.registry[clazz.prototype.name]/*plugin name*/ = lang.mixin({"class": clazz}, (props ? props : {}));
+};
+
+return _PluginManager;
+
+}); \ No newline at end of file
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/EnhancedGrid.js
new file mode 100644
index 0000000..29bd64b
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/EnhancedGrid.js
@@ -0,0 +1,48 @@
+//>>built
+define("dojox/grid/enhanced/nls/EnhancedGrid", { root:
+//begin v1.x content
+({
+ singleSort: "Single Sort",
+ nestedSort: "Nested Sort",
+ ascending: "Click to sort Ascending",
+ descending: "Click to sort Descending",
+ sortingState: "${0} - ${1}",
+ unsorted: "Do not sort this column",
+ indirectSelectionRadio: "Row ${0}, single selection, radio box",
+ indirectSelectionCheckBox: "Row ${0}, multiple selection, check box",
+ selectAll: "Select all"
+})
+//end v1.x content
+,
+"ar": true,
+"ca": true,
+"cs": true,
+"da": true,
+"de": true,
+"el": true,
+"es": true,
+"fi": true,
+"fr": true,
+"he": true,
+"hr": true,
+"hu": true,
+"hr": true,
+"it": true,
+"ja": true,
+"kk": true,
+"ko": true,
+"nb": true,
+"nl": true,
+"pl": true,
+"pt": true,
+"pt-pt": true,
+"ro": true,
+"ru": true,
+"sk": true,
+"sl": true,
+"sv": true,
+"th": true,
+"tr": true,
+"zh": true,
+"zh-tw": true
+});
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/Filter.js
new file mode 100644
index 0000000..5bf56a4
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/Filter.js
@@ -0,0 +1,121 @@
+//>>built
+define("dojox/grid/enhanced/nls/Filter", { root:
+//begin v1.x content
+({
+ "clearFilterDialogTitle": "Clear Filter",
+ "filterDefDialogTitle": "Filter",
+ "ruleTitleTemplate": "Rule ${0}",
+
+ "conditionEqual": "equal",
+ "conditionNotEqual": "does not equal",
+ "conditionLess": "is less than",
+ "conditionLessEqual": "less than or equal",
+ "conditionLarger": "is greater than",
+ "conditionLargerEqual": "greater than or equal",
+ "conditionContains": "contains",
+ "conditionIs": "is",
+ "conditionStartsWith": "starts with",
+ "conditionEndWith": "ends with",
+ "conditionNotContain": "does not contain",
+ "conditionIsNot": "is not",
+ "conditionNotStartWith": "does not start with",
+ "conditionNotEndWith": "does not end with",
+ "conditionBefore": "before",
+ "conditionAfter": "after",
+ "conditionRange": "range",
+ "conditionIsEmpty": "is empty",
+
+ "all": "all",
+ "any": "any",
+ "relationAll": "all rules",
+ "waiRelAll": "Match all of the following rules:",
+ "relationAny": "any rules",
+ "waiRelAny": "Match any of the following rules:",
+ "relationMsgFront": "Match:",
+ "relationMsgTail": "",
+ "and": "and",
+ "or": "or",
+
+ "addRuleButton": "Add Rule",
+ "waiAddRuleButton": "Add a new rule",
+ "removeRuleButton": "Remove Rule",
+ "waiRemoveRuleButtonTemplate": "Remove rule ${0}",
+
+ "cancelButton": "Cancel",
+ "waiCancelButton": "Cancel this dialog",
+ "clearButton": "Clear",
+ "waiClearButton": "Clear the filter",
+ "filterButton": "Filter",
+ "waiFilterButton": "Submit the filter",
+
+ "columnSelectLabel": "Column",
+ "waiColumnSelectTemplate": "Column for rule ${0}",
+ "conditionSelectLabel": "Condition",
+ "waiConditionSelectTemplate": "Condition for rule ${0}",
+ "valueBoxLabel": "Value",
+ "waiValueBoxTemplate": "Enter value to filter for rule ${0}",
+
+ "rangeTo": "to",
+ "rangeTemplate": "from ${0} to ${1}",
+
+ "statusTipHeaderColumn": "Column",
+ "statusTipHeaderCondition": "Rules",
+ "statusTipTitle": "Filter Bar",
+ "statusTipMsg": "Click the filter bar here to filter on values in ${0}.",
+ "anycolumn": "any column",
+ "statusTipTitleNoFilter": "Filter Bar",
+ "statusTipTitleHasFilter": "Filter",
+ "statusTipRelAny": "Match any rules.",
+ "statusTipRelAll": "Match all rules.",
+
+ "defaultItemsName": "items",
+ "filterBarMsgHasFilterTemplate": "${0} of ${1} ${2} shown.",
+ "filterBarMsgNoFilterTemplate": "No filter applied",
+
+ "filterBarDefButton": "Define filter",
+ "waiFilterBarDefButton": "Filter the table",
+ "a11yFilterBarDefButton": "Filter...",
+ "filterBarClearButton": "Clear filter",
+ "waiFilterBarClearButton": "Clear the filter",
+ "closeFilterBarBtn": "Close filter bar",
+
+ "clearFilterMsg": "This will remove the filter and show all available records.",
+ "anyColumnOption": "Any Column",
+
+ "trueLabel": "True",
+ "falseLabel": "False"
+})
+//end v1.x content
+,
+"ar": true,
+"ca": true,
+"cs": true,
+"da": true,
+"de": true,
+"el": true,
+"es": true,
+"fi": true,
+"fr": true,
+"he": true,
+"hr": true,
+"hu": true,
+"hr": true,
+"it": true,
+"ja": true,
+"kk": true,
+"ko": true,
+"nb": true,
+"nl": true,
+"pl": true,
+"pt": true,
+"pt-pt": true,
+"ro": true,
+"ru": true,
+"sk": true,
+"sl": true,
+"sv": true,
+"th": true,
+"tr": true,
+"zh": true,
+"zh-tw": true
+});
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/Pagination.js
new file mode 100644
index 0000000..65eec33
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/Pagination.js
@@ -0,0 +1,56 @@
+//>>built
+define("dojox/grid/enhanced/nls/Pagination", { root:
+//begin v1.x content
+({
+ "descTemplate": "${2} - ${3} of ${1} ${0}",
+ "firstTip": "First Page",
+ "lastTip": "Last Page",
+ "nextTip": "Next Page",
+ "prevTip": "Previous Page",
+ "itemTitle": "items",
+ "singularItemTitle": "item",
+ "pageStepLabelTemplate": "Page ${0}",
+ "pageSizeLabelTemplate": "${0} items per page",
+ "allItemsLabelTemplate": "All items",
+ "gotoButtonTitle": "Go to a specific page",
+ "dialogTitle": "Go to Page",
+ "dialogIndication": "Specify the page number",
+ "pageCountIndication": " (${0} pages)",
+ "dialogConfirm": "Go",
+ "dialogCancel": "Cancel",
+ "all": "All"
+})
+//end v1.x content
+,
+"ar": true,
+"ca": true,
+"cs": true,
+"da": true,
+"de": true,
+"el": true,
+"es": true,
+"fi": true,
+"fr": true,
+"he": true,
+"hr": true,
+"hu": true,
+"hr": true,
+"it": true,
+"ja": true,
+"kk": true,
+"ko": true,
+"nb": true,
+"nl": true,
+"pl": true,
+"pt": true,
+"pt-pt": true,
+"ro": true,
+"ru": true,
+"sk": true,
+"sl": true,
+"sv": true,
+"th": true,
+"tr": true,
+"zh": true,
+"zh-tw": true
+});
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/ar/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ar/EnhancedGrid.js
new file mode 100644
index 0000000..f55709f
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ar/EnhancedGrid.js
@@ -0,0 +1,17 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/ar/EnhancedGrid", //begin v1.x content
+({
+ singleSort: "فرز منفرد",
+ nestedSort: "فرز متداخل",
+ ascending: "تصاعدي",
+ descending: "تنازلي",
+ sortingState: "${0} - ${1}",
+ unsorted: "عدم فرز هذا العمود",
+ indirectSelectionRadio: "الصف ${0}، اختيار منفرد، اختيار دائري",
+ indirectSelectionCheckBox: "الصف ${0}، اختيارات متعددة، مربع اختيار",
+ selectAll: "تحديد كل"
+})
+//end v1.x content
+);
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/ar/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ar/Filter.js
new file mode 100644
index 0000000..fa26b93
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ar/Filter.js
@@ -0,0 +1,90 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/ar/Filter", //begin v1.x content
+({
+ "clearFilterDialogTitle": "محو ترشيح البيانات",
+ "filterDefDialogTitle": "ترشيح البيانات",
+ "ruleTitleTemplate": "القاعدة ${0}",
+
+ "conditionEqual": "يساوي",
+ "conditionNotEqual": "لا يساوي",
+ "conditionLess": "أصغر من",
+ "conditionLessEqual": "أصغر من أو يساوي",
+ "conditionLarger": "أكبر من",
+ "conditionLargerEqual": "أكبر من أو يساوي",
+ "conditionContains": "يتضمن",
+ "conditionIs": "هو",
+ "conditionStartsWith": "يبدأ بالحروف",
+ "conditionEndWith": "ينتهي بالحروف",
+ "conditionNotContain": "لا يتضمن",
+ "conditionIsNot": "ليس",
+ "conditionNotStartWith": "لا يبدأ بالحروف",
+ "conditionNotEndWith": "لا ينتهي بالحروف",
+ "conditionBefore": "قبل",
+ "conditionAfter": "بعد",
+ "conditionRange": "المدى",
+ "conditionIsEmpty": "خالي",
+
+ "all": "كل",
+ "any": "أي",
+ "relationAll": "كل القواعد",
+ "waiRelAll": "مطابقة كل القواعد التالية:",
+ "relationAny": "أية قواعد",
+ "waiRelAny": "مطابقة أي من القواعد التالية:",
+ "relationMsgFront": "مطابقة",
+ "relationMsgTail": "",
+ "and": "and",
+ "or": "or",
+
+ "addRuleButton": "اضافة قاعدة",
+ "waiAddRuleButton": "اضافة قاعدة جديدة",
+ "removeRuleButton": "ازالة قاعدة",
+ "waiRemoveRuleButtonTemplate": "ازالة القاعدة ${0}",
+
+ "cancelButton": "الغاء",
+ "waiCancelButton": "الغاء مربع الحوار هذا",
+ "clearButton": "محو",
+ "waiClearButton": "محو ترشيح البيانات",
+ "filterButton": "ترشيح البيانات",
+ "waiFilterButton": "احالة ترشيح البيانات",
+
+ "columnSelectLabel": "العمود",
+ "waiColumnSelectTemplate": "العمود للقاعدة ${0}",
+ "conditionSelectLabel": "الشرط",
+ "waiConditionSelectTemplate": "الشرط للقاعدة ${0}",
+ "valueBoxLabel": "القيمة",
+ "waiValueBoxTemplate": "أدخل قيمة لترشيح البيانات للقاعدة ${0}",
+
+ "rangeTo": "الى",
+ "rangeTemplate": "من ${0} الى ${1}",
+
+ "statusTipHeaderColumn": "العمود",
+ "statusTipHeaderCondition": "القواعد",
+ "statusTipTitle": "خط ترشيح البيانات",
+ "statusTipMsg": "اضغط على خط ترشيح البيانات هنا لترشيح البيانات بناءا على القيم التي توجد في ${0}.",
+ "anycolumn": "أي عمود",
+ "statusTipTitleNoFilter": "خط ترشيح البيانات",
+ "statusTipTitleHasFilter": "ترشيح البيانات",
+
+ "defaultItemsName": "بنود",
+ "filterBarMsgHasFilterTemplate": "يتم عرض ${0} من ${1} ${2}.",
+ "filterBarMsgNoFilterTemplate": "لم يتم تطبيق أي ترشيح للبيانات.",
+
+ "filterBarDefButton": "تعريف ترشيح البيانات",
+ "waiFilterBarDefButton": "ترشيح بيانات الجدول",
+ "a11yFilterBarDefButton": "ترشيح البيانات...",
+ "filterBarClearButton": "محو ترشيح البيانات",
+ "waiFilterBarClearButton": "محو ترشيح البيانات",
+ "closeFilterBarBtn": "اغلاق خط ترشيح البيانات",
+
+ "clearFilterMsg": "سيؤدي هذا الى ازالة ترشيح البيانات وعرض كل السجلات المتاحة.",
+ "anyColumnOption": "أي عمود",
+
+ "trueLabel": "متحقق",
+ "falseLabel": "غير متحقق"
+})
+//end v1.x content
+);
+
+
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/ar/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ar/Pagination.js
new file mode 100644
index 0000000..ed7a329
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ar/Pagination.js
@@ -0,0 +1,24 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/ar/Pagination", //begin v1.x content
+({
+ "descTemplate": "${2} - ${3} من ${1} ${0}",
+ "firstTip": "الصفحة الأولى",
+ "lastTip": "الصفحة الأخيرة",
+ "nextTip": "الصفحة التالية",
+ "prevTip": "الصفحة السابقة",
+ "itemTitle": "بنود",
+ "pageStepLabelTemplate": "الصفحة ${0}",
+ "pageSizeLabelTemplate": "${0} بند/بنود بكل صفحة",
+ "allItemsLabelTemplate": "كل البنود",
+ "gotoButtonTitle": "اذهب الى الصفحة المحددة",
+ "dialogTitle": "اذهب الى الصفحة",
+ "dialogIndication": "حدد رقم الصفحة",
+ "pageCountIndication": " (${0} صفحات)",
+ "dialogConfirm": "بدء",
+ "dialogCancel": "الغاء",
+ "all": "كل"
+})
+//end v1.x content
+);
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/ca/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ca/EnhancedGrid.js
new file mode 100644
index 0000000..b5eb2c3
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ca/EnhancedGrid.js
@@ -0,0 +1,17 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/ca/EnhancedGrid", //begin v1.x content
+({
+ singleSort: "Ordre únic",
+ nestedSort: "Ordre imbricat",
+ ascending: "Ascendent",
+ descending: "Descendent",
+ sortingState: "${0} - ${1}",
+ unsorted: "No ordenis aquesta finestra",
+ indirectSelectionRadio: "Fila ${0}, selecció única, quadre d'opció",
+ indirectSelectionCheckBox: "Fila ${0}, selecció múltiple, quadre de selecció",
+ selectAll: "Seleccionar-ho tot"
+})
+//end v1.x content
+);
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/ca/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ca/Filter.js
new file mode 100644
index 0000000..f758b8d
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ca/Filter.js
@@ -0,0 +1,89 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/ca/Filter", //begin v1.x content
+({
+ "clearFilterDialogTitle": "Netejar el filtre",
+ "filterDefDialogTitle": "Filtre",
+ "ruleTitleTemplate": "Regla ${0}",
+
+ "conditionEqual": "igual que",
+ "conditionNotEqual": "no és igual que",
+ "conditionLess": "és menys que",
+ "conditionLessEqual": "és menys o igual que",
+ "conditionLarger": "és més que",
+ "conditionLargerEqual": "és més o igual que",
+ "conditionContains": "conté",
+ "conditionIs": "és",
+ "conditionStartsWith": "comença per",
+ "conditionEndWith": "acaba per",
+ "conditionNotContain": "no conté",
+ "conditionIsNot": "no és",
+ "conditionNotStartWith": "no comença per",
+ "conditionNotEndWith": "no acaba per",
+ "conditionBefore": "abans",
+ "conditionAfter": "després",
+ "conditionRange": "interval",
+ "conditionIsEmpty": "és buida",
+
+ "all": "tot",
+ "any": "qualsevol",
+ "relationAll": "totes les regles",
+ "waiRelAll": "Fes coincidir totes les regles següents:",
+ "relationAny": "qualsevol regla",
+ "waiRelAny": "Fes coincidir qualsevol de les regles següents:",
+ "relationMsgFront": "Coincidència",
+ "relationMsgTail": "",
+ "and": "i",
+ "or": "o",
+
+ "addRuleButton": "Afegeix regla",
+ "waiAddRuleButton": "Afegeix una regla nova",
+ "removeRuleButton": "Elimina regla",
+ "waiRemoveRuleButtonTemplate": "Elimina la regla ${0}",
+
+ "cancelButton": "Cancel·la",
+ "waiCancelButton": "Cancel·la aquest diàleg",
+ "clearButton": "Esborra",
+ "waiClearButton": "Neteja el filtre",
+ "filterButton": "Filtre",
+ "waiFilterButton": "Envia el filtre",
+
+ "columnSelectLabel": "Columna",
+ "waiColumnSelectTemplate": "Columna per a la regla ${0}",
+ "conditionSelectLabel": "Condició",
+ "waiConditionSelectTemplate": "Condició per a la regla ${0}",
+ "valueBoxLabel": "Valor",
+ "waiValueBoxTemplate": "Especifiqueu el valor de filtre per a la regla ${0}",
+
+ "rangeTo": "a",
+ "rangeTemplate": "de ${0} a ${1}",
+
+ "statusTipHeaderColumn": "Columna",
+ "statusTipHeaderCondition": "Regles",
+ "statusTipTitle": "Barra de filtre",
+ "statusTipMsg": "Feu clic aquí a la barra de filtre per filtrar els valors a ${0}.",
+ "anycolumn": "qualsevol columna",
+ "statusTipTitleNoFilter": "Barra de filtre",
+ "statusTipTitleHasFilter": "Filtre",
+ "statusTipRelAny": "Coincideix amb qualsevol regla.",
+ "statusTipRelAll": "Coincideix amb totes les regles.",
+
+ "defaultItemsName": "elements",
+ "filterBarMsgHasFilterTemplate": "Es mostren ${0} de ${1} ${2}.",
+ "filterBarMsgNoFilterTemplate": "No s'ha aplicat cap filtre",
+
+ "filterBarDefButton": "Defineix filtre",
+ "waiFilterBarDefButton": "Filtra la taula",
+ "a11yFilterBarDefButton": "Filtre...",
+ "filterBarClearButton": "Netejar filtre",
+ "waiFilterBarClearButton": "Neteja el filtre",
+ "closeFilterBarBtn": "Tancar la barra de filtre",
+
+ "clearFilterMsg": "Això eliminarà el filtre i mostrarà tots els registres disponibles.",
+ "anyColumnOption": "Qualsevol columna",
+
+ "trueLabel": "Cert",
+ "falseLabel": "Fals"
+})
+//end v1.x content
+);
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/ca/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ca/Pagination.js
new file mode 100644
index 0000000..74b7121
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ca/Pagination.js
@@ -0,0 +1,24 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/ca/Pagination", //begin v1.x content
+({
+ "descTemplate": "${2} - ${3} de ${1} ${0}",
+ "firstTip": "Primera pàgina",
+ "lastTip": "Darrera pàgina",
+ "nextTip": "Pàgina següent",
+ "prevTip": "Pàgina anterior",
+ "itemTitle": "elements",
+ "singularItemTitle": "element",
+ "pageStepLabelTemplate": "Pàgina ${0}",
+ "pageSizeLabelTemplate": "${0} elements per pàgina",
+ "allItemsLabelTemplate": "Tots els elements",
+ "gotoButtonTitle": "Vés a una pàgina específica",
+ "dialogTitle": "Vés a pàgina",
+ "dialogIndication": "Especifiqueu el número de pàgina",
+ "pageCountIndication": " (${0} pàgines)",
+ "dialogConfirm": "Vés-hi",
+ "dialogCancel": "Cancel·la",
+ "all": "tot"
+})
+//end v1.x content
+);
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/cs/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/cs/EnhancedGrid.js
new file mode 100644
index 0000000..86191d4
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/cs/EnhancedGrid.js
@@ -0,0 +1,17 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/cs/EnhancedGrid", //begin v1.x content
+({
+ singleSort: "Jednotlivé řazení",
+ nestedSort: "Vnořené řazení",
+ ascending: "Vzestupně",
+ descending: "Sestupně",
+ sortingState: "${0} - ${1}",
+ unsorted: "Neřadit tento sloupec",
+ indirectSelectionRadio: "Řádek ${0}, jednotlivý výběr, přepínač",
+ indirectSelectionCheckBox: "Řádek ${0}, vícenásobný výběr, zaškrtávací políčko",
+ selectAll: "Vybrat vše"
+})
+//end v1.x content
+);
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/cs/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/cs/Filter.js
new file mode 100644
index 0000000..6157fce
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/cs/Filter.js
@@ -0,0 +1,89 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/cs/Filter", //begin v1.x content
+({
+ "clearFilterDialogTitle": "Vymazat filtr",
+ "filterDefDialogTitle": "Filtr",
+ "ruleTitleTemplate": "Pravidlo ${0}",
+
+ "conditionEqual": "rovná se",
+ "conditionNotEqual": "nerovná se",
+ "conditionLess": "méně než",
+ "conditionLessEqual": "méně nebo rovno",
+ "conditionLarger": "více než",
+ "conditionLargerEqual": "více nebo rovno",
+ "conditionContains": "obsahuje",
+ "conditionIs": "je",
+ "conditionStartsWith": "začíná",
+ "conditionEndWith": "končí",
+ "conditionNotContain": "neobsahuje",
+ "conditionIsNot": "není",
+ "conditionNotStartWith": "nezačíná",
+ "conditionNotEndWith": "nekončí",
+ "conditionBefore": "před",
+ "conditionAfter": "po",
+ "conditionRange": "rozsah",
+ "conditionIsEmpty": "je prázdné",
+
+ "all": "vše",
+ "any": "jakékoli",
+ "relationAll": "všechna pravidla",
+ "waiRelAll": "Porovnat všechna tato pravidla:",
+ "relationAny": "jakákoli pravidla",
+ "waiRelAny": "Porovnat jakákoli z těchto pravidel:",
+ "relationMsgFront": "Shoda",
+ "relationMsgTail": "",
+ "and": "a",
+ "or": "nebo",
+
+ "addRuleButton": "Přidat pravidlo",
+ "waiAddRuleButton": "Přidat nové pravidlo",
+ "removeRuleButton": "Odebrat pravidlo",
+ "waiRemoveRuleButtonTemplate": "Odebrat pravidlo ${0}",
+
+ "cancelButton": "Storno",
+ "waiCancelButton": "Zrušit toto dialogové okno",
+ "clearButton": "Vymazat",
+ "waiClearButton": "Vymazat filtr",
+ "filterButton": "Filtr",
+ "waiFilterButton": "Odeslat filtr",
+
+ "columnSelectLabel": "Sloupec",
+ "waiColumnSelectTemplate": "Sloupec pro pravidlo ${0}",
+ "conditionSelectLabel": "Podmínka",
+ "waiConditionSelectTemplate": "Podmínka pro pravidlo ${0}",
+ "valueBoxLabel": "Hodnota",
+ "waiValueBoxTemplate": "Zadejte hodnotu do filtru pro pravidlo ${0}",
+
+ "rangeTo": "do",
+ "rangeTemplate": "z ${0} do ${1}",
+
+ "statusTipHeaderColumn": "Sloupec",
+ "statusTipHeaderCondition": "Pravidla",
+ "statusTipTitle": "Panel filtrování",
+ "statusTipMsg": "Klepněte zde na panel filtrování, abyste filtrovali hodnoty v ${0}.",
+ "anycolumn": "jakýkoli sloupec",
+ "statusTipTitleNoFilter": "Panel filtrování",
+ "statusTipTitleHasFilter": "Filtr",
+ "statusTipRelAny": "Vyhovovat libovolnému pravidlu",
+ "statusTipRelAll": "Vyhovovat všem pravidlům",
+
+ "defaultItemsName": "položek",
+ "filterBarMsgHasFilterTemplate": "${0} z ${1} ${2} zobrazeno.",
+ "filterBarMsgNoFilterTemplate": "Není použitý žádný filtr",
+
+ "filterBarDefButton": "Definovat filtr",
+ "waiFilterBarDefButton": "Filtrovat tabulku",
+ "a11yFilterBarDefButton": "Filtrovat...",
+ "filterBarClearButton": "Vymazat filtr",
+ "waiFilterBarClearButton": "Vymazat filtr",
+ "closeFilterBarBtn": "Zavřít panel filtrování",
+
+ "clearFilterMsg": "Tímto se odebere filtr a zobrazí všechny dostupné záznamy.",
+ "anyColumnOption": "Jakýkoli sloupec",
+
+ "trueLabel": "Pravda",
+ "falseLabel": "Nepravda"
+})
+//end v1.x content
+);
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/cs/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/cs/Pagination.js
new file mode 100644
index 0000000..2f8086d
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/cs/Pagination.js
@@ -0,0 +1,25 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/cs/Pagination", //begin v1.x content
+({
+ "descTemplate": "${2} - ${3} z ${1} ${0}",
+ "firstTip": "První stránka",
+ "lastTip": "Poslední stránka",
+ "nextTip": "Další stránka",
+ "prevTip": "Předchozí stránka",
+ "itemTitle": "položky",
+ "singularItemTitle": "položka",
+ "pageStepLabelTemplate": "Stránka ${0}",
+ "pageSizeLabelTemplate": "${0} položek na stránku",
+ "allItemsLabelTemplate": "Všechny položky",
+ "gotoButtonTitle": "Přejít na specifickou stránku",
+ "dialogTitle": "Přejít na stránku",
+ "dialogIndication": "Uvést číslo stránky",
+ "pageCountIndication": " (${0} stránky)",
+ "dialogConfirm": "Přejít",
+ "dialogCancel": "Storno",
+ "all": "vše"
+})
+//end v1.x content
+);
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/da/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/da/EnhancedGrid.js
new file mode 100644
index 0000000..331ab8f
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/da/EnhancedGrid.js
@@ -0,0 +1,17 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/da/EnhancedGrid", //begin v1.x content
+({
+ singleSort: "Enkelt sortering",
+ nestedSort: "Indlejret sortering",
+ ascending: "Stigende",
+ descending: "Faldende",
+ sortingState: "${0} - ${1}",
+ unsorted: "Sortér ikke denne kolonne",
+ indirectSelectionRadio: "Række ${0}, enkelt valg, valgknap",
+ indirectSelectionCheckBox: "Række ${0}, flere valg, afkrydsningsfelt",
+ selectAll: "Markér alle"
+})
+//end v1.x content
+);
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/da/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/da/Filter.js
new file mode 100644
index 0000000..c382275
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/da/Filter.js
@@ -0,0 +1,89 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/da/Filter", //begin v1.x content
+({
+ "clearFilterDialogTitle": "Ryd filter",
+ "filterDefDialogTitle": "Filter",
+ "ruleTitleTemplate": "Regel ${0}",
+
+ "conditionEqual": "lig med",
+ "conditionNotEqual": "er forskellig fra",
+ "conditionLess": "er mindre end",
+ "conditionLessEqual": "mindre end eller lig med",
+ "conditionLarger": "er større end",
+ "conditionLargerEqual": "større end eller lig med",
+ "conditionContains": "indeholder",
+ "conditionIs": "er",
+ "conditionStartsWith": "begynder med",
+ "conditionEndWith": "slutter med",
+ "conditionNotContain": "indeholder ikke",
+ "conditionIsNot": "er ikke",
+ "conditionNotStartWith": "begynder ikke med",
+ "conditionNotEndWith": "slutter ikke med",
+ "conditionBefore": "før",
+ "conditionAfter": "efter",
+ "conditionRange": "interval",
+ "conditionIsEmpty": "er tom",
+
+ "all": "alle",
+ "any": "vilkårlig",
+ "relationAll": "alle regler",
+ "waiRelAll": "Matcher alle følgende regler:",
+ "relationAny": "vilkårlige regler",
+ "waiRelAny": "Matcher en eller flere af følgende regler:",
+ "relationMsgFront": "Match",
+ "relationMsgTail": "",
+ "and": "og",
+ "or": "eller",
+
+ "addRuleButton": "Tilføj regel",
+ "waiAddRuleButton": "Tilføj en ny regel",
+ "removeRuleButton": "Fjern regel",
+ "waiRemoveRuleButtonTemplate": "Fjern reglen ${0}",
+
+ "cancelButton": "Annullér",
+ "waiCancelButton": "Annullér denne dialogboks",
+ "clearButton": "Ryd",
+ "waiClearButton": "Ryd filtret",
+ "filterButton": "Filter",
+ "waiFilterButton": "Send filtret",
+
+ "columnSelectLabel": "Kolonne",
+ "waiColumnSelectTemplate": "Kolonne for reglen ${0}",
+ "conditionSelectLabel": "Betingelse",
+ "waiConditionSelectTemplate": "Betingelse for reglen ${0}",
+ "valueBoxLabel": "Værdi",
+ "waiValueBoxTemplate": "Angiv værdi, der skal filtreres efter for reglen ${0}",
+
+ "rangeTo": "til",
+ "rangeTemplate": "fra ${0} til ${1}",
+
+ "statusTipHeaderColumn": "Kolonne",
+ "statusTipHeaderCondition": "Regler",
+ "statusTipTitle": "Filterlinje",
+ "statusTipMsg": "Klik på filterlinjen for at filtrere efter værdier i ${0}.",
+ "anycolumn": "vilkårlig kolonne",
+ "statusTipTitleNoFilter": "Filterlinje",
+ "statusTipTitleHasFilter": "Filter",
+ "statusTipRelAny": "Matcher en hvilken som helst regel.",
+ "statusTipRelAll": "Matcher alle regler.",
+
+ "defaultItemsName": "elementer",
+ "filterBarMsgHasFilterTemplate": "${0} af ${1} ${2} vist.",
+ "filterBarMsgNoFilterTemplate": "Intet filter anvendt",
+
+ "filterBarDefButton": "Definér filter",
+ "waiFilterBarDefButton": "Filtrér tabellen",
+ "a11yFilterBarDefButton": "Filtrér...",
+ "filterBarClearButton": "Ryd filter",
+ "waiFilterBarClearButton": "Ryd filtret",
+ "closeFilterBarBtn": "Luk filterlinje",
+
+ "clearFilterMsg": "Denne funktion fjerner filtret og viser alle tilgængelige records.",
+ "anyColumnOption": "Vilkårlig kolonne",
+
+ "trueLabel": "Sand",
+ "falseLabel": "Falsk"
+})
+//end v1.x content
+);
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/da/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/da/Pagination.js
new file mode 100644
index 0000000..0ebcfce
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/da/Pagination.js
@@ -0,0 +1,24 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/da/Pagination", //begin v1.x content
+({
+ "descTemplate": "${2} - ${3} af ${1} ${0}",
+ "firstTip": "Første side",
+ "lastTip": "Sidste side",
+ "nextTip": "Næste side",
+ "prevTip": "Forrige side",
+ "itemTitle": "elementer",
+ "singularItemTitle": "element",
+ "pageStepLabelTemplate": "Side ${0}",
+ "pageSizeLabelTemplate": "${0} elementer pr. side",
+ "allItemsLabelTemplate": "Alle elementer",
+ "gotoButtonTitle": "Gå til en bestemt side",
+ "dialogTitle": "Gå til side",
+ "dialogIndication": "Angiv sidetallet",
+ "pageCountIndication": " (${0} sider)",
+ "dialogConfirm": "Gå",
+ "dialogCancel": "Annullér",
+ "all": "alle"
+})
+//end v1.x content
+);
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/de/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/de/EnhancedGrid.js
new file mode 100644
index 0000000..120b559
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/de/EnhancedGrid.js
@@ -0,0 +1,17 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/de/EnhancedGrid", //begin v1.x content
+({
+ singleSort: "Einzelne Sortierung",
+ nestedSort: "Verschachtelte Sortierung",
+ ascending: "Aufsteigend",
+ descending: "Absteigend",
+ sortingState: "${0} - ${1}",
+ unsorted: "Diese Spalte nicht sortieren",
+ indirectSelectionRadio: "Zeile ${0}, einzelne Auswahl, Optionsfeld",
+ indirectSelectionCheckBox: "Zeile ${0}, Mehrfachauswahl, Kontrollkästchen",
+ selectAll: "Alles auswählen"
+})
+//end v1.x content
+);
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/de/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/de/Filter.js
new file mode 100644
index 0000000..8a1f295
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/de/Filter.js
@@ -0,0 +1,89 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/de/Filter", //begin v1.x content
+({
+ "clearFilterDialogTitle": "Filter löschen",
+ "filterDefDialogTitle": "Filter",
+ "ruleTitleTemplate": "Regel ${0}",
+
+ "conditionEqual": "gleich",
+ "conditionNotEqual": "ungleich",
+ "conditionLess": "kleiner als",
+ "conditionLessEqual": "kleiner-gleich",
+ "conditionLarger": "größer als",
+ "conditionLargerEqual": "größer-gleich",
+ "conditionContains": "enthält",
+ "conditionIs": "ist",
+ "conditionStartsWith": "beginnt mit",
+ "conditionEndWith": "endet mit",
+ "conditionNotContain": "enthält nicht",
+ "conditionIsNot": "ist nicht",
+ "conditionNotStartWith": "beginnt nicht mit",
+ "conditionNotEndWith": "endet nicht mit",
+ "conditionBefore": "vorher",
+ "conditionAfter": "danach",
+ "conditionRange": "Bereich",
+ "conditionIsEmpty": "ist leer",
+
+ "all": "alle",
+ "any": "beliebige",
+ "relationAll": "alle Regeln",
+ "waiRelAll": "Stimmt mit allen der folgenden Regeln überein:",
+ "relationAny": "beliebige Regeln",
+ "waiRelAny": "Stimmt mit einer beliebigen der folgenden Regeln überein:",
+ "relationMsgFront": "Übereinstimmung",
+ "relationMsgTail": "",
+ "and": "und",
+ "or": "oder",
+
+ "addRuleButton": "Regel hinzufügen",
+ "waiAddRuleButton": "Neue Regel hinzufügen",
+ "removeRuleButton": "Regel entfernen",
+ "waiRemoveRuleButtonTemplate": "Regel ${0} entfernen",
+
+ "cancelButton": "Abbrechen",
+ "waiCancelButton": "Diesen Dialog abbrechen",
+ "clearButton": "Löschen",
+ "waiClearButton": "Den Filter löschen",
+ "filterButton": "Filter",
+ "waiFilterButton": "Den Filter abschicken",
+
+ "columnSelectLabel": "Spalte",
+ "waiColumnSelectTemplate": "Spalte für Regel ${0}",
+ "conditionSelectLabel": "Bedingung",
+ "waiConditionSelectTemplate": "Bedingung für Regel ${0}",
+ "valueBoxLabel": "Wert",
+ "waiValueBoxTemplate": "Wert eingeben, um nach Regel ${0} zu filtern",
+
+ "rangeTo": "bis",
+ "rangeTemplate": "von ${0} bis ${1}",
+
+ "statusTipHeaderColumn": "Spalte",
+ "statusTipHeaderCondition": "Regeln",
+ "statusTipTitle": "Filterleiste",
+ "statusTipMsg": "Klicken Sie auf die Filterleiste hier, um nach Werten in ${0} zu filtern.",
+ "anycolumn": "beliebige Spalte",
+ "statusTipTitleNoFilter": "Filterleiste",
+ "statusTipTitleHasFilter": "Filter",
+ "statusTipRelAny": "Übereinstimmung mit einer oder mehreren beliebigen Regeln.",
+ "statusTipRelAll": "Übereinstimmung mit allen Regeln.",
+
+ "defaultItemsName": "Elemente",
+ "filterBarMsgHasFilterTemplate": "${0} von ${1} ${2} angezeigt.",
+ "filterBarMsgNoFilterTemplate": "Kein Filter angewendet",
+
+ "filterBarDefButton": "Filter definieren",
+ "waiFilterBarDefButton": "Die Tabelle filtern",
+ "a11yFilterBarDefButton": "Filter...",
+ "filterBarClearButton": "Filter löschen",
+ "waiFilterBarClearButton": "Den Filter löschen",
+ "closeFilterBarBtn": "Filterleiste schließen",
+
+ "clearFilterMsg": "Damit wird der Filter gelöscht und es werden alle verfügbaren Sätze angezeigt.",
+ "anyColumnOption": "Beliebige Spalte",
+
+ "trueLabel": "Wahr",
+ "falseLabel": "Falsch"
+})
+//end v1.x content
+);
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/de/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/de/Pagination.js
new file mode 100644
index 0000000..67f173e
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/de/Pagination.js
@@ -0,0 +1,25 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/de/Pagination", //begin v1.x content
+({
+ "descTemplate": "${2} - ${3} von ${1} ${0}",
+ "firstTip": "Erste Seite",
+ "lastTip": "Letzte Seite",
+ "nextTip": "Nächste Seite",
+ "prevTip": "Vorherige Seite",
+ "itemTitle": "Elemente",
+ "singularItemTitle": "Element",
+ "pageStepLabelTemplate": "Seite ${0}",
+ "pageSizeLabelTemplate": "${0} Elemente pro Seite",
+ "allItemsLabelTemplate": "Alle Elemente",
+ "gotoButtonTitle": "Bestimmte Seite aufrufen",
+ "dialogTitle": "Seite aufrufen",
+ "dialogIndication": "Seitenzahl angeben",
+ "pageCountIndication": " (${0} Seiten)",
+ "dialogConfirm": "Start",
+ "dialogCancel": "Abbrechen",
+ "all": "alle"
+})
+//end v1.x content
+);
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/el/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/el/EnhancedGrid.js
new file mode 100644
index 0000000..e1179cc
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/el/EnhancedGrid.js
@@ -0,0 +1,17 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/el/EnhancedGrid", //begin v1.x content
+({
+ singleSort: "Απλή ταξινόμηση",
+ nestedSort: "Ένθετη ταξινόμηση",
+ ascending: "Αύξουσα",
+ descending: "Φθίνουσα",
+ sortingState: "${0} - ${1}",
+ unsorted: "Χωρίς ταξινόμηση αυτής της στήλης",
+ indirectSelectionRadio: "Γραμμή ${0}, μονή επιλογή, κουμπί επιλογής",
+ indirectSelectionCheckBox: "Γραμμή ${0}, πολλαπλές επιλογές, τετραγωνίδιο επιλογής",
+ selectAll: "Επιλογή όλων"
+})
+//end v1.x content
+);
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/el/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/el/Filter.js
new file mode 100644
index 0000000..cf1a917
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/el/Filter.js
@@ -0,0 +1,89 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/el/Filter", //begin v1.x content
+({
+ "clearFilterDialogTitle": "Εκκαθάριση φίλτρου",
+ "filterDefDialogTitle": "Φίλτρο",
+ "ruleTitleTemplate": "Κανόνας ${0}",
+
+ "conditionEqual": "ίσο",
+ "conditionNotEqual": "όχι ίσο",
+ "conditionLess": "είναι μικρότερο από",
+ "conditionLessEqual": "μικρότερο ή ίσο",
+ "conditionLarger": "είναι μεγαλύτερο από",
+ "conditionLargerEqual": "μεγαλύτερο ή ίσο",
+ "conditionContains": "περιέχει",
+ "conditionIs": "είναι",
+ "conditionStartsWith": "αρχίζει από",
+ "conditionEndWith": "τελειώνει σε",
+ "conditionNotContain": "δεν περιέχει",
+ "conditionIsNot": "δεν είναι",
+ "conditionNotStartWith": "δεν αρχίζει από",
+ "conditionNotEndWith": "δεν τελειώνει σε",
+ "conditionBefore": "πριν",
+ "conditionAfter": "μετά",
+ "conditionRange": "εύρος",
+ "conditionIsEmpty": "είναι κενό",
+
+ "all": "όλα",
+ "any": "οποιοδήποτε",
+ "relationAll": "όλοι οι κανόνες",
+ "waiRelAll": "Αντιστοιχία με όλους τους παρακάτω κανόνες:",
+ "relationAny": "οποιοσδήποτε κανόνας",
+ "waiRelAny": "Αντιστοιχία με οποιονδήποτε από τους παρακάτω κανόνες:",
+ "relationMsgFront": "Αντιστοιχία",
+ "relationMsgTail": "",
+ "and": "και",
+ "or": "ή",
+
+ "addRuleButton": "Προσθήκη κανόνα",
+ "waiAddRuleButton": "Προσθήκη νέου κανόνα",
+ "removeRuleButton": "Αφαίρεση κανόνα",
+ "waiRemoveRuleButtonTemplate": "Αφαίρεση κανόνα ${0}",
+
+ "cancelButton": "Ακύρωση",
+ "waiCancelButton": "Ακύρωση αυτού του πλαισίου διαλόγου",
+ "clearButton": "Εκκαθάριση",
+ "waiClearButton": "Εκκαθάριση του φίλτρου",
+ "filterButton": "Φίλτρο",
+ "waiFilterButton": "Υποβολή του φίλτρου",
+
+ "columnSelectLabel": "Στήλη",
+ "waiColumnSelectTemplate": "Στήλη για τον κανόνα ${0}",
+ "conditionSelectLabel": "Συνθήκη",
+ "waiConditionSelectTemplate": "Συνθήκη για τον κανόνα ${0}",
+ "valueBoxLabel": "Τιμή",
+ "waiValueBoxTemplate": "Καταχωρήστε τιμή φίλτρου για τον κανόνα ${0}",
+
+ "rangeTo": "έως",
+ "rangeTemplate": "από ${0} έως ${1}",
+
+ "statusTipHeaderColumn": "Στήλη",
+ "statusTipHeaderCondition": "Κανόνες",
+ "statusTipTitle": "Γραμμή φίλτρου",
+ "statusTipMsg": "Πατήστε στη γραμμή φίλτρου για φιλτράρισμα με βάση τις τιμές στο ${0}.",
+ "anycolumn": "οποιαδήποτε στήλη",
+ "statusTipTitleNoFilter": "Γραμμή φίλτρου",
+ "statusTipTitleHasFilter": "Φίλτρο",
+ "statusTipRelAny": "Αντιστοιχία με οποιουσδήποτε κανόνες.",
+ "statusTipRelAll": "Αντιστοιχία με όλους τους κανόνες.",
+
+ "defaultItemsName": "στοιχεία",
+ "filterBarMsgHasFilterTemplate": "Εμφανίζονται ${0} από ${1} ${2}.",
+ "filterBarMsgNoFilterTemplate": "Δεν έχει εφαρμοστεί φίλτρο",
+
+ "filterBarDefButton": "Ορισμός φίλτρου",
+ "waiFilterBarDefButton": "Φιλτράρισμα του πίνακα",
+ "a11yFilterBarDefButton": "Φιλτράρισμα...",
+ "filterBarClearButton": "Εκκαθάριση φίλτρου",
+ "waiFilterBarClearButton": "Εκκαθάριση του φίλτρου",
+ "closeFilterBarBtn": "Κλείσιμο γραμμής φίλτρου",
+
+ "clearFilterMsg": "Με την επιλογή αυτή θα αφαιρεθεί το φίλτρο και θα εμφανιστούν όλες οι διαθέσιμες εγγραφές.",
+ "anyColumnOption": "Οποιαδήποτε στήλη",
+
+ "trueLabel": "Αληθές",
+ "falseLabel": "Ψευδές"
+})
+//end v1.x content
+);
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/el/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/el/Pagination.js
new file mode 100644
index 0000000..b03e995
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/el/Pagination.js
@@ -0,0 +1,24 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/el/Pagination", //begin v1.x content
+({
+ "descTemplate": "${2} - ${3} από ${1} ${0}",
+ "firstTip": "Πρώτη σελίδα",
+ "lastTip": "Τελευταία σελίδα",
+ "nextTip": "Επόμενη σελίδα",
+ "prevTip": "Προηγούμενη σελίδα",
+ "itemTitle": "στοιχεία",
+ "singularItemTitle": "στοιχείο",
+ "pageStepLabelTemplate": "Σελίδα ${0}",
+ "pageSizeLabelTemplate": "${0} στοιχεία ανά σελίδα",
+ "allItemsLabelTemplate": "Όλα τα στοιχεία",
+ "gotoButtonTitle": "Μετάβαση σε συγκεκριμένη σελίδα",
+ "dialogTitle": "Μετάβαση σε σελίδα",
+ "dialogIndication": "Καθορίστε τον αριθμό της σελίδας",
+ "pageCountIndication": " (${0} σελίδες)",
+ "dialogConfirm": "Μετάβαση",
+ "dialogCancel": "Ακύρωση",
+ "all": "όλα"
+})
+//end v1.x content
+);
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/es/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/es/EnhancedGrid.js
new file mode 100644
index 0000000..5886b73
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/es/EnhancedGrid.js
@@ -0,0 +1,17 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/es/EnhancedGrid", //begin v1.x content
+({
+ singleSort: "Orden único",
+ nestedSort: "Orden anidado",
+ ascending: "Ascendente",
+ descending: "Descendente",
+ sortingState: "${0} - ${1}",
+ unsorted: "No ordenar esta columna",
+ indirectSelectionRadio: "Fila ${0}, selección única, botón de selección",
+ indirectSelectionCheckBox: "Fila ${0}, selección múltiple, recuadro de selección",
+ selectAll: "Seleccionar todo"
+})
+//end v1.x content
+);
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/es/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/es/Filter.js
new file mode 100644
index 0000000..8994bb5
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/es/Filter.js
@@ -0,0 +1,89 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/es/Filter", //begin v1.x content
+({
+ "clearFilterDialogTitle": "Borrar filtro",
+ "filterDefDialogTitle": "Filtro",
+ "ruleTitleTemplate": "Regla ${0}",
+
+ "conditionEqual": "es igual a",
+ "conditionNotEqual": "no es igual a",
+ "conditionLess": "es menor que",
+ "conditionLessEqual": "es menor o igual que",
+ "conditionLarger": "es mayor que",
+ "conditionLargerEqual": "es mayor o igual que",
+ "conditionContains": "contiene",
+ "conditionIs": "es",
+ "conditionStartsWith": "empieza por",
+ "conditionEndWith": "acaba por",
+ "conditionNotContain": "no contiene",
+ "conditionIsNot": "no es",
+ "conditionNotStartWith": "no empieza por",
+ "conditionNotEndWith": "no acaba por",
+ "conditionBefore": "antes",
+ "conditionAfter": "después",
+ "conditionRange": "rango",
+ "conditionIsEmpty": "está vacío",
+
+ "all": "todas",
+ "any": "cualquiera",
+ "relationAll": "todas las reglas",
+ "waiRelAll": "Coincidir con todas las reglas siguientes:",
+ "relationAny": "cualquier regla",
+ "waiRelAny": "Coincidir con cualquiera de las reglas siguientes:",
+ "relationMsgFront": "Coincidir",
+ "relationMsgTail": "",
+ "and": "y",
+ "or": "o",
+
+ "addRuleButton": "Añadir regla",
+ "waiAddRuleButton": "Añadir una regla nueva",
+ "removeRuleButton": "Eliminar regla",
+ "waiRemoveRuleButtonTemplate": "Eliminar la regla ${0}",
+
+ "cancelButton": "Cancelar",
+ "waiCancelButton": "Cancelar este diálogo",
+ "clearButton": "Borrar",
+ "waiClearButton": "Borrar el filtro",
+ "filterButton": "Filtrar",
+ "waiFilterButton": "Enviar el filtro",
+
+ "columnSelectLabel": "Columna",
+ "waiColumnSelectTemplate": "Columna para la regla ${0}",
+ "conditionSelectLabel": "Condición",
+ "waiConditionSelectTemplate": "Condición para la regla ${0}",
+ "valueBoxLabel": "Valor",
+ "waiValueBoxTemplate": "Escriba el valor que se debe filtrar para la regla ${0}",
+
+ "rangeTo": "a",
+ "rangeTemplate": "de ${0} a ${1}",
+
+ "statusTipHeaderColumn": "Columna",
+ "statusTipHeaderCondition": "Reglas",
+ "statusTipTitle": "Barra de filtro",
+ "statusTipMsg": "Pulse aquí en la barra de filtro para filtrar por los valores de ${0}.",
+ "anycolumn": "cualquier columna",
+ "statusTipTitleNoFilter": "Barra de filtro",
+ "statusTipTitleHasFilter": "Filtro",
+ "statusTipRelAny": "Coincidir con cualquier regla.",
+ "statusTipRelAll": "Coincidir con todas las reglas.",
+
+ "defaultItemsName": "elementos",
+ "filterBarMsgHasFilterTemplate": "${0} de ${1} ${2} mostrados.",
+ "filterBarMsgNoFilterTemplate": "Ningún filtro aplicado",
+
+ "filterBarDefButton": "Definir filtro",
+ "waiFilterBarDefButton": "Filtrar la tabla",
+ "a11yFilterBarDefButton": "Filtrar...",
+ "filterBarClearButton": "Borrar filtro",
+ "waiFilterBarClearButton": "Borrar el filtro",
+ "closeFilterBarBtn": "Cerrar barra de filtro",
+
+ "clearFilterMsg": "Esto eliminará el filtro y mostrará todos los registros disponibles.",
+ "anyColumnOption": "Cualquier columna",
+
+ "trueLabel": "Verdadero",
+ "falseLabel": "Falso"
+})
+//end v1.x content
+);
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/es/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/es/Pagination.js
new file mode 100644
index 0000000..6bcc4da
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/es/Pagination.js
@@ -0,0 +1,25 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/es/Pagination", //begin v1.x content
+({
+ "descTemplate": "${2} - ${3} de ${1} ${0}",
+ "firstTip": "Primera página",
+ "lastTip": "Última página",
+ "nextTip": "Página siguiente",
+ "prevTip": "Página anterior",
+ "itemTitle": "elementos",
+ "singularItemTitle": "elemento",
+ "pageStepLabelTemplate": "Página ${0}",
+ "pageSizeLabelTemplate": "${0} elementos por página",
+ "allItemsLabelTemplate": "Todos los elementos",
+ "gotoButtonTitle": "Ir a una página específica",
+ "dialogTitle": "Ir a página",
+ "dialogIndication": "Especifique el número de página",
+ "pageCountIndication": " (${0} páginas)",
+ "dialogConfirm": "Ir",
+ "dialogCancel": "Cancelar",
+ "all": "todas"
+})
+//end v1.x content
+);
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/fi/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/fi/EnhancedGrid.js
new file mode 100644
index 0000000..307794a
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/fi/EnhancedGrid.js
@@ -0,0 +1,17 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/fi/EnhancedGrid", //begin v1.x content
+({
+ singleSort: "Yksinkertainen lajittelu",
+ nestedSort: "Sisäkkäinen lajittelu",
+ ascending: "Nouseva",
+ descending: "Laskeva",
+ sortingState: "${0} - ${1}",
+ unsorted: "Älä lajittele tätä saraketta",
+ indirectSelectionRadio: "Rivi ${0}, yksittäisvalinta, ruutu",
+ indirectSelectionCheckBox: "Rivi ${0}, monivalinta, valintaruutu",
+ selectAll: "Valitse kaikki"
+})
+//end v1.x content
+);
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/fi/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/fi/Filter.js
new file mode 100644
index 0000000..e2a5346
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/fi/Filter.js
@@ -0,0 +1,89 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/fi/Filter", //begin v1.x content
+({
+ "clearFilterDialogTitle": "Tyhjennä suodatin",
+ "filterDefDialogTitle": "Suodatin",
+ "ruleTitleTemplate": "Sääntö ${0}",
+
+ "conditionEqual": "yhtä suuri kuin",
+ "conditionNotEqual": "ei ole yhtä suuri kuin",
+ "conditionLess": "on pienempi kuin",
+ "conditionLessEqual": "pienempi tai yhtä suuri kuin",
+ "conditionLarger": "on suurempi kuin",
+ "conditionLargerEqual": "suurempi tai yhtä suuri kuin",
+ "conditionContains": "sisältää",
+ "conditionIs": "on",
+ "conditionStartsWith": "alussa on",
+ "conditionEndWith": "lopussa on",
+ "conditionNotContain": "ei sisällä",
+ "conditionIsNot": "ei ole",
+ "conditionNotStartWith": "alussa ei ole",
+ "conditionNotEndWith": "lopussa ei ole",
+ "conditionBefore": "ennen",
+ "conditionAfter": "jälkeen",
+ "conditionRange": "vaihtelualue",
+ "conditionIsEmpty": "on tyhjä",
+
+ "all": "kaikki",
+ "any": "mikä tahansa",
+ "relationAll": "kaikki säännöt",
+ "waiRelAll": "Täsmäytä kaikki seuraavat säännöt:",
+ "relationAny": "mitkä tahansa säännöt",
+ "waiRelAny": "Täsmäytä mitkä tahansa seuraavista säännöistä:",
+ "relationMsgFront": "Vastine",
+ "relationMsgTail": "",
+ "and": "ja",
+ "or": "tai",
+
+ "addRuleButton": "Lisää sääntö",
+ "waiAddRuleButton": "Lisää uusi sääntö",
+ "removeRuleButton": "Poista sääntö",
+ "waiRemoveRuleButtonTemplate": "Poista sääntö ${0}",
+
+ "cancelButton": "Peruuta",
+ "waiCancelButton": "Peruuta keskustelu",
+ "clearButton": "Tyhjennä",
+ "waiClearButton": "Tyhjennä suodatin",
+ "filterButton": "Suodata",
+ "waiFilterButton": "Lähetä suodatin",
+
+ "columnSelectLabel": "Sarake",
+ "waiColumnSelectTemplate": "Säännön ${0} sarake",
+ "conditionSelectLabel": "Ehto",
+ "waiConditionSelectTemplate": "Säännön ${0} ehto",
+ "valueBoxLabel": "Arvo",
+ "waiValueBoxTemplate": "Syötä säännön ${0} suodatettava arvo",
+
+ "rangeTo": "kohde",
+ "rangeTemplate": "lähde ${0}, kohde ${1}",
+
+ "statusTipHeaderColumn": "Sarake",
+ "statusTipHeaderCondition": "Säännöt",
+ "statusTipTitle": "Suodatinpalkki",
+ "statusTipMsg": "Napsauta suodatinpalkkia kohteen ${0} arvojen suodattamiseksi.",
+ "anycolumn": "mikä tahansa sarake",
+ "statusTipTitleNoFilter": "Suodatinpalkki",
+ "statusTipTitleHasFilter": "Suodatin",
+ "statusTipRelAny": "Vastaa jotakin sääntöä.",
+ "statusTipRelAll": "Vastaa kaikkia sääntöjä.",
+
+ "defaultItemsName": "nimikkeet",
+ "filterBarMsgHasFilterTemplate": "näkyvissä ${0} / ${1} ${2}.",
+ "filterBarMsgNoFilterTemplate": "Mikään suodatin ei ole käytössä",
+
+ "filterBarDefButton": "Määritä suodatin",
+ "waiFilterBarDefButton": "Suodata taulukko",
+ "a11yFilterBarDefButton": "Suodata...",
+ "filterBarClearButton": "Tyhjennä suodatin",
+ "waiFilterBarClearButton": "Tyhjennä suodatin",
+ "closeFilterBarBtn": "Sulje suodatinpalkki",
+
+ "clearFilterMsg": "Tämä toimenpide poistaa suodattimen ja näyttää kaikki saatavilla olevat tallenteet.",
+ "anyColumnOption": "Mikä tahansa sarake",
+
+ "trueLabel": "Tosi",
+ "falseLabel": "Epätosi"
+})
+//end v1.x content
+);
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/fi/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/fi/Pagination.js
new file mode 100644
index 0000000..beae77a
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/fi/Pagination.js
@@ -0,0 +1,24 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/fi/Pagination", //begin v1.x content
+({
+ "descTemplate": "${2} - ${3} / ${1} ${0}",
+ "firstTip": "Ensimmäinen sivu",
+ "lastTip": "Viimeinen sivu",
+ "nextTip": "Seuraava sivu",
+ "prevTip": "Edellinen sivu",
+ "itemTitle": "nimikkeet",
+ "singularItemTitle": "kohde",
+ "pageStepLabelTemplate": "Sivu ${0}",
+ "pageSizeLabelTemplate": "${0} nimikettä sivua kohti",
+ "allItemsLabelTemplate": "Kaikki nimikkeet",
+ "gotoButtonTitle": "Siirry tietylle sivulle",
+ "dialogTitle": "Siirry sivulle",
+ "dialogIndication": "Kirjoita sivunumero",
+ "pageCountIndication": " (${0} sivua)",
+ "dialogConfirm": "Siirry",
+ "dialogCancel": "Peruuta",
+ "all": "kaikki"
+})
+//end v1.x content
+);
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/fr/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/fr/EnhancedGrid.js
new file mode 100644
index 0000000..d1ee539
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/fr/EnhancedGrid.js
@@ -0,0 +1,17 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/fr/EnhancedGrid", //begin v1.x content
+({
+ singleSort: "Tri simple",
+ nestedSort: "Tri imbriqué",
+ ascending: "Croissant",
+ descending: "Décroissant",
+ sortingState: "${0} - ${1}",
+ unsorted: "Ne pas trier cette colonne",
+ indirectSelectionRadio: "Ligne ${0}, sélection unique, bouton radio",
+ indirectSelectionCheckBox: "Ligne ${0}, sélection multiple, case à cocher",
+ selectAll: "Tout sélectionner"
+})
+//end v1.x content
+);
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/fr/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/fr/Filter.js
new file mode 100644
index 0000000..9295240
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/fr/Filter.js
@@ -0,0 +1,89 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/fr/Filter", //begin v1.x content
+({
+ "clearFilterDialogTitle": "Effacer le filtre",
+ "filterDefDialogTitle": "Filtrer",
+ "ruleTitleTemplate": "Règle ${0}",
+
+ "conditionEqual": "égal",
+ "conditionNotEqual": "est différent de",
+ "conditionLess": "est inférieur à",
+ "conditionLessEqual": "inférieur ou égal",
+ "conditionLarger": "est supérieur à",
+ "conditionLargerEqual": "supérieur ou égal",
+ "conditionContains": "contient",
+ "conditionIs": "est",
+ "conditionStartsWith": "commence par",
+ "conditionEndWith": "se termine par",
+ "conditionNotContain": "ne contient pas",
+ "conditionIsNot": "n'est pas",
+ "conditionNotStartWith": "ne commence pas par",
+ "conditionNotEndWith": "ne se termine pas par",
+ "conditionBefore": "avant",
+ "conditionAfter": "après",
+ "conditionRange": "plage",
+ "conditionIsEmpty": "est vide",
+
+ "all": "tout",
+ "any": "n'importe quelle",
+ "relationAll": "toutes les règles",
+ "waiRelAll": "Satisfaire à toutes les règles suivantes :",
+ "relationAny": "n'importe quelles règles",
+ "waiRelAny": "Satisfaire à une quelconque des règles suivantes :",
+ "relationMsgFront": "Satisfaire",
+ "relationMsgTail": "",
+ "and": "et",
+ "or": "ou",
+
+ "addRuleButton": "Ajouter une règle",
+ "waiAddRuleButton": "Ajouter une nouvelle règle",
+ "removeRuleButton": "Supprimer la règle",
+ "waiRemoveRuleButtonTemplate": "Supprimer la règle ${0}",
+
+ "cancelButton": "Annuler",
+ "waiCancelButton": "Annuler cette boîte de dialogue",
+ "clearButton": "Effacer",
+ "waiClearButton": "Effacer le filtre",
+ "filterButton": "Filtrer",
+ "waiFilterButton": "Soumettre le filtre",
+
+ "columnSelectLabel": "Colonne",
+ "waiColumnSelectTemplate": "Colonne pour la règle ${0}",
+ "conditionSelectLabel": "Condition",
+ "waiConditionSelectTemplate": "Condition pour la règle ${0}",
+ "valueBoxLabel": "Valeur",
+ "waiValueBoxTemplate": "Saisir la valeur à filtrer pour la règle ${0}",
+
+ "rangeTo": "à",
+ "rangeTemplate": "de ${0} à ${1}",
+
+ "statusTipHeaderColumn": "Colonne",
+ "statusTipHeaderCondition": "Règles",
+ "statusTipTitle": "Barre de filtre",
+ "statusTipMsg": "Cliquer sur la barre de filtre ici pour filtrer sur les valeurs de ${0}.",
+ "anycolumn": "n'importe quelle colonne",
+ "statusTipTitleNoFilter": "Barre de filtre",
+ "statusTipTitleHasFilter": "Filtrer",
+ "statusTipRelAny": "Répondre à l'une des règles.",
+ "statusTipRelAll": "Réponde à toutes les régles.",
+
+ "defaultItemsName": "éléments",
+ "filterBarMsgHasFilterTemplate": "${0} sur ${1} ${2} affichés.",
+ "filterBarMsgNoFilterTemplate": "Aucun filtre appliqué",
+
+ "filterBarDefButton": "Définir le filtre",
+ "waiFilterBarDefButton": "Filtrer le tableau",
+ "a11yFilterBarDefButton": "Filtrer...",
+ "filterBarClearButton": "Effacer le filtre",
+ "waiFilterBarClearButton": "Effacer le filtre",
+ "closeFilterBarBtn": "Fermer la barre de filtre",
+
+ "clearFilterMsg": "Cela supprimera le filtre et affichera tous les enregistrements disponibles.",
+ "anyColumnOption": "N'importe quelle colonne",
+
+ "trueLabel": "Vrai",
+ "falseLabel": "Faux"
+})
+//end v1.x content
+);
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/fr/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/fr/Pagination.js
new file mode 100644
index 0000000..b9f614d
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/fr/Pagination.js
@@ -0,0 +1,25 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/fr/Pagination", //begin v1.x content
+({
+ "descTemplate": "${2} - ${3} sur ${1} ${0}",
+ "firstTip": "Première page",
+ "lastTip": "Dernière page",
+ "nextTip": "Page suivante",
+ "prevTip": "Page précédente",
+ "itemTitle": "éléments",
+ "singularItemTitle": "élément",
+ "pageStepLabelTemplate": "Page ${0}",
+ "pageSizeLabelTemplate": "${0} éléments par page",
+ "allItemsLabelTemplate": "Tous les éléments",
+ "gotoButtonTitle": "Accéder à une page spécifique",
+ "dialogTitle": "Accéder à la page",
+ "dialogIndication": "Indiquer le numéro de page",
+ "pageCountIndication": " (${0} pages)",
+ "dialogConfirm": "Accès",
+ "dialogCancel": "Annuler",
+ "all": "tout"
+})
+//end v1.x content
+);
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/he/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/he/EnhancedGrid.js
new file mode 100644
index 0000000..b161267
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/he/EnhancedGrid.js
@@ -0,0 +1,17 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/he/EnhancedGrid", //begin v1.x content
+({
+ singleSort: "מיון יחיד",
+ nestedSort: "מיון מקונן",
+ ascending: "עולה",
+ descending: "יורד",
+ sortingState: "${0} - ${1}",
+ unsorted: "אין למיין עמודה זו",
+ indirectSelectionRadio: "שורה ${0}, בחירה יחידה, תיבת בחירה",
+ indirectSelectionCheckBox: "שורה ${0}, בחירה מרובה, תיבת סימון",
+ selectAll: "בחירת הכל"
+})
+//end v1.x content
+);
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/he/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/he/Filter.js
new file mode 100644
index 0000000..5dd2eaa
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/he/Filter.js
@@ -0,0 +1,90 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/he/Filter", //begin v1.x content
+({
+ "clearFilterDialogTitle": "ניקוי מסנן",
+ "filterDefDialogTitle": "מסנן",
+ "ruleTitleTemplate": "כלל ${0}",
+
+ "conditionEqual": "שווה",
+ "conditionNotEqual": "לא שווה",
+ "conditionLess": "קטן מ",
+ "conditionLessEqual": "קטן או שווה",
+ "conditionLarger": "גדול מ",
+ "conditionLargerEqual": "גדול או שווה",
+ "conditionContains": "מכיל",
+ "conditionIs": "הוא",
+ "conditionStartsWith": "מתחיל ב",
+ "conditionEndWith": "מסתיים ב",
+ "conditionNotContain": "לא מכיל",
+ "conditionIsNot": "אינו",
+ "conditionNotStartWith": "לא מתחיל ב",
+ "conditionNotEndWith": "לא מסתיים ב",
+ "conditionBefore": "לפני",
+ "conditionAfter": "אחרי",
+ "conditionRange": "טווח",
+ "conditionIsEmpty": "ריק",
+
+ "all": "הכל",
+ "any": "כל",
+ "relationAll": "כל הכללים",
+ "waiRelAll": "התאמה לכל הכללים הבאים:",
+ "relationAny": "כל כלל שהוא",
+ "waiRelAny": "התאמה לכל אחד מהכללים הבאים:",
+ "relationMsgFront": "התאמה",
+ "relationMsgTail": "",
+ "and": "ו",
+ "or": "או",
+
+ "addRuleButton": "הוספת כלל",
+ "waiAddRuleButton": "הוספת כלל חדש",
+ "removeRuleButton": "סילוק כלל",
+ "waiRemoveRuleButtonTemplate": "סילוק כלל ${0}",
+
+ "cancelButton": "ביטול",
+ "waiCancelButton": "ביטול תיבת דו-שיח זו",
+ "clearButton": "ניקוי",
+ "waiClearButton": "ניקוי המסנן",
+ "filterButton": "מסנן",
+ "waiFilterButton": "הגשת המסנן",
+
+ "columnSelectLabel": "עמודה",
+ "waiColumnSelectTemplate": "עמודה עבור כלל ${0}",
+ "conditionSelectLabel": "תנאי",
+ "waiConditionSelectTemplate": "תנאי עבור כלל ${0}",
+ "valueBoxLabel": "ערך",
+ "waiValueBoxTemplate": "ציון ערך לסינון עבור כלל ${0}",
+
+ "rangeTo": "עד",
+ "rangeTemplate": "מ-${0} עד ${1}",
+
+ "statusTipHeaderColumn": "עמודה",
+ "statusTipHeaderCondition": "כללים",
+ "statusTipTitle": "סרגל סינון",
+ "statusTipMsg": "לחצו על סרגל הסינון כאן כדי לסנן ערכים ב-${0}.",
+ "anycolumn": "כל עמודה",
+ "statusTipTitleNoFilter": "סרגל סינון",
+ "statusTipTitleHasFilter": "מסנן",
+
+ "defaultItemsName": "פריטים",
+ "filterBarMsgHasFilterTemplate": "מוצג ${0} מתוך ${1} ${2}.",
+ "filterBarMsgNoFilterTemplate": "לא הוחל מסנן",
+
+ "filterBarDefButton": "הגדרת מסנן",
+ "waiFilterBarDefButton": "סינון הטבלה",
+ "a11yFilterBarDefButton": "מסנן...",
+ "filterBarClearButton": "ניקוי מסנן",
+ "waiFilterBarClearButton": "ניקוי המסנן",
+ "closeFilterBarBtn": "סגירת סרגל סינון",
+
+ "clearFilterMsg": "פעולה זו תגרום לסילוק המסנן ולהצגת כל הרשומות הזמינות.",
+ "anyColumnOption": "כל עמודה",
+
+ "trueLabel": "True",
+ "falseLabel": "False"
+})
+//end v1.x content
+);
+
+
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/he/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/he/Pagination.js
new file mode 100644
index 0000000..b343a44
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/he/Pagination.js
@@ -0,0 +1,24 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/he/Pagination", //begin v1.x content
+({
+ "descTemplate": "${2} - ${3} מתוך ${1} ${0}",
+ "firstTip": "עמוד ראשון",
+ "lastTip": "עמוד אחרון",
+ "nextTip": "העמוד הבא",
+ "prevTip": "העמוד הקודם",
+ "itemTitle": "פריטים",
+ "pageStepLabelTemplate": "עמוד ${0}",
+ "pageSizeLabelTemplate": "${0} פריטים לעמוד",
+ "allItemsLabelTemplate": "כל הפריטים",
+ "gotoButtonTitle": "מעבר לעמוד ספציפי",
+ "dialogTitle": "מעבר לעמוד",
+ "dialogIndication": "ציון מספר העמוד",
+ "pageCountIndication": " (${0} עמודים)",
+ "dialogConfirm": "ביצוע",
+ "dialogCancel": "ביטול",
+ "all": "הכל"
+})
+//end v1.x content
+);
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/hr/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/hr/EnhancedGrid.js
new file mode 100644
index 0000000..b97c618
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/hr/EnhancedGrid.js
@@ -0,0 +1,17 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/hr/EnhancedGrid", //begin v1.x content
+({
+ singleSort: "Jedan sort",
+ nestedSort: "Ugniježđeni sort",
+ ascending: "Uzlazno",
+ descending: "Silazno",
+ sortingState: "${0} - ${1}",
+ unsorted: "Ne sortiraj ovaj stupac",
+ indirectSelectionRadio: "Red ${0}, jedan izbor, radio kućica",
+ indirectSelectionCheckBox: "Red ${0}, više izbora, kontrolna kućica",
+ selectAll: "Izaberi sve"
+})
+//end v1.x content
+);
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/hr/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/hr/Filter.js
new file mode 100644
index 0000000..8494a50
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/hr/Filter.js
@@ -0,0 +1,89 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/hr/Filter", //begin v1.x content
+({
+ "clearFilterDialogTitle": "Brisanje filtera",
+ "filterDefDialogTitle": "Filter",
+ "ruleTitleTemplate": "Pravilo ${0}",
+
+ "conditionEqual": "jednako",
+ "conditionNotEqual": "nije jednako",
+ "conditionLess": "je manje od",
+ "conditionLessEqual": "manje ili jednako",
+ "conditionLarger": "je veće od",
+ "conditionLargerEqual": "veće ili jednako",
+ "conditionContains": "sadrži",
+ "conditionIs": "je",
+ "conditionStartsWith": "počinje sa",
+ "conditionEndWith": "završava sa",
+ "conditionNotContain": "ne sadrži",
+ "conditionIsNot": "nije",
+ "conditionNotStartWith": "ne počinje sa",
+ "conditionNotEndWith": "ne završava sa",
+ "conditionBefore": "prije",
+ "conditionAfter": "poslije",
+ "conditionRange": "raspon",
+ "conditionIsEmpty": "je prazan",
+
+ "all": "svi",
+ "any": "bilo koji",
+ "relationAll": "sva pravila",
+ "waiRelAll": "Usporedi sva sljedeća pravila:",
+ "relationAny": "bilo koja pravila",
+ "waiRelAny": "Usporedi bilo koje od sljedećih pravila:",
+ "relationMsgFront": "Odgovara",
+ "relationMsgTail": "",
+ "and": "i",
+ "or": "ili",
+
+ "addRuleButton": "Bilo koje pravilo",
+ "waiAddRuleButton": "Dodaj novo pravilo",
+ "removeRuleButton": "Ukloni pravilo",
+ "waiRemoveRuleButtonTemplate": "Ukloni pravilo ${0}",
+
+ "cancelButton": "Opoziv",
+ "waiCancelButton": "Opoziv ovog dijaloga",
+ "clearButton": "Obriši",
+ "waiClearButton": "Obriši filter",
+ "filterButton": "Filter",
+ "waiFilterButton": "Predaj filter",
+
+ "columnSelectLabel": "Stupac",
+ "waiColumnSelectTemplate": "Stupac za pravilo ${0}",
+ "conditionSelectLabel": "Uvjet",
+ "waiConditionSelectTemplate": "Uvjet za pravilo ${0}",
+ "valueBoxLabel": "Vrijednost",
+ "waiValueBoxTemplate": "Unesite vrijednost filtera za pravilo ${0}",
+
+ "rangeTo": "do",
+ "rangeTemplate": "od ${0} do ${1}",
+
+ "statusTipHeaderColumn": "Stupac",
+ "statusTipHeaderCondition": "Pravila",
+ "statusTipTitle": "Traka filtera",
+ "statusTipMsg": "Kliknite traku filtera za filtriranje po vrijednostima u ${0}.",
+ "anycolumn": "bilo koji stupac",
+ "statusTipTitleNoFilter": "Traka filtera",
+ "statusTipTitleHasFilter": "Filter",
+ "statusTipRelAny": "Usporedi bilo koja pravila.",
+ "statusTipRelAll": "Usporedi sva pravila.",
+
+ "defaultItemsName": "stavke",
+ "filterBarMsgHasFilterTemplate": "${0} od ${1} ${2} prikazano.",
+ "filterBarMsgNoFilterTemplate": "Filter nije primijenjen",
+
+ "filterBarDefButton": "Definiraj filter",
+ "waiFilterBarDefButton": "Filtriraj tablicu",
+ "a11yFilterBarDefButton": "Filtriraj...",
+ "filterBarClearButton": "Obriši filter",
+ "waiFilterBarClearButton": "Obriši filter",
+ "closeFilterBarBtn": "Zatvori traku filtera",
+
+ "clearFilterMsg": "Ovo uklanja filter i prikazuje sve raspoložive slogove.",
+ "anyColumnOption": "Bilo koji stupac",
+
+ "trueLabel": "True",
+ "falseLabel": "False"
+})
+//end v1.x content
+);
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/hr/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/hr/Pagination.js
new file mode 100644
index 0000000..4ddd71b
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/hr/Pagination.js
@@ -0,0 +1,25 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/hr/Pagination", //begin v1.x content
+({
+ "descTemplate": "${2} - ${3} od ${1} ${0}",
+ "firstTip": "Prva stranica",
+ "lastTip": "Zadnja stranica",
+ "nextTip": "Sljedeća stranica",
+ "prevTip": "Prethodna stranica",
+ "itemTitle": "stavke",
+ "singularItemTitle": "stavka",
+ "pageStepLabelTemplate": "Strana ${0}",
+ "pageSizeLabelTemplate": "${0} stavki po stranici",
+ "allItemsLabelTemplate": "Sve stavke",
+ "gotoButtonTitle": "Idi na određenu stranicu",
+ "dialogTitle": "Idi na stranicu",
+ "dialogIndication": "Navedite broj stranice",
+ "pageCountIndication": " (${0} stranica)",
+ "dialogConfirm": "Idi",
+ "dialogCancel": "Opoziv",
+ "all": "svi"
+})
+//end v1.x content
+);
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/hu/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/hu/EnhancedGrid.js
new file mode 100644
index 0000000..d8d4f9a
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/hu/EnhancedGrid.js
@@ -0,0 +1,17 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/hu/EnhancedGrid", //begin v1.x content
+({
+ singleSort: "Egyszerű rendezés",
+ nestedSort: "Beágyazott rendezés",
+ ascending: "Növekvő",
+ descending: "Csökkenő",
+ sortingState: "${0} - ${1}",
+ unsorted: "Ne rendezze ezt az oszlopot",
+ indirectSelectionRadio: "${0} sor, egyetlen kijelölés, választógomb",
+ indirectSelectionCheckBox: "${0} sor, több kijelölés, jelölőnégyzet",
+ selectAll: "Összes kijelölése"
+})
+//end v1.x content
+);
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/hu/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/hu/Filter.js
new file mode 100644
index 0000000..8dd5943
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/hu/Filter.js
@@ -0,0 +1,89 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/hu/Filter", //begin v1.x content
+({
+ "clearFilterDialogTitle": "Szűrő törlése",
+ "filterDefDialogTitle": "Szűrő",
+ "ruleTitleTemplate": "${0} szabály",
+
+ "conditionEqual": "egyenlő",
+ "conditionNotEqual": "nem egyenlő",
+ "conditionLess": "kisebb mint",
+ "conditionLessEqual": "kisebb vagy egyenlő",
+ "conditionLarger": "nagyobb mint",
+ "conditionLargerEqual": "nagyobb vagy egyenlő",
+ "conditionContains": "tartalmazza",
+ "conditionIs": "pontosan",
+ "conditionStartsWith": "kezdete",
+ "conditionEndWith": "vége",
+ "conditionNotContain": "nem tartalmazza",
+ "conditionIsNot": "nem",
+ "conditionNotStartWith": "nem kezdete",
+ "conditionNotEndWith": "nem vége",
+ "conditionBefore": "előtt",
+ "conditionAfter": "után",
+ "conditionRange": "tartomány",
+ "conditionIsEmpty": "üres",
+
+ "all": "mind",
+ "any": "bármely",
+ "relationAll": "minden szabály",
+ "waiRelAll": "Megfelel a következő összes szabálynak:",
+ "relationAny": "bármely szabály",
+ "waiRelAny": "Megfelel a következő bármely szabálynak:",
+ "relationMsgFront": "Egyezik",
+ "relationMsgTail": "",
+ "and": "és",
+ "or": "vagy",
+
+ "addRuleButton": "Szabály hozzáadása",
+ "waiAddRuleButton": "Új szabály hozzáadása",
+ "removeRuleButton": "Szabály eltávolítása",
+ "waiRemoveRuleButtonTemplate": "${0} szabály eltávolítása",
+
+ "cancelButton": "Mégse",
+ "waiCancelButton": "A párbeszédablak bezárása",
+ "clearButton": "Törlés",
+ "waiClearButton": "A szűrő törlése",
+ "filterButton": "Szűrő",
+ "waiFilterButton": "A szűrő elküldése",
+
+ "columnSelectLabel": "Oszlop",
+ "waiColumnSelectTemplate": "Oszlop a(z) ${0} szabályhoz",
+ "conditionSelectLabel": "Feltétel",
+ "waiConditionSelectTemplate": "Feltétel a(z) ${0} szabályhoz",
+ "valueBoxLabel": "Érték",
+ "waiValueBoxTemplate": "Írja be a szűrni kívánt értéket a(z) ${0} szabályhoz",
+
+ "rangeTo": "-",
+ "rangeTemplate": "${0} - ${1}",
+
+ "statusTipHeaderColumn": "Oszlop",
+ "statusTipHeaderCondition": "Szabályok",
+ "statusTipTitle": "Szűrősáv",
+ "statusTipMsg": "Kattintson a szűrősávra az értékek szűréséhez a következőben: ${0}.",
+ "anycolumn": "bármely oszlop",
+ "statusTipTitleNoFilter": "Szűrősáv",
+ "statusTipTitleHasFilter": "Szűrő",
+ "statusTipRelAny": "Bármely szabálynak megfelel.",
+ "statusTipRelAll": "Minden szabálynak megfelel.",
+
+ "defaultItemsName": "elemek",
+ "filterBarMsgHasFilterTemplate": "${0} / ${1} ${2} megjelenítve.",
+ "filterBarMsgNoFilterTemplate": "Nincs szűrő alkalmazva.",
+
+ "filterBarDefButton": "Szűrő meghatározása",
+ "waiFilterBarDefButton": "Táblázat szűrése",
+ "a11yFilterBarDefButton": "Szűrés...",
+ "filterBarClearButton": "Szűrő törlése",
+ "waiFilterBarClearButton": "A szűrő törlése",
+ "closeFilterBarBtn": "Szűrősáv bezárása",
+
+ "clearFilterMsg": "Eltávolítja a szűrőt és megjeleníti az összes elérhető rekordot.",
+ "anyColumnOption": "Bármely oszlop",
+
+ "trueLabel": "Igaz",
+ "falseLabel": "Hamis"
+})
+//end v1.x content
+);
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/hu/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/hu/Pagination.js
new file mode 100644
index 0000000..51ff037
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/hu/Pagination.js
@@ -0,0 +1,25 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/hu/Pagination", //begin v1.x content
+({
+ "descTemplate": "${2} - ${3} / ${1} ${0}",
+ "firstTip": "Első oldal",
+ "lastTip": "Utolsó oldal",
+ "nextTip": "Következő oldal",
+ "prevTip": "Előző oldal",
+ "itemTitle": "elemek",
+ "singularItemTitle": "elem",
+ "pageStepLabelTemplate": "${0}. oldal",
+ "pageSizeLabelTemplate": "${0} elem oldalanként",
+ "allItemsLabelTemplate": "Összes elem",
+ "gotoButtonTitle": "Ugrás adott oldalra",
+ "dialogTitle": "Ugrás adott oldalra",
+ "dialogIndication": "Adja meg az oldalszámot",
+ "pageCountIndication": " (${0} oldal)",
+ "dialogConfirm": "Mehet",
+ "dialogCancel": "Mégse",
+ "all": "mind"
+})
+//end v1.x content
+);
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/it/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/it/EnhancedGrid.js
new file mode 100644
index 0000000..430c858
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/it/EnhancedGrid.js
@@ -0,0 +1,17 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/it/EnhancedGrid", //begin v1.x content
+({
+ singleSort: "Ordine singolo",
+ nestedSort: "Ordine nidificato",
+ ascending: "Ascendente",
+ descending: "Decrescente",
+ sortingState: "${0} - ${1}",
+ unsorted: "Non ordinare questa colonna",
+ indirectSelectionRadio: "Riga ${0}, selezione singola, casella di opzione",
+ indirectSelectionCheckBox: "Riga ${0}, selezione multipla, casella di spunta",
+ selectAll: "Seleziona tutto"
+})
+//end v1.x content
+);
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/it/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/it/Filter.js
new file mode 100644
index 0000000..69d6a6b
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/it/Filter.js
@@ -0,0 +1,89 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/it/Filter", //begin v1.x content
+({
+ "clearFilterDialogTitle": "Cancella filtro",
+ "filterDefDialogTitle": "Filtro",
+ "ruleTitleTemplate": "Regola ${0}",
+
+ "conditionEqual": "uguale a",
+ "conditionNotEqual": "non uguale a",
+ "conditionLess": "minore di",
+ "conditionLessEqual": "minore di o uguale a",
+ "conditionLarger": "maggiore di",
+ "conditionLargerEqual": "maggiore di o uguale a",
+ "conditionContains": "contiene",
+ "conditionIs": "è",
+ "conditionStartsWith": "inizia con",
+ "conditionEndWith": "finisce con",
+ "conditionNotContain": "non contiene",
+ "conditionIsNot": "non è",
+ "conditionNotStartWith": "non inizia con",
+ "conditionNotEndWith": "non finisce con",
+ "conditionBefore": "prima",
+ "conditionAfter": "dopo",
+ "conditionRange": "intervallo",
+ "conditionIsEmpty": "è vuoto",
+
+ "all": "tutte",
+ "any": "qualsiasi",
+ "relationAll": "tutte le regole",
+ "waiRelAll": "Confronta con tutte le seguenti regole:",
+ "relationAny": "qualsiasi regola",
+ "waiRelAny": "Confronta con qualsiasi delle seguenti regole:",
+ "relationMsgFront": "Confronta",
+ "relationMsgTail": "",
+ "and": "e",
+ "or": "o",
+
+ "addRuleButton": "Aggiungi regola",
+ "waiAddRuleButton": "Aggiungi una nuova regola",
+ "removeRuleButton": "Rimuovi regola",
+ "waiRemoveRuleButtonTemplate": "Rimuovi regola ${0}",
+
+ "cancelButton": "Annulla",
+ "waiCancelButton": "Annulla questa finestra di dialogo",
+ "clearButton": "Cancella",
+ "waiClearButton": "Cancella il filtro",
+ "filterButton": "Filtro",
+ "waiFilterButton": "Inoltra il filtro",
+
+ "columnSelectLabel": "Colonna",
+ "waiColumnSelectTemplate": "Colonna per la regola ${0}",
+ "conditionSelectLabel": "Condizione",
+ "waiConditionSelectTemplate": "Condizione per la regola ${0}",
+ "valueBoxLabel": "Valore",
+ "waiValueBoxTemplate": "Immettere il valore da filtrare per la regola ${0}",
+
+ "rangeTo": "a",
+ "rangeTemplate": "da ${0} a ${1}",
+
+ "statusTipHeaderColumn": "Colonna",
+ "statusTipHeaderCondition": "Regole",
+ "statusTipTitle": "Barra di filtro",
+ "statusTipMsg": "Fare clic sulla barra di filtro qui per filtrare sui valori in ${0}.",
+ "anycolumn": "qualsiasi colonna",
+ "statusTipTitleNoFilter": "Barra di filtro",
+ "statusTipTitleHasFilter": "Filtro",
+ "statusTipRelAny": "Corrispondenza con qualsiasi regola.",
+ "statusTipRelAll": "Corrispondenza con tutte le regole.",
+
+ "defaultItemsName": "elementi",
+ "filterBarMsgHasFilterTemplate": "${0} di ${1} ${2} visualizzati.",
+ "filterBarMsgNoFilterTemplate": "Nessun filtro applicato",
+
+ "filterBarDefButton": "Definisci filtro",
+ "waiFilterBarDefButton": "Filtra la tabella",
+ "a11yFilterBarDefButton": "Filtro...",
+ "filterBarClearButton": "Cancella filtro",
+ "waiFilterBarClearButton": "Cancella il filtro",
+ "closeFilterBarBtn": "Chiudi barra di filtro",
+
+ "clearFilterMsg": "Questo rimuoverà il filtro e visualizzerà tutti i record disponibili.",
+ "anyColumnOption": "Qualsiasi colonna",
+
+ "trueLabel": "Vero",
+ "falseLabel": "Falso"
+})
+//end v1.x content
+);
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/it/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/it/Pagination.js
new file mode 100644
index 0000000..96d042c
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/it/Pagination.js
@@ -0,0 +1,25 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/it/Pagination", //begin v1.x content
+({
+ "descTemplate": "${2} - ${3} di ${1} ${0}",
+ "firstTip": "Prima pagina",
+ "lastTip": "Ultima pagina",
+ "nextTip": "Pagina successiva ",
+ "prevTip": "Pagina precedente ",
+ "itemTitle": "elementi ",
+ "singularItemTitle": "elemento",
+ "pageStepLabelTemplate": "Pagina ${0}",
+ "pageSizeLabelTemplate": "${0} elementi per pagina ",
+ "allItemsLabelTemplate": "Tutti gli elementi",
+ "gotoButtonTitle": "Vai a una pagina specifica ",
+ "dialogTitle": "Vai a pagina ",
+ "dialogIndication": "Specificare il numero di pagina",
+ "pageCountIndication": " (${0} pagine)",
+ "dialogConfirm": "Vai",
+ "dialogCancel": "Annulla",
+ "all": "tutte"
+})
+//end v1.x content
+);
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/ja/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ja/EnhancedGrid.js
new file mode 100644
index 0000000..851e550
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ja/EnhancedGrid.js
@@ -0,0 +1,16 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/ja/EnhancedGrid", //begin v1.x content
+({
+ singleSort: "単一ソート",
+ nestedSort: "ネスト・ソート",
+ ascending: "昇順",
+ descending: "降順",
+ sortingState: "${0} - ${1}",
+ unsorted: "この列をソートしない",
+ indirectSelectionRadio: "行 ${0}、単一選択、ラジオ・ボックス",
+ indirectSelectionCheckBox: "行 ${0}、複数選択、チェック・ボックス",
+ selectAll: "すべてを選択"
+})
+//end v1.x content
+);
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/ja/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ja/Filter.js
new file mode 100644
index 0000000..0366bfc
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ja/Filter.js
@@ -0,0 +1,89 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/ja/Filter", //begin v1.x content
+({
+ "clearFilterDialogTitle": "フィルターのクリア",
+ "filterDefDialogTitle": "フィルター",
+ "ruleTitleTemplate": "ルール ${0}",
+
+ "conditionEqual": "等しい",
+ "conditionNotEqual": "等しくない",
+ "conditionLess": "より小",
+ "conditionLessEqual": "より小または等しい",
+ "conditionLarger": "より大",
+ "conditionLargerEqual": "より大または等しい",
+ "conditionContains": "含む",
+ "conditionIs": "該当する",
+ "conditionStartsWith": "先頭",
+ "conditionEndWith": "末尾",
+ "conditionNotContain": "含まない",
+ "conditionIsNot": "該当しない",
+ "conditionNotStartWith": "先頭が異なる",
+ "conditionNotEndWith": "末尾が異なる",
+ "conditionBefore": "より前",
+ "conditionAfter": "より後",
+ "conditionRange": "範囲",
+ "conditionIsEmpty": "空である",
+
+ "all": "すべて",
+ "any": "いずれか",
+ "relationAll": "すべてのルール",
+ "waiRelAll": "次のルールのすべてに一致:",
+ "relationAny": "いずれかのルール",
+ "waiRelAny": "次のルールのいずれかに一致:",
+ "relationMsgFront": "一致",
+ "relationMsgTail": "",
+ "and": "かつ",
+ "or": "または",
+
+ "addRuleButton": "ルールの追加",
+ "waiAddRuleButton": "新規ルールの追加",
+ "removeRuleButton": "ルールの削除",
+ "waiRemoveRuleButtonTemplate": "ルール ${0} の削除",
+
+ "cancelButton": "キャンセル",
+ "waiCancelButton": "このダイアログをキャンセル",
+ "clearButton": "クリア",
+ "waiClearButton": "フィルターのクリア",
+ "filterButton": "フィルター",
+ "waiFilterButton": "フィルターの実行依頼",
+
+ "columnSelectLabel": "列",
+ "waiColumnSelectTemplate": "ルール ${0} の列",
+ "conditionSelectLabel": "条件",
+ "waiConditionSelectTemplate": "ルール ${0} の条件",
+ "valueBoxLabel": "値",
+ "waiValueBoxTemplate": "ルール ${0} を検出するフィルター操作のための値を入力",
+
+ "rangeTo": "範囲",
+ "rangeTemplate": "${0} から ${1} まで",
+
+ "statusTipHeaderColumn": "列",
+ "statusTipHeaderCondition": "ルール",
+ "statusTipTitle": "フィルター・バー",
+ "statusTipMsg": "このフィルター・バーをクリックして、${0} の値にフィルターを適用します。",
+ "anycolumn": "いずれかの列",
+ "statusTipTitleNoFilter": "フィルター・バー",
+ "statusTipTitleHasFilter": "フィルター",
+ "statusTipRelAny": "いずれかのルールに一致。",
+ "statusTipRelAll": "すべてのルールに一致。",
+
+ "defaultItemsName": "項目",
+ "filterBarMsgHasFilterTemplate": "${0}/${1} ${2} が表示されました。",
+ "filterBarMsgNoFilterTemplate": "フィルターが適用されていません",
+
+ "filterBarDefButton": "フィルターの定義",
+ "waiFilterBarDefButton": "表のフィルタリング",
+ "a11yFilterBarDefButton": "フィルター...",
+ "filterBarClearButton": "フィルターのクリア",
+ "waiFilterBarClearButton": "フィルターのクリア",
+ "closeFilterBarBtn": "フィルター・バーを閉じる",
+
+ "clearFilterMsg": "これによりフィルターが解除され、使用可能なレコードがすべて表示されます。",
+ "anyColumnOption": "いずれかの列",
+
+ "trueLabel": "True",
+ "falseLabel": "False"
+})
+//end v1.x content
+);
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/ja/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ja/Pagination.js
new file mode 100644
index 0000000..90cd698
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ja/Pagination.js
@@ -0,0 +1,24 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/ja/Pagination", //begin v1.x content
+({
+ "descTemplate": "${2} - ${3}/${1} ${0}",
+ "firstTip": "最初のページ",
+ "lastTip": "最後のページ",
+ "nextTip": "次のページ",
+ "prevTip": "前のページ",
+ "itemTitle": "項目",
+ "singularItemTitle": "項目",
+ "pageStepLabelTemplate": "ページ ${0}",
+ "pageSizeLabelTemplate": "ページ当たり ${0} 項目",
+ "allItemsLabelTemplate": "すべての項目",
+ "gotoButtonTitle": "特定のページに移動",
+ "dialogTitle": "ページの移動",
+ "dialogIndication": "ページ番号を指定してください",
+ "pageCountIndication": " (${0} ページ)",
+ "dialogConfirm": "実行",
+ "dialogCancel": "キャンセル",
+ "all": "すべて"
+})
+//end v1.x content
+);
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/kk/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/kk/EnhancedGrid.js
new file mode 100644
index 0000000..d1aeac2
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/kk/EnhancedGrid.js
@@ -0,0 +1,17 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/kk/EnhancedGrid", //begin v1.x content
+({
+ singleSort: "Бір рет сұрыптау",
+ nestedSort: "Кірістірілген сұрыптау",
+ ascending: "Артуы бойынша",
+ descending: "Кемуі бойынша",
+ sortingState: "${0} - ${1}",
+ unsorted: "Бұл бағанды сұрыптамау",
+ indirectSelectionRadio: "${0}-жол, жалғыз элементті таңдау, бір түймешікті таңдау тақтасы",
+ indirectSelectionCheckBox: "${0}-жол, бірнеше элементті таңдау, құсбелгі",
+ selectAll: "Барлығын таңдау"
+})
+//end v1.x content
+);
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/kk/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/kk/Filter.js
new file mode 100644
index 0000000..fbe4cd2
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/kk/Filter.js
@@ -0,0 +1,89 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/kk/Filter", //begin v1.x content
+({
+ "clearFilterDialogTitle": "Сүзгіні тазалау",
+ "filterDefDialogTitle": "Сүзгі",
+ "ruleTitleTemplate": "${0} ережесі",
+
+ "conditionEqual": "тең",
+ "conditionNotEqual": "тең емес",
+ "conditionLess": "аздау",
+ "conditionLessEqual": "аздау немесе тең",
+ "conditionLarger": "үлкендеу",
+ "conditionLargerEqual": "үлкендеу немесе тең",
+ "conditionContains": "құрамында бар",
+ "conditionIs": "–",
+ "conditionStartsWith": "басталады",
+ "conditionEndWith": "аяқталады",
+ "conditionNotContain": "құрамында жоқ",
+ "conditionIsNot": "емес",
+ "conditionNotStartWith": "басталмайды",
+ "conditionNotEndWith": "аяқталмайды",
+ "conditionBefore": "алдында",
+ "conditionAfter": "артында",
+ "conditionRange": "ауқым",
+ "conditionIsEmpty": "– бос",
+
+ "all": "барлығы",
+ "any": "кез келген",
+ "relationAll": "барлық ережелер",
+ "waiRelAll": "Барлық мына ережелерге сәйкес:",
+ "relationAny": "кез келген ереже",
+ "waiRelAny": "Мына ережелерге сәйкес:",
+ "relationMsgFront": "Сәйкес келу",
+ "relationMsgTail": "",
+ "and": "және",
+ "or": "немесе",
+
+ "addRuleButton": "Ереже қосу",
+ "waiAddRuleButton": "Жаңа ереже қосу",
+ "removeRuleButton": "Ережені алып тастау",
+ "waiRemoveRuleButtonTemplate": "${0} ережесін алып тастау",
+
+ "cancelButton": "Болдырмау",
+ "waiCancelButton": "Осы тілқатысу терезесін болдырмау",
+ "clearButton": "Тазалау ",
+ "waiClearButton": "Сүзгіні тазалау",
+ "filterButton": "Сүзгі",
+ "waiFilterButton": "Сүзгіні жіберу",
+
+ "columnSelectLabel": "Баған",
+ "waiColumnSelectTemplate": "${0} ережесінің бағаны",
+ "conditionSelectLabel": "Шарт",
+ "waiConditionSelectTemplate": "${0} ережесінің шарты",
+ "valueBoxLabel": "Мән",
+ "waiValueBoxTemplate": "${0} ережесін сүзу үшін мәнді енгізу",
+
+ "rangeTo": "неге",
+ "rangeTemplate": "${0} мәнінен ${1} мәніне",
+
+ "statusTipHeaderColumn": "Баған",
+ "statusTipHeaderCondition": "Ережелер",
+ "statusTipTitle": "Сүзгі тақтасы",
+ "statusTipMsg": "${0} ішіндегі мәндер бойынша сүзу үшін сүзгі тақтасын нұқыңыз.",
+ "anycolumn": "кез келген баған",
+ "statusTipTitleNoFilter": "Сүзгі тақтасы",
+ "statusTipTitleHasFilter": "Сүзгі",
+ "statusTipRelAny": "Кез келген ережелерді сәйкестендіріңіз.",
+ "statusTipRelAll": "Барлық ережелерді сәйкестендіріңіз.",
+
+ "defaultItemsName": "элементтер",
+ "filterBarMsgHasFilterTemplate": "${1} ${2} ішінен ${0} көрсетілді.",
+ "filterBarMsgNoFilterTemplate": "Сүзгі қолданылмады",
+
+ "filterBarDefButton": "Сүзгіні анықтау",
+ "waiFilterBarDefButton": "Кестені сүзу",
+ "a11yFilterBarDefButton": "Сүзгі...",
+ "filterBarClearButton": "Сүзгіні тазалау",
+ "waiFilterBarClearButton": "Сүзгіні тазалау",
+ "closeFilterBarBtn": "Сүзгі тақтасын жабу",
+
+ "clearFilterMsg": "Бұл сүзгіні жояды және барлық қол жетімді жазбаларды көрсетеді.",
+ "anyColumnOption": "Кез келген баған",
+
+ "trueLabel": "Шын",
+ "falseLabel": "Жалған"
+})
+//end v1.x content
+);
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/kk/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/kk/Pagination.js
new file mode 100644
index 0000000..baa56fe
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/kk/Pagination.js
@@ -0,0 +1,24 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/kk/Pagination", //begin v1.x content
+({
+ "descTemplate": "${1} ${0} элементтің ${2} - ${3} элементі",
+ "firstTip": "Бірінші бет",
+ "lastTip": "Соңғы бет",
+ "nextTip": "Келесі бет",
+ "prevTip": "Алдыңғы бет",
+ "itemTitle": "элементтер",
+ "singularItemTitle": "элемент",
+ "pageStepLabelTemplate": "Бет ${0}",
+ "pageSizeLabelTemplate": "Бетіне ${0} элемент",
+ "allItemsLabelTemplate": "Барлық элементтер",
+ "gotoButtonTitle": "Белгілі бір бетке өту",
+ "dialogTitle": "Бетке өту",
+ "dialogIndication": "Бет нөмірін көрсету",
+ "pageCountIndication": " (${0} бет)",
+ "dialogConfirm": "Өту",
+ "dialogCancel": "Болдырмау",
+ "all": "барлығы"
+})
+//end v1.x content
+);
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/ko/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ko/EnhancedGrid.js
new file mode 100644
index 0000000..9e0d07b
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ko/EnhancedGrid.js
@@ -0,0 +1,17 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/ko/EnhancedGrid", //begin v1.x content
+({
+ singleSort: "단일 정렬",
+ nestedSort: "중첩된 정렬",
+ ascending: "오름차순",
+ descending: "내림차순",
+ sortingState: "${0} - ${1}",
+ unsorted: "이 컬럼은 정렬하지 마십시오",
+ indirectSelectionRadio: "행 ${0}, 단일 선택, 라디오 상자",
+ indirectSelectionCheckBox: "행 ${0}, 다중 선택, 선택란",
+ selectAll: "모두 선택"
+})
+//end v1.x content
+);
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/ko/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ko/Filter.js
new file mode 100644
index 0000000..0b909b2
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ko/Filter.js
@@ -0,0 +1,89 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/ko/Filter", //begin v1.x content
+({
+ "clearFilterDialogTitle": "필터 지우기",
+ "filterDefDialogTitle": "필터",
+ "ruleTitleTemplate": "규칙 ${0}",
+
+ "conditionEqual": "같음",
+ "conditionNotEqual": "같지 않음",
+ "conditionLess": "미만",
+ "conditionLessEqual": "이하",
+ "conditionLarger": "초과",
+ "conditionLargerEqual": "이상",
+ "conditionContains": "포함",
+ "conditionIs": "다음과 같음",
+ "conditionStartsWith": "다음으로 시작",
+ "conditionEndWith": "다음으로 종료",
+ "conditionNotContain": "포함하지 않음",
+ "conditionIsNot": "다음이 아님",
+ "conditionNotStartWith": "다음으로 시작하지 않음",
+ "conditionNotEndWith": "다음으로 종료하지 않음",
+ "conditionBefore": "이전",
+ "conditionAfter": "이후",
+ "conditionRange": "범위",
+ "conditionIsEmpty": "다음이 비어있음",
+
+ "all": "모두",
+ "any": "임의",
+ "relationAll": "모든 규칙",
+ "waiRelAll": "다음 규칙에 모두 일치:",
+ "relationAny": "임의 규칙",
+ "waiRelAny": "다음 규칙 중에 일치:",
+ "relationMsgFront": "일치",
+ "relationMsgTail": "",
+ "and": "및",
+ "or": "또는",
+
+ "addRuleButton": "규칙 추가",
+ "waiAddRuleButton": "새 규칙 추가",
+ "removeRuleButton": "규칙 제거",
+ "waiRemoveRuleButtonTemplate": "${0} 규칙 제거",
+
+ "cancelButton": "취소",
+ "waiCancelButton": "이 대화 상자 취소",
+ "clearButton": "지우기",
+ "waiClearButton": "해당 필터 지우기",
+ "filterButton": "필터",
+ "waiFilterButton": "필터 제출",
+
+ "columnSelectLabel": "컬럼",
+ "waiColumnSelectTemplate": "${0} 규칙에 대한 컬럼",
+ "conditionSelectLabel": "조건",
+ "waiConditionSelectTemplate": "${0} 규칙에 대한 조건",
+ "valueBoxLabel": "값",
+ "waiValueBoxTemplate": "${0} 규칙에 대해 필터링할 값 입력",
+
+ "rangeTo": "다음에서 종료",
+ "rangeTemplate": "${0}에서 ${1}까지",
+
+ "statusTipHeaderColumn": "컬럼",
+ "statusTipHeaderCondition": "규칙",
+ "statusTipTitle": "필터 표시줄",
+ "statusTipMsg": "${0}의 값을 필터링하려면 이 필터 표시줄을 클릭하십시오.",
+ "anycolumn": "임의의 컬럼",
+ "statusTipTitleNoFilter": "필터 표시줄",
+ "statusTipTitleHasFilter": "필터",
+ "statusTipRelAny": "임의 규칙과 일치.",
+ "statusTipRelAll": "모든 규칙과 일치.",
+
+ "defaultItemsName": "항목",
+ "filterBarMsgHasFilterTemplate": "${0}/${1} ${2} 표시됨",
+ "filterBarMsgNoFilterTemplate": "적용된 필터 없음",
+
+ "filterBarDefButton": "필터 정의",
+ "waiFilterBarDefButton": "표 필터링",
+ "a11yFilterBarDefButton": "필터...",
+ "filterBarClearButton": "필터 지우기",
+ "waiFilterBarClearButton": "해당 필터 지우기",
+ "closeFilterBarBtn": "필터 표시줄 닫기",
+
+ "clearFilterMsg": "이로 인해 해당 필터가 제거되며 사용 가능한 모든 레코드가 표시됩니다.",
+ "anyColumnOption": "임의의 컬럼",
+
+ "trueLabel": "True",
+ "falseLabel": "False"
+})
+//end v1.x content
+);
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/ko/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ko/Pagination.js
new file mode 100644
index 0000000..39c88b1
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ko/Pagination.js
@@ -0,0 +1,25 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/ko/Pagination", //begin v1.x content
+({
+ "descTemplate": "${1} ${0} 중 ${2} - ${3}",
+ "firstTip": "첫 번째 페이지",
+ "lastTip": "마지막 페이지",
+ "nextTip": "다음 페이지",
+ "prevTip": "이전 페이지",
+ "itemTitle": "항목",
+ "singularItemTitle": "항목",
+ "pageStepLabelTemplate": "페이지 ${0}",
+ "pageSizeLabelTemplate": "페이지 당 ${0} 항목",
+ "allItemsLabelTemplate": "모든 항목",
+ "gotoButtonTitle": "특정 페이지로 이동",
+ "dialogTitle": "페이지로 이동",
+ "dialogIndication": "페이지 번호 지정",
+ "pageCountIndication": " (${0} 페이지)",
+ "dialogConfirm": "이동",
+ "dialogCancel": "취소",
+ "all": "모두"
+})
+//end v1.x content
+);
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/nb/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/nb/EnhancedGrid.js
new file mode 100644
index 0000000..660d223
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/nb/EnhancedGrid.js
@@ -0,0 +1,17 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/nb/EnhancedGrid", //begin v1.x content
+({
+ singleSort: "Enkeltsortering",
+ nestedSort: "Nestet sortering",
+ ascending: "Stigende",
+ descending: "Synkende",
+ sortingState: "${0} - ${1}",
+ unsorted: "Ikke sorter denne kolonnen",
+ indirectSelectionRadio: "Rad ${0}, enkeltvalg, valgknapp",
+ indirectSelectionCheckBox: "Rad ${0}, flervalg, avmerkingsboks",
+ selectAll: "Velg alle"
+})
+//end v1.x content
+);
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/nb/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/nb/Filter.js
new file mode 100644
index 0000000..5a58363
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/nb/Filter.js
@@ -0,0 +1,89 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/nb/Filter", //begin v1.x content
+({
+ "clearFilterDialogTitle": "Tøm filter",
+ "filterDefDialogTitle": "Filter",
+ "ruleTitleTemplate": "Regel ${0}",
+
+ "conditionEqual": "er lik",
+ "conditionNotEqual": "er ikke lik",
+ "conditionLess": "er mindre enn",
+ "conditionLessEqual": "mindre enn eller lik",
+ "conditionLarger": "er større enn",
+ "conditionLargerEqual": "større enn eller lik",
+ "conditionContains": "inneholder",
+ "conditionIs": "er",
+ "conditionStartsWith": "starter med",
+ "conditionEndWith": "slutter med",
+ "conditionNotContain": "inneholder ikke",
+ "conditionIsNot": "er ikke",
+ "conditionNotStartWith": "starter ikke med",
+ "conditionNotEndWith": "slutter ikke med",
+ "conditionBefore": "før",
+ "conditionAfter": "etter",
+ "conditionRange": "område",
+ "conditionIsEmpty": "er tom",
+
+ "all": "alle",
+ "any": "minst en",
+ "relationAll": "alle regler",
+ "waiRelAll": "Samsvar med alle disse reglene:",
+ "relationAny": "minst en regel",
+ "waiRelAny": "Samsvar med minst en av disse reglene:",
+ "relationMsgFront": "Samsvar med",
+ "relationMsgTail": "",
+ "and": "og",
+ "or": "eller",
+
+ "addRuleButton": "Legg til regel",
+ "waiAddRuleButton": "Legg til en ny regel",
+ "removeRuleButton": "Fjern regel",
+ "waiRemoveRuleButtonTemplate": "Fjern regel ${0}",
+
+ "cancelButton": "Avbryt",
+ "waiCancelButton": "Avbryt denne dialogboksen",
+ "clearButton": "Tøm",
+ "waiClearButton": "Tøm filteret",
+ "filterButton": "Filtrer",
+ "waiFilterButton": "Send filteret",
+
+ "columnSelectLabel": "Kolonne",
+ "waiColumnSelectTemplate": "Kolonne for regel ${0}",
+ "conditionSelectLabel": "Betingelse",
+ "waiConditionSelectTemplate": "Betingelse for regel ${0}",
+ "valueBoxLabel": "Verdi",
+ "waiValueBoxTemplate": "Oppgi verdi som skal filtreres for regel ${0}",
+
+ "rangeTo": "til",
+ "rangeTemplate": "fra ${0} til ${1}",
+
+ "statusTipHeaderColumn": "Kolonne",
+ "statusTipHeaderCondition": "Regler",
+ "statusTipTitle": "Filterlinje",
+ "statusTipMsg": "Klikk på filterlinjen her for å filtrere på verdiene i ${0}.",
+ "anycolumn": "enhver kolonne",
+ "statusTipTitleNoFilter": "Filterlinje",
+ "statusTipTitleHasFilter": "Filter",
+ "statusTipRelAny": "Samsvar med minst en regel.",
+ "statusTipRelAll": "Samsvar med alle regler.",
+
+ "defaultItemsName": "elementer",
+ "filterBarMsgHasFilterTemplate": "${0} av ${1} ${2} vist.",
+ "filterBarMsgNoFilterTemplate": "Ikke brukt filter",
+
+ "filterBarDefButton": "Definer filter",
+ "waiFilterBarDefButton": "Filtrer tabellen",
+ "a11yFilterBarDefButton": "Filtrer...",
+ "filterBarClearButton": "Tøm filter",
+ "waiFilterBarClearButton": "Tøm filteret",
+ "closeFilterBarBtn": "Lukk filterlinjen",
+
+ "clearFilterMsg": "Dette fjerner filteret og viser alle tilgjengelige poster.",
+ "anyColumnOption": "Minst en kolonne",
+
+ "trueLabel": "Sann",
+ "falseLabel": "Usann"
+})
+//end v1.x content
+);
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/nb/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/nb/Pagination.js
new file mode 100644
index 0000000..ae43787
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/nb/Pagination.js
@@ -0,0 +1,24 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/nb/Pagination", //begin v1.x content
+({
+ "descTemplate": "${2} - ${3} av ${1} ${0}",
+ "firstTip": "Første side",
+ "lastTip": "Siste side",
+ "nextTip": "Neste side",
+ "prevTip": "Forrige side",
+ "itemTitle": "elementer",
+ "singularItemTitle": "element",
+ "pageStepLabelTemplate": "Side ${0}",
+ "pageSizeLabelTemplate": "${0} elementer per side",
+ "allItemsLabelTemplate": "Alle elementer",
+ "gotoButtonTitle": "Gå til en bestemt side",
+ "dialogTitle": "Gå til side",
+ "dialogIndication": "Oppgi sidetallet",
+ "pageCountIndication": " (${0} sider)",
+ "dialogConfirm": "Utfør",
+ "dialogCancel": "Avbryt",
+ "all": "alle"
+})
+//end v1.x content
+);
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/nl/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/nl/EnhancedGrid.js
new file mode 100644
index 0000000..d74e154
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/nl/EnhancedGrid.js
@@ -0,0 +1,17 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/nl/EnhancedGrid", //begin v1.x content
+({
+ singleSort: "Enkelvoudig sorteren",
+ nestedSort: "Genest sorteren",
+ ascending: "Oplopend",
+ descending: "Aflopend",
+ sortingState: "${0} - ${1}",
+ unsorted: "Deze kolom niet sorteren",
+ indirectSelectionRadio: "Rij ${0}, enkele selectie, keuzerondje",
+ indirectSelectionCheckBox: "Rij ${0}, meerdere selecties, selectievakje",
+ selectAll: "Alles selecteren"
+})
+//end v1.x content
+);
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/nl/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/nl/Filter.js
new file mode 100644
index 0000000..4456d4b
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/nl/Filter.js
@@ -0,0 +1,89 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/nl/Filter", //begin v1.x content
+({
+ "clearFilterDialogTitle": "Filter wissen",
+ "filterDefDialogTitle": "Filteren",
+ "ruleTitleTemplate": "Regel ${0}",
+
+ "conditionEqual": "gelijk aan",
+ "conditionNotEqual": "niet gelijk aan",
+ "conditionLess": "is kleiner dan",
+ "conditionLessEqual": "kleiner dan of gelijk aan",
+ "conditionLarger": "is groter dan",
+ "conditionLargerEqual": "groter dan of gelijk aan",
+ "conditionContains": "bevat",
+ "conditionIs": "is",
+ "conditionStartsWith": "begint met",
+ "conditionEndWith": "eindigt op",
+ "conditionNotContain": "bevat niet",
+ "conditionIsNot": "is niet",
+ "conditionNotStartWith": "begint niet met",
+ "conditionNotEndWith": "eindigt niet op",
+ "conditionBefore": "voor",
+ "conditionAfter": "na",
+ "conditionRange": "bereik",
+ "conditionIsEmpty": "is leeg",
+
+ "all": "alle",
+ "any": "een of meer",
+ "relationAll": "alle regels",
+ "waiRelAll": "Voldoen aan al deze regels:",
+ "relationAny": "een of meer regels",
+ "waiRelAny": "Voldoen aan een van deze regels:",
+ "relationMsgFront": "Voldoen aan",
+ "relationMsgTail": "",
+ "and": "en",
+ "or": "of",
+
+ "addRuleButton": "Regel toevoegen",
+ "waiAddRuleButton": "Een nieuwe regel toevoegen",
+ "removeRuleButton": "Regel verwijderen",
+ "waiRemoveRuleButtonTemplate": "Regel ${0} verwijderen",
+
+ "cancelButton": "Annuleren",
+ "waiCancelButton": "Dit dialoogvenster annuleren",
+ "clearButton": "Leegmaken",
+ "waiClearButton": "Het filter wissen",
+ "filterButton": "Filteren",
+ "waiFilterButton": "Het filter verzenden",
+
+ "columnSelectLabel": "Kolom",
+ "waiColumnSelectTemplate": "Kolom voor regel ${0}",
+ "conditionSelectLabel": "Voorwaarde",
+ "waiConditionSelectTemplate": "Voorwaarde voor regel ${0}",
+ "valueBoxLabel": "Waarde",
+ "waiValueBoxTemplate": "Geef een filterwaarde op voor regel ${0}",
+
+ "rangeTo": "tot",
+ "rangeTemplate": "van ${0} tot ${1}",
+
+ "statusTipHeaderColumn": "Kolom",
+ "statusTipHeaderCondition": "Regels",
+ "statusTipTitle": "Filterbalk",
+ "statusTipMsg": "Klik hier op de filterbalk om te filteren op waarden in ${0}.",
+ "anycolumn": "een kolom",
+ "statusTipTitleNoFilter": "Filterbalk",
+ "statusTipTitleHasFilter": "Filter",
+ "statusTipRelAny": "Voldoen aan een van de regels.",
+ "statusTipRelAll": "Voldoen aan alle regels.",
+
+ "defaultItemsName": "items",
+ "filterBarMsgHasFilterTemplate": "${0} van ${1} ${2} afgebeeld.",
+ "filterBarMsgNoFilterTemplate": "Geen filter toegepast",
+
+ "filterBarDefButton": "Filter definiëren",
+ "waiFilterBarDefButton": "De tabel filteren",
+ "a11yFilterBarDefButton": "Filteren...",
+ "filterBarClearButton": "Filter wissen",
+ "waiFilterBarClearButton": "Het filter wissen",
+ "closeFilterBarBtn": "Filterbalk sluiten",
+
+ "clearFilterMsg": "Hiermee verwijdert u het filter en worden alle beschikbare records afgebeeld.",
+ "anyColumnOption": "Een kolom",
+
+ "trueLabel": "Waar",
+ "falseLabel": "Onwaar"
+})
+//end v1.x content
+);
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/nl/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/nl/Pagination.js
new file mode 100644
index 0000000..c18a2ea
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/nl/Pagination.js
@@ -0,0 +1,25 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/nl/Pagination", //begin v1.x content
+({
+ "descTemplate": "${2} - ${3} van ${1} ${0}",
+ "firstTip": "Eerste pagina",
+ "lastTip": "Laatste pagina",
+ "nextTip": "Volgende pagina",
+ "prevTip": "Vorige pagina",
+ "itemTitle": "items",
+ "singularItemTitle": "item",
+ "pageStepLabelTemplate": "Pagina ${0}",
+ "pageSizeLabelTemplate": "${0} items per pagina",
+ "allItemsLabelTemplate": "Alle items",
+ "gotoButtonTitle": "Ga naar bepaalde pagina",
+ "dialogTitle": "Ga naar pagina",
+ "dialogIndication": "Geef het paginanummer op",
+ "pageCountIndication": " (${0} pagina's)",
+ "dialogConfirm": "Go",
+ "dialogCancel": "Annuleren",
+ "all": "alle"
+})
+//end v1.x content
+);
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/pl/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/pl/EnhancedGrid.js
new file mode 100644
index 0000000..0fe4701
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/pl/EnhancedGrid.js
@@ -0,0 +1,17 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/pl/EnhancedGrid", //begin v1.x content
+({
+ singleSort: "Pojedyncze sortowanie",
+ nestedSort: "Zagnieżdżone sortowanie",
+ ascending: "Rosnąco",
+ descending: "Malejąco",
+ sortingState: "${0} - ${1}",
+ unsorted: "Nie sortuj tej kolumny",
+ indirectSelectionRadio: "Wiersz ${0}, pojedynczy wybór, zestaw przełączników",
+ indirectSelectionCheckBox: "Wiersz ${0}, wybór wielokrotny, pole wyboru",
+ selectAll: "Wybierz wszystko"
+})
+//end v1.x content
+);
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/pl/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/pl/Filter.js
new file mode 100644
index 0000000..16737ae
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/pl/Filter.js
@@ -0,0 +1,89 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/pl/Filter", //begin v1.x content
+({
+ "clearFilterDialogTitle": "Wyczyść filtr",
+ "filterDefDialogTitle": "Filtr",
+ "ruleTitleTemplate": "Reguła ${0}",
+
+ "conditionEqual": "równe",
+ "conditionNotEqual": "różne od",
+ "conditionLess": "mniejsze od",
+ "conditionLessEqual": "mniejsze lub równe",
+ "conditionLarger": "większe od",
+ "conditionLargerEqual": "większe lub równe",
+ "conditionContains": "zawiera",
+ "conditionIs": "jest",
+ "conditionStartsWith": "zaczyna się od",
+ "conditionEndWith": "kończy się na",
+ "conditionNotContain": "nie zawiera",
+ "conditionIsNot": "nie jest",
+ "conditionNotStartWith": "nie zaczyna się od",
+ "conditionNotEndWith": "nie kończy się na",
+ "conditionBefore": "przed",
+ "conditionAfter": "po",
+ "conditionRange": "zakres",
+ "conditionIsEmpty": "jest pusty",
+
+ "all": "wszystkie",
+ "any": "dowolne",
+ "relationAll": "wszystkie reguły",
+ "waiRelAll": "Dopasuj wszystkie poniższe reguły:",
+ "relationAny": "dowolna reguła",
+ "waiRelAny": "Dopasuj dowolną z poniższych reguł:",
+ "relationMsgFront": "Dopasuj",
+ "relationMsgTail": "",
+ "and": "i",
+ "or": "lub",
+
+ "addRuleButton": "Dodaj regułę",
+ "waiAddRuleButton": "Dodaj nową regułę",
+ "removeRuleButton": "Usuń regułę",
+ "waiRemoveRuleButtonTemplate": "Usuń regułę ${0}",
+
+ "cancelButton": "Anuluj",
+ "waiCancelButton": "Anuluj to okno dialogowe",
+ "clearButton": "Wyczyść",
+ "waiClearButton": "Wyczyść filtr",
+ "filterButton": "Filtruj",
+ "waiFilterButton": "Wprowadź ten filtr",
+
+ "columnSelectLabel": "Kolumna",
+ "waiColumnSelectTemplate": "Kolumna dla reguły ${0}",
+ "conditionSelectLabel": "Warunek",
+ "waiConditionSelectTemplate": "Warunek dla reguły ${0}",
+ "valueBoxLabel": "Wartość",
+ "waiValueBoxTemplate": "Wprowadź wartość, aby filtrować dla reguły ${0}",
+
+ "rangeTo": "do",
+ "rangeTemplate": "od ${0} do ${1}",
+
+ "statusTipHeaderColumn": "Kolumna",
+ "statusTipHeaderCondition": "Reguły",
+ "statusTipTitle": "Pasek filtru",
+ "statusTipMsg": "Kliknij pasek filtru tutaj, aby filtrować według wartości w ${0}.",
+ "anycolumn": "dowolna kolumna",
+ "statusTipTitleNoFilter": "Pasek filtru",
+ "statusTipTitleHasFilter": "Filtr",
+ "statusTipRelAny": "Dopasuj do dowolnej z reguł.",
+ "statusTipRelAll": "Dopasuj do wszystkich reguł.",
+
+ "defaultItemsName": "elementy",
+ "filterBarMsgHasFilterTemplate": "Wyświetlane ${0} z ${1} ${2}.",
+ "filterBarMsgNoFilterTemplate": "Filtr wyłączony",
+
+ "filterBarDefButton": "Zdefiniuj filtr",
+ "waiFilterBarDefButton": "Filtruj tabelę",
+ "a11yFilterBarDefButton": "Filtruj...",
+ "filterBarClearButton": "Wyczyść filtr",
+ "waiFilterBarClearButton": "Wyczyść filtr",
+ "closeFilterBarBtn": "Zamknij pasek filtru",
+
+ "clearFilterMsg": "Filtr zostanie usunięty i wyświetlone będą wszystkie dostępne rekordy.",
+ "anyColumnOption": "Dowolna kolumna",
+
+ "trueLabel": "Prawda",
+ "falseLabel": "Fałsz"
+})
+//end v1.x content
+);
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/pl/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/pl/Pagination.js
new file mode 100644
index 0000000..c8db8df
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/pl/Pagination.js
@@ -0,0 +1,25 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/pl/Pagination", //begin v1.x content
+({
+ "descTemplate": "${2} - ${3} z ${1} ${0}",
+ "firstTip": "Pierwsza strona",
+ "lastTip": "Ostatnia strona",
+ "nextTip": "Następna strona",
+ "prevTip": "Poprzednia strona",
+ "itemTitle": "poz.",
+ "singularItemTitle": "pozycja",
+ "pageStepLabelTemplate": "Strona ${0}",
+ "pageSizeLabelTemplate": "${0} poz. na stronę",
+ "allItemsLabelTemplate": "Wszystkie pozycje",
+ "gotoButtonTitle": "Idź do konkretnej strony",
+ "dialogTitle": "Idź do strony",
+ "dialogIndication": "Podaj numer strony",
+ "pageCountIndication": " (${0} str.)",
+ "dialogConfirm": "Wykonaj",
+ "dialogCancel": "Anuluj",
+ "all": "wszystkie"
+})
+//end v1.x content
+);
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt-br/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt-br/EnhancedGrid.js
new file mode 100644
index 0000000..093461c
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt-br/EnhancedGrid.js
@@ -0,0 +1,16 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/pt-br/EnhancedGrid", ({
+ singleSort: "Classificação Única",
+ nestedSort: "Classificação Aninhada",
+ ascending: "Crescente",
+ descending: "Decrescente",
+ sortingState: "${0} - ${1}",
+ unsorted: "Não classificar esta coluna",
+ indirectSelectionRadio: "Linha ${0}, seleção única, caixa de opção",
+ indirectSelectionCheckBox: "Linha ${0}, seleção múltipla, caixa de seleção",
+ selectAll: "Selecionar todos"
+})
+
+
+); \ No newline at end of file
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt-br/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt-br/Filter.js
new file mode 100644
index 0000000..dcc9553
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt-br/Filter.js
@@ -0,0 +1,89 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/pt-br/Filter", ({
+ "clearFilterDialogTitle": "Limpar Filtro",
+ "filterDefDialogTitle": "Filtrar",
+ "ruleTitleTemplate": "Regra ${0}",
+
+ "conditionEqual": "igual",
+ "conditionNotEqual": "não é igual",
+ "conditionLess": "é menor que",
+ "conditionLessEqual": "menor que ou igual",
+ "conditionLarger": "é maior que",
+ "conditionLargerEqual": "maior que ou igual",
+ "conditionContains": "contém",
+ "conditionIs": "é",
+ "conditionStartsWith": "começa com",
+ "conditionEndWith": "termina com",
+ "conditionNotContain": "não contém",
+ "conditionIsNot": "não é",
+ "conditionNotStartWith": "não começa com",
+ "conditionNotEndWith": "não termina com",
+ "conditionBefore": "antes",
+ "conditionAfter": "após",
+ "conditionRange": "intervalo",
+ "conditionIsEmpty": "está vazio",
+
+ "all": "todos",
+ "any": "qualquer",
+ "relationAll": "todas as regras",
+ "waiRelAll": "Corresponder todas as regras a seguir:",
+ "relationAny": "quaisquer regras",
+ "waiRelAny": "Corresponder qualquer uma das regras a seguir:",
+ "relationMsgFront": "Corresponder",
+ "relationMsgTail": "",
+ "and": "e",
+ "or": "ou",
+
+ "addRuleButton": "Incluir Regra",
+ "waiAddRuleButton": "Incluir uma nova regra",
+ "removeRuleButton": "Remover Regra",
+ "waiRemoveRuleButtonTemplate": "Remover regra ${0}",
+
+ "cancelButton": "Cancelar",
+ "waiCancelButton": "cancelar este diálogo",
+ "clearButton": "Limpar",
+ "waiClearButton": "Limpar o filtro",
+ "filterButton": "Filtrar",
+ "waiFilterButton": "Submeter o filtro",
+
+ "columnSelectLabel": "Coluna",
+ "waiColumnSelectTemplate": "Coluna para a regra ${0}",
+ "conditionSelectLabel": "Condição",
+ "waiConditionSelectTemplate": "Condição para a regra ${0}",
+ "valueBoxLabel": "Valor",
+ "waiValueBoxTemplate": "Inserir o valor para filtro para a regra ${0}",
+
+ "rangeTo": "para",
+ "rangeTemplate": "de ${0} para ${1}",
+
+ "statusTipHeaderColumn": "Coluna",
+ "statusTipHeaderCondition": "Regras",
+ "statusTipTitle": "Barra de Filtro",
+ "statusTipMsg": "Clique aqui na barra de filtro para filtrar os valores em ${0}.",
+ "anycolumn": "qualquer coluna",
+ "statusTipTitleNoFilter": "Barra de Filtro",
+ "statusTipTitleHasFilter": "Filtrar",
+
+ "defaultItemsName": "itens",
+ "filterBarMsgHasFilterTemplate": "${0} de ${1} ${2} mostrado.",
+ "filterBarMsgNoFilterTemplate": "Nenhum filtro aplicado",
+
+ "filterBarDefButton": "Definir filtro",
+ "waiFilterBarDefButton": "Filtrar a tabela",
+ "a11yFilterBarDefButton": "Filtrar...",
+ "filterBarClearButton": "Limpar Filtro",
+ "waiFilterBarClearButton": "Limpar o filtro",
+ "closeFilterBarBtn": "Fechar a barra de filtro",
+
+ "clearFilterMsg": "Isso removerá o filtro e mostrará todos os registros disponíveis.",
+ "anyColumnOption": "Qualquer Coluna",
+
+ "trueLabel": "Verdadeiro",
+ "falseLabel": "Falso"
+})
+
+
+
+
+); \ No newline at end of file
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt-br/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt-br/Pagination.js
new file mode 100644
index 0000000..25bf82b
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt-br/Pagination.js
@@ -0,0 +1,36 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/pt-br/Pagination", ({
+ // ${0}: string
+ // unit of item, identified by "itemTitle"
+ // ${2}: number
+ // start item index of current page
+ // ${3}: number
+ // end item index of current page
+ // ${1}: number
+ // total number of all items
+ // example:
+ // the total number is 200, the unit of item is "items"
+ // rows per page is 20, current page is 1, then the description
+ // would be looked as below:
+ // | 1 - 20 of 200 items
+ "descTemplate": "${2} - ${3} de ${1} ${0}",
+ "firstTip": "Primeira Página",
+ "lastTip": "Última Página",
+ "nextTip": "Próxima Página",
+ "prevTip": "Página Anterior",
+ "itemTitle": "itens",
+ "singularItemTitle": "item",
+ "pageStepLabelTemplate": "Página ${0}",
+ "pageSizeLabelTemplate": "${0} itens por página",
+ "allItemsLabelTemplate": "Todos os itens",
+ "gotoButtonTitle": "Ir para uma página específica",
+ "dialogTitle": "Ir para a página",
+ "dialogIndication": "Especificar o número da página",
+ "pageCountIndication": " (${0} páginas)",
+ "dialogConfirm": "Ir",
+ "dialogCancel": "Cancelar",
+ "all": "todos"
+})
+
+); \ No newline at end of file
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt-pt/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt-pt/EnhancedGrid.js
new file mode 100644
index 0000000..f5c5340
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt-pt/EnhancedGrid.js
@@ -0,0 +1,17 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/pt-pt/EnhancedGrid", //begin v1.x content
+({
+ singleSort: "Ordenação única",
+ nestedSort: "Ordenação imbricada",
+ ascending: "Ascendente",
+ descending: "Descendente",
+ sortingState: "${0} - ${1}",
+ unsorted: "Não ordenar esta coluna",
+ indirectSelectionRadio: "Fila ${0}, selecção única, caixa de opção",
+ indirectSelectionCheckBox: "Fila ${0}, selecção múltipla, quadrado de confirmação",
+ selectAll: "Seleccionar tudo"
+})
+//end v1.x content
+);
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt-pt/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt-pt/Filter.js
new file mode 100644
index 0000000..beb4937
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt-pt/Filter.js
@@ -0,0 +1,90 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/pt-pt/Filter", //begin v1.x content
+({
+ "clearFilterDialogTitle": "Limpar filtro",
+ "filterDefDialogTitle": "Filtro",
+ "ruleTitleTemplate": "Regra ${0}",
+
+ "conditionEqual": "igual",
+ "conditionNotEqual": "não é igual",
+ "conditionLess": "é menor do que",
+ "conditionLessEqual": "menor ou igual",
+ "conditionLarger": "é maior do que",
+ "conditionLargerEqual": "maior ou igual",
+ "conditionContains": "contém",
+ "conditionIs": "é",
+ "conditionStartsWith": "começa com",
+ "conditionEndWith": "termina com",
+ "conditionNotContain": "não contém",
+ "conditionIsNot": "não é",
+ "conditionNotStartWith": "não começa com",
+ "conditionNotEndWith": "não termina com",
+ "conditionBefore": "antes",
+ "conditionAfter": "após",
+ "conditionRange": "intervalo",
+ "conditionIsEmpty": "está vazio",
+
+ "all": "tudo",
+ "any": "qualquer",
+ "relationAll": "todas as regras",
+ "waiRelAll": "Corresponder a todas as seguintes regras:",
+ "relationAny": "quaisquer regras",
+ "waiRelAny": "Corresponder a qualquer uma das seguintes regras:",
+ "relationMsgFront": "Corresponder",
+ "relationMsgTail": "",
+ "and": "and",
+ "or": "or",
+
+ "addRuleButton": "Adicionar regra",
+ "waiAddRuleButton": "Adicionar uma nova regra",
+ "removeRuleButton": "Remover regra",
+ "waiRemoveRuleButtonTemplate": "Remover regra ${0}",
+
+ "cancelButton": "Cancelar",
+ "waiCancelButton": "Cancelar esta caixa de diálogo",
+ "clearButton": "Limpar",
+ "waiClearButton": "Limpar o filtro",
+ "filterButton": "Filtro",
+ "waiFilterButton": "Submeter o filtro",
+
+ "columnSelectLabel": "Coluna",
+ "waiColumnSelectTemplate": "Coluna para a regra ${0}",
+ "conditionSelectLabel": "Condição",
+ "waiConditionSelectTemplate": "Condição para a regra ${0}",
+ "valueBoxLabel": "Valor",
+ "waiValueBoxTemplate": "Introduzir valor para filtrar para a regra ${0}",
+
+ "rangeTo": "a",
+ "rangeTemplate": "de ${0} a ${1}",
+
+ "statusTipHeaderColumn": "Coluna",
+ "statusTipHeaderCondition": "Regras",
+ "statusTipTitle": "Barra do filtro",
+ "statusTipMsg": "Faça clique na barra de filtro para filtrar os valores em ${0}.",
+ "anycolumn": "qualquer coluna",
+ "statusTipTitleNoFilter": "Barra do filtro",
+ "statusTipTitleHasFilter": "Filtro",
+
+ "defaultItemsName": "itens",
+ "filterBarMsgHasFilterTemplate": "${0} de ${1} ${2} apresentado(s).",
+ "filterBarMsgNoFilterTemplate": "Nenhum filtro aplicado",
+
+ "filterBarDefButton": "Definir filtro",
+ "waiFilterBarDefButton": "Filtrar a tabela",
+ "a11yFilterBarDefButton": "Filtrar...",
+ "filterBarClearButton": "Limpar filtro",
+ "waiFilterBarClearButton": "Limpar o filtro",
+ "closeFilterBarBtn": "Fechar barra de filtro",
+
+ "clearFilterMsg": "Este procedimento irá remover o filtro e apresentar todos os registos disponíveis.",
+ "anyColumnOption": "Qualquer coluna",
+
+ "trueLabel": "True",
+ "falseLabel": "False"
+})
+//end v1.x content
+);
+
+
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt-pt/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt-pt/Pagination.js
new file mode 100644
index 0000000..ac54ab0
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt-pt/Pagination.js
@@ -0,0 +1,24 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/pt-pt/Pagination", //begin v1.x content
+({
+ "descTemplate": "${2} - ${3} de ${1} ${0}",
+ "firstTip": "Primeira página",
+ "lastTip": "Última página",
+ "nextTip": "Página seguinte",
+ "prevTip": "Página anterior",
+ "itemTitle": "itens",
+ "pageStepLabelTemplate": "Página ${0}",
+ "pageSizeLabelTemplate": "${0} itens por página",
+ "allItemsLabelTemplate": "Todos os itens",
+ "gotoButtonTitle": "Avançar para uma página específica",
+ "dialogTitle": "Avançar para a página",
+ "dialogIndication": "Especificar o número de página",
+ "pageCountIndication": " (${0} páginas)",
+ "dialogConfirm": "Ir",
+ "dialogCancel": "Cancelar",
+ "all": "tudo"
+})
+//end v1.x content
+);
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt/EnhancedGrid.js
new file mode 100644
index 0000000..b09ab48
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt/EnhancedGrid.js
@@ -0,0 +1,17 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/pt/EnhancedGrid", //begin v1.x content
+({
+ singleSort: "Classificação Única",
+ nestedSort: "Classificação Aninhada",
+ ascending: "Ascendente",
+ descending: "Descendente",
+ sortingState: "${0} - ${1}",
+ unsorted: "Não classificar esta coluna",
+ indirectSelectionRadio: "Linha ${0}, seleção única, botão de seleção",
+ indirectSelectionCheckBox: "Linha ${0}, seleção múltipla, caixa de seleção",
+ selectAll: "Selecionar todos"
+})
+//end v1.x content
+);
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt/Filter.js
new file mode 100644
index 0000000..7974304
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt/Filter.js
@@ -0,0 +1,92 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/pt/Filter", //begin v1.x content
+({
+ "clearFilterDialogTitle": "Limpar Filtro",
+ "filterDefDialogTitle": "Filtrar",
+ "ruleTitleTemplate": "Regra ${0}",
+
+ "conditionEqual": "igual",
+ "conditionNotEqual": "não é igual",
+ "conditionLess": "é menor que",
+ "conditionLessEqual": "menor ou igual a",
+ "conditionLarger": "é maior que",
+ "conditionLargerEqual": "maior ou igual a",
+ "conditionContains": "contém",
+ "conditionIs": "é",
+ "conditionStartsWith": "inicia com",
+ "conditionEndWith": "termina com",
+ "conditionNotContain": "não contém",
+ "conditionIsNot": "não é",
+ "conditionNotStartWith": "não inicia com",
+ "conditionNotEndWith": "não termina com",
+ "conditionBefore": "antes",
+ "conditionAfter": "depois",
+ "conditionRange": "intervalo",
+ "conditionIsEmpty": "está vazio",
+
+ "all": "todos",
+ "any": "qualquer um",
+ "relationAll": "todas as regras",
+ "waiRelAll": "Corresponder a todas as seguintes regras:",
+ "relationAny": "qualquer regra",
+ "waiRelAny": "Corresponder a qualquer uma das seguintes regras:",
+ "relationMsgFront": "Corresponder",
+ "relationMsgTail": "",
+ "and": "e",
+ "or": "ou",
+
+ "addRuleButton": "Incluir Regra",
+ "waiAddRuleButton": "Incluir uma nova regra",
+ "removeRuleButton": "Remover Regra",
+ "waiRemoveRuleButtonTemplate": "Remover regra ${0}",
+
+ "cancelButton": "Cancelar",
+ "waiCancelButton": "Cancelar este diálogo",
+ "clearButton": "Limpar",
+ "waiClearButton": "Limpar o filtro",
+ "filterButton": "Filtrar",
+ "waiFilterButton": "Enviar o filtro",
+
+ "columnSelectLabel": "Coluna",
+ "waiColumnSelectTemplate": "Coluna para a regra ${0}",
+ "conditionSelectLabel": "Condição",
+ "waiConditionSelectTemplate": "Condição para a regra ${0}",
+ "valueBoxLabel": "Valor",
+ "waiValueBoxTemplate": "Insira o valor para filtragem da regra ${0}",
+
+ "rangeTo": "a",
+ "rangeTemplate": "de ${0} a ${1}",
+
+ "statusTipHeaderColumn": "Coluna",
+ "statusTipHeaderCondition": "Regras",
+ "statusTipTitle": "Barra de Filtragem",
+ "statusTipMsg": "Clique na barra de filtragem aqui para filtrar os valores de ${0}.",
+ "anycolumn": "qualquer coluna",
+ "statusTipTitleNoFilter": "Barra de Filtragem",
+ "statusTipTitleHasFilter": "Filtrar",
+ "statusTipRelAny": "Quaisquer Regras.",
+ "statusTipRelAll": "Todas as Regras.",
+
+ "defaultItemsName": "itens",
+ "filterBarMsgHasFilterTemplate": "${0} de ${1} ${2} mostrados.",
+ "filterBarMsgNoFilterTemplate": "Nenhum filtro aplicado",
+
+ "filterBarDefButton": "Definir filtro",
+ "waiFilterBarDefButton": "Filtrar a tabela",
+ "a11yFilterBarDefButton": "Filtrar...",
+ "filterBarClearButton": "Limpar filtro",
+ "waiFilterBarClearButton": "Limpar o filtro",
+ "closeFilterBarBtn": "Fechar a barra de filtragem",
+
+ "clearFilterMsg": "Isso removerá o filtro e mostrará todos os registros disponíveis.",
+ "anyColumnOption": "Qualquer Coluna",
+
+ "trueLabel": "Verdadeiro",
+ "falseLabel": "Falso"
+})
+//end v1.x content
+);
+
+
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt/Pagination.js
new file mode 100644
index 0000000..5a1320d
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/pt/Pagination.js
@@ -0,0 +1,24 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/pt/Pagination", //begin v1.x content
+({
+ "descTemplate": "${2} - ${3} de ${1} ${0}",
+ "firstTip": "Primeira Página",
+ "lastTip": "Última Página",
+ "nextTip": "Próxima página",
+ "prevTip": "Página anterior",
+ "itemTitle": "itens",
+ "singularItemTitle": "item",
+ "pageStepLabelTemplate": "Página ${0}",
+ "pageSizeLabelTemplate": "${0} itens por página",
+ "allItemsLabelTemplate": "Todos os itens",
+ "gotoButtonTitle": "Acesse uma página específica",
+ "dialogTitle": "Acesse a Página",
+ "dialogIndication": "Especifique o número da página",
+ "pageCountIndication": " (${0} páginas)",
+ "dialogConfirm": "Ir",
+ "dialogCancel": "Cancelar",
+ "all": "todos"
+})
+//end v1.x content
+);
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/ro/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ro/EnhancedGrid.js
new file mode 100644
index 0000000..0415b11
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ro/EnhancedGrid.js
@@ -0,0 +1,17 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/ro/EnhancedGrid", //begin v1.x content
+({
+ singleSort: "Sortare singulară",
+ nestedSort: "Sortare imbricată",
+ ascending: "Crescător",
+ descending: "Descrescător",
+ sortingState: "${0} - ${1}",
+ unsorted: "Nu se sortează această coloană",
+ indirectSelectionRadio: "Rândul ${0}, selecţie singulară, casetă radio",
+ indirectSelectionCheckBox: "Rândul ${0}, selecţie multiplă, casetă de bifare",
+ selectAll: "Selectare tot"
+})
+//end v1.x content
+);
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/ro/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ro/Filter.js
new file mode 100644
index 0000000..ba2879c
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ro/Filter.js
@@ -0,0 +1,89 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/ro/Filter", //begin v1.x content
+({
+ "clearFilterDialogTitle": "Ştergere filtru",
+ "filterDefDialogTitle": "Filtru",
+ "ruleTitleTemplate": "Regulă ${0}",
+
+ "conditionEqual": "egal",
+ "conditionNotEqual": "nu este egal",
+ "conditionLess": "este mai mic decât",
+ "conditionLessEqual": "mai mic sau egal",
+ "conditionLarger": "este mai mare decât",
+ "conditionLargerEqual": "mai mare sau egal",
+ "conditionContains": "conţine",
+ "conditionIs": "este",
+ "conditionStartsWith": "începe cu",
+ "conditionEndWith": "se termină cu",
+ "conditionNotContain": "nu conţine",
+ "conditionIsNot": "nu este",
+ "conditionNotStartWith": "nu începe cu",
+ "conditionNotEndWith": "nu se termină cu",
+ "conditionBefore": "înaintea",
+ "conditionAfter": "după",
+ "conditionRange": "interval",
+ "conditionIsEmpty": "este gol",
+
+ "all": "toate",
+ "any": "oricare",
+ "relationAll": "toate regulile",
+ "waiRelAll": "Răspundeţi tuturor regulilor următoare:",
+ "relationAny": "oricare reguli",
+ "waiRelAny": "Răspundeţi oricărei dintre regulile următoare:",
+ "relationMsgFront": "Răspuns",
+ "relationMsgTail": "",
+ "and": "şi",
+ "or": "sau",
+
+ "addRuleButton": "Adăugare regulă",
+ "waiAddRuleButton": "Adăugare regulă nouă",
+ "removeRuleButton": "Înlăturare regulă",
+ "waiRemoveRuleButtonTemplate": "Înlăturare regulă ${0}",
+
+ "cancelButton": "Anulare",
+ "waiCancelButton": "Anulaţi acest dialog",
+ "clearButton": "Ştergere",
+ "waiClearButton": "Ştergeţi filtrul",
+ "filterButton": "Filtru",
+ "waiFilterButton": "Lansaţi în execuţie filtrul",
+
+ "columnSelectLabel": "Coloană",
+ "waiColumnSelectTemplate": "Coloană pentru regulă ${0}",
+ "conditionSelectLabel": "Condiţie",
+ "waiConditionSelectTemplate": "Condiţie pentru regula ${0}",
+ "valueBoxLabel": "Valoare",
+ "waiValueBoxTemplate": "Introduceţi valoarea pentru filtrarea pentru regulă ${0}",
+
+ "rangeTo": "la",
+ "rangeTemplate": "din ${0} la ${1}",
+
+ "statusTipHeaderColumn": "Coloană",
+ "statusTipHeaderCondition": "Reguli",
+ "statusTipTitle": "Bară de filtru",
+ "statusTipMsg": "Faceţi clic pe bara de filtru aici pentru a filtra valorile în ${0}.",
+ "anycolumn": "orice coloană",
+ "statusTipTitleNoFilter": "Bară de filtru",
+ "statusTipTitleHasFilter": "Filtru",
+ "statusTipRelAny": "Potrivire orice regulă.",
+ "statusTipRelAll": "Potrivire toate regulile.",
+
+ "defaultItemsName": "articole",
+ "filterBarMsgHasFilterTemplate": "${0} din ${1} ${2} afişate.",
+ "filterBarMsgNoFilterTemplate": "Niciun filtru nu este aplicat",
+
+ "filterBarDefButton": "Definire filtru",
+ "waiFilterBarDefButton": "Filtrare tabelă",
+ "a11yFilterBarDefButton": "Filtru...",
+ "filterBarClearButton": "Ştergere filtru",
+ "waiFilterBarClearButton": "Ştergeţi filtrul",
+ "closeFilterBarBtn": "Închidere bară de filtru",
+
+ "clearFilterMsg": "Aceasta va înlătura filtrul şi va afişa toate înregistrările disponibile.",
+ "anyColumnOption": "Orice coloană",
+
+ "trueLabel": "Adevărat",
+ "falseLabel": "Fals"
+})
+//end v1.x content
+);
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/ro/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ro/Pagination.js
new file mode 100644
index 0000000..633a192
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ro/Pagination.js
@@ -0,0 +1,24 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/ro/Pagination", //begin v1.x content
+({
+ "descTemplate": "${2} - ${3} din ${1} ${0}",
+ "firstTip": "Prima pagină",
+ "lastTip": "Ultima pagină",
+ "nextTip": "Următoarea pagină",
+ "prevTip": "Pagina anterioarp",
+ "itemTitle": "articole",
+ "singularItemTitle": "articol",
+ "pageStepLabelTemplate": "Pagina ${0}",
+ "pageSizeLabelTemplate": "${0} articole pe pagină",
+ "allItemsLabelTemplate": "Toate articolele",
+ "gotoButtonTitle": "Deplasare la o pagină anumită",
+ "dialogTitle": "Deplasare la pagină",
+ "dialogIndication": "Specificaţi numărul de pagină",
+ "pageCountIndication": " (${0} pagini)",
+ "dialogConfirm": "Deplasare",
+ "dialogCancel": "Anulare",
+ "all": "toate"
+})
+//end v1.x content
+);
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/ru/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ru/EnhancedGrid.js
new file mode 100644
index 0000000..cdb44ac
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ru/EnhancedGrid.js
@@ -0,0 +1,17 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/ru/EnhancedGrid", //begin v1.x content
+({
+ singleSort: "Простая сортировка",
+ nestedSort: "Вложенная сортировка",
+ ascending: "По возрастанию",
+ descending: "По убыванию",
+ sortingState: "${0} - ${1}",
+ unsorted: "Не сортировать этот столбец",
+ indirectSelectionRadio: "Строка ${0}, один выбор, радиокнопка",
+ indirectSelectionCheckBox: "Строка ${0}, несколько выборов, переключатель",
+ selectAll: "Выбрать все"
+})
+//end v1.x content
+);
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/ru/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ru/Filter.js
new file mode 100644
index 0000000..ea9567d
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ru/Filter.js
@@ -0,0 +1,89 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/ru/Filter", //begin v1.x content
+({
+ "clearFilterDialogTitle": "Удалить фильтр",
+ "filterDefDialogTitle": "Фильтр",
+ "ruleTitleTemplate": "Правило ${0}",
+
+ "conditionEqual": "равно",
+ "conditionNotEqual": "не равно",
+ "conditionLess": "меньше, чем",
+ "conditionLessEqual": "меньше или равно",
+ "conditionLarger": "больше, чем",
+ "conditionLargerEqual": "больше или равно",
+ "conditionContains": "содержит",
+ "conditionIs": "является",
+ "conditionStartsWith": "начинается с",
+ "conditionEndWith": "заканчивается на",
+ "conditionNotContain": "не содержит",
+ "conditionIsNot": "не является",
+ "conditionNotStartWith": "не начинается с",
+ "conditionNotEndWith": "не заканчивается на",
+ "conditionBefore": "до",
+ "conditionAfter": "после",
+ "conditionRange": "диапазон",
+ "conditionIsEmpty": "пустое",
+
+ "all": "все",
+ "any": "любое",
+ "relationAll": "все правила",
+ "waiRelAll": "Соответствие всем следующим правилам:",
+ "relationAny": "любое правило",
+ "waiRelAny": "Соответствие любому из следующих правил:",
+ "relationMsgFront": "Соответствие",
+ "relationMsgTail": "",
+ "and": "и",
+ "or": "или",
+
+ "addRuleButton": "Добавить правило",
+ "waiAddRuleButton": "Добавить новое правило",
+ "removeRuleButton": "Удалить правило",
+ "waiRemoveRuleButtonTemplate": "Удалить правило ${0}",
+
+ "cancelButton": "Отмена",
+ "waiCancelButton": "Отменить этот диалог",
+ "clearButton": "Удалить",
+ "waiClearButton": "Удалить фильтр",
+ "filterButton": "Фильтр",
+ "waiFilterButton": "Передать фильтр",
+
+ "columnSelectLabel": "Столбец",
+ "waiColumnSelectTemplate": "Столбец для правила ${0}",
+ "conditionSelectLabel": "Условие",
+ "waiConditionSelectTemplate": "Условие для правила ${0}",
+ "valueBoxLabel": "Значение",
+ "waiValueBoxTemplate": "Задайте значение фильтра для правила ${0}",
+
+ "rangeTo": "до",
+ "rangeTemplate": "от ${0} до ${1}",
+
+ "statusTipHeaderColumn": "Столбец",
+ "statusTipHeaderCondition": "Правила",
+ "statusTipTitle": "Панель фильтра",
+ "statusTipMsg": "Щелкните по панели фильтра, чтобы применить фильтр к значениям в ${0}.",
+ "anycolumn": "любой столбец",
+ "statusTipTitleNoFilter": "Панель фильтра",
+ "statusTipTitleHasFilter": "Фильтр",
+ "statusTipRelAny": "Соответствует любому из правил.",
+ "statusTipRelAll": "Соответствует всем правилам.",
+
+ "defaultItemsName": "элементов",
+ "filterBarMsgHasFilterTemplate": "Показано ${0} из ${1} ${2}.",
+ "filterBarMsgNoFilterTemplate": "Фильтр не применен",
+
+ "filterBarDefButton": "Задать фильтр",
+ "waiFilterBarDefButton": "Применить фильтр к таблице",
+ "a11yFilterBarDefButton": "Фильтр...",
+ "filterBarClearButton": "Удалить фильтр",
+ "waiFilterBarClearButton": "Удалить фильтр",
+ "closeFilterBarBtn": "Закрыть панель фильтра",
+
+ "clearFilterMsg": "Фильтр будет удален, и будут показаны все записи.",
+ "anyColumnOption": "Любой столбец",
+
+ "trueLabel": "True",
+ "falseLabel": "False"
+})
+//end v1.x content
+);
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/ru/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ru/Pagination.js
new file mode 100644
index 0000000..db662ca
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/ru/Pagination.js
@@ -0,0 +1,25 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/ru/Pagination", //begin v1.x content
+({
+ "descTemplate": "${2} - ${3} из ${1} ${0}",
+ "firstTip": "Первая страница",
+ "lastTip": "Последняя страница",
+ "nextTip": "Следующая страница",
+ "prevTip": "Предыдущая страница",
+ "itemTitle": "элементов",
+ "singularItemTitle": "элемент",
+ "pageStepLabelTemplate": "Страница ${0}",
+ "pageSizeLabelTemplate": "${0} элементов на странице",
+ "allItemsLabelTemplate": "Все элементы",
+ "gotoButtonTitle": "Перейти на определенную страницу",
+ "dialogTitle": "Перейти на страницу",
+ "dialogIndication": "Задайте номер страницы",
+ "pageCountIndication": " (${0} страниц)",
+ "dialogConfirm": "Перейти",
+ "dialogCancel": "Отмена",
+ "all": "все"
+})
+//end v1.x content
+);
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/sk/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/sk/EnhancedGrid.js
new file mode 100644
index 0000000..9338e81
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/sk/EnhancedGrid.js
@@ -0,0 +1,17 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/sk/EnhancedGrid", //begin v1.x content
+({
+ singleSort: "Jednoduché triedenie",
+ nestedSort: "Vnorené triedenie",
+ ascending: "Vzostupne",
+ descending: "Zostupne",
+ sortingState: "${0} - ${1}",
+ unsorted: "Netriediť tento stĺpec",
+ indirectSelectionRadio: "Riadok ${0}, jednoduchý výber, prepínač",
+ indirectSelectionCheckBox: "Riadok ${0}, viacnásobný výber, začiarkavacie políčko",
+ selectAll: "Vybrať všetko"
+})
+//end v1.x content
+);
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/sk/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/sk/Filter.js
new file mode 100644
index 0000000..8d83150
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/sk/Filter.js
@@ -0,0 +1,89 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/sk/Filter", //begin v1.x content
+({
+ "clearFilterDialogTitle": "Zrušiť filter",
+ "filterDefDialogTitle": "Filter",
+ "ruleTitleTemplate": "Pravidlo ${0}",
+
+ "conditionEqual": "rovné",
+ "conditionNotEqual": "nerovné",
+ "conditionLess": "menšie ako",
+ "conditionLessEqual": "menšie ako alebo rovné",
+ "conditionLarger": "väčšie ako",
+ "conditionLargerEqual": "väčšie ako alebo rovné",
+ "conditionContains": "obsahuje",
+ "conditionIs": "je",
+ "conditionStartsWith": "začína s",
+ "conditionEndWith": "končí s",
+ "conditionNotContain": "neobsahuje",
+ "conditionIsNot": "nie je",
+ "conditionNotStartWith": "nezačína s",
+ "conditionNotEndWith": "nekončí s",
+ "conditionBefore": "pred",
+ "conditionAfter": "za",
+ "conditionRange": "rozsah",
+ "conditionIsEmpty": "je prázdne",
+
+ "all": "všetko",
+ "any": "žiadne",
+ "relationAll": "všetky pravidlá",
+ "waiRelAll": "Vyhovovať všetkým týmto pravidlám:",
+ "relationAny": "ľubovoľné pravidlá",
+ "waiRelAny": "Vyhovovať ľubovoľným z týchto pravidiel:",
+ "relationMsgFront": "Vyhovieť",
+ "relationMsgTail": "",
+ "and": "a",
+ "or": "alebo",
+
+ "addRuleButton": "Pridať pravidlo",
+ "waiAddRuleButton": "Pridať nové pravidlo",
+ "removeRuleButton": "Odstrániť pravidlo",
+ "waiRemoveRuleButtonTemplate": "Odstrániť pravidlo ${0}",
+
+ "cancelButton": "Zrušiť",
+ "waiCancelButton": "Zrušiť toto dialógové okno",
+ "clearButton": "Zrušiť",
+ "waiClearButton": "Zrušiť filter",
+ "filterButton": "Filtrovať",
+ "waiFilterButton": "Odoslať filter",
+
+ "columnSelectLabel": "Stĺpec",
+ "waiColumnSelectTemplate": "Stĺpec pre pravidlo ${0}",
+ "conditionSelectLabel": "Podmienka",
+ "waiConditionSelectTemplate": "Podmienka pre pravidlo ${0}",
+ "valueBoxLabel": "Hodnota",
+ "waiValueBoxTemplate": "Zadajte hodnotu na filtrovanie pre pravidlo ${0}",
+
+ "rangeTo": "do",
+ "rangeTemplate": "od ${0} do ${1}",
+
+ "statusTipHeaderColumn": "Stĺpec",
+ "statusTipHeaderCondition": "Pravidlá",
+ "statusTipTitle": "Lišta filtra",
+ "statusTipMsg": "Kliknite na lištu filtra, ak chcete filtrovať podľa hodnôt v ${0}.",
+ "anycolumn": "ľubovoľný stĺpec",
+ "statusTipTitleNoFilter": "Lišta filtra",
+ "statusTipTitleHasFilter": "Filter",
+ "statusTipRelAny": "Zhoda s akýmikoľvek pravidlami.",
+ "statusTipRelAll": "Zhoda so všetkými pravidlami.",
+
+ "defaultItemsName": "položky",
+ "filterBarMsgHasFilterTemplate": "Zobrazuje sa ${0} z ${1} ${2}.",
+ "filterBarMsgNoFilterTemplate": "Nepoužíva sa žiadny filter",
+
+ "filterBarDefButton": "Definovať filter",
+ "waiFilterBarDefButton": "Filtrovať tabuľku",
+ "a11yFilterBarDefButton": "Filtrovať...",
+ "filterBarClearButton": "Zrušiť filter",
+ "waiFilterBarClearButton": "Zrušiť filter",
+ "closeFilterBarBtn": "Zatvoriť lištu filtra",
+
+ "clearFilterMsg": "Toto odstráni filter a zobrazí všetky dostupné záznamy",
+ "anyColumnOption": "Ľubovoľný stĺpec",
+
+ "trueLabel": "Pravda",
+ "falseLabel": "Nepravda"
+})
+//end v1.x content
+);
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/sk/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/sk/Pagination.js
new file mode 100644
index 0000000..ec6cb2e
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/sk/Pagination.js
@@ -0,0 +1,24 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/sk/Pagination", //begin v1.x content
+({
+ "descTemplate": "${2} - ${3} z ${1} ${0}",
+ "firstTip": "Prvá strana",
+ "lastTip": "Posledná strana",
+ "nextTip": "Ďalšia strana",
+ "prevTip": "Predošlá strana",
+ "itemTitle": "položiek",
+ "singularItemTitle": "položka",
+ "pageStepLabelTemplate": "Strana ${0}",
+ "pageSizeLabelTemplate": "${0} položiek na strane",
+ "allItemsLabelTemplate": "Všetky položky",
+ "gotoButtonTitle": "Prejsť na špecifickú stranu",
+ "dialogTitle": "Prejsť na stranu",
+ "dialogIndication": "Zadajte číslo strany",
+ "pageCountIndication": " (${0} strán)",
+ "dialogConfirm": "Prejsť",
+ "dialogCancel": "Zrušiť",
+ "all": "všetko"
+})
+//end v1.x content
+);
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/sl/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/sl/EnhancedGrid.js
new file mode 100644
index 0000000..f2a3d6c
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/sl/EnhancedGrid.js
@@ -0,0 +1,17 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/sl/EnhancedGrid", //begin v1.x content
+({
+ singleSort: "Enostavno razvrščanje",
+ nestedSort: "Ugnezdeno razvrščanje",
+ ascending: "Naraščajoče",
+ descending: "Padajoče",
+ sortingState: "${0} - ${1}",
+ unsorted: "Ne razvrščaj tega stolpca",
+ indirectSelectionRadio: "Vrstica ${0}, izbira enega elementa, okence z izbirnim gumbom",
+ indirectSelectionCheckBox: "Vrstica ${0}, izbira več elementov, okence s potrditvenimi polji",
+ selectAll: "Izberi vse"
+})
+//end v1.x content
+);
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/sl/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/sl/Filter.js
new file mode 100644
index 0000000..283b9c7
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/sl/Filter.js
@@ -0,0 +1,89 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/sl/Filter", //begin v1.x content
+({
+ "clearFilterDialogTitle": "Počisti filter",
+ "filterDefDialogTitle": "Filter",
+ "ruleTitleTemplate": "Pravilo ${0}",
+
+ "conditionEqual": "je enako",
+ "conditionNotEqual": "ni enako",
+ "conditionLess": "je manjše kot",
+ "conditionLessEqual": "je manjše kot ali enako",
+ "conditionLarger": "je večje kot",
+ "conditionLargerEqual": "je večje kot ali enako",
+ "conditionContains": "vsebuje",
+ "conditionIs": "je",
+ "conditionStartsWith": "se začne s",
+ "conditionEndWith": "se konča s",
+ "conditionNotContain": "ne vsebuje",
+ "conditionIsNot": "ni",
+ "conditionNotStartWith": "se ne začne s",
+ "conditionNotEndWith": "se ne konča s",
+ "conditionBefore": "pred",
+ "conditionAfter": "za",
+ "conditionRange": "obseg",
+ "conditionIsEmpty": "je prazno",
+
+ "all": "vse",
+ "any": "karkoli",
+ "relationAll": "vsa pravila",
+ "waiRelAll": "Ujema se z vsemi od naslednjih pravil:",
+ "relationAny": "katerakoli pravila",
+ "waiRelAny": "Ujema se s katerimkoli od naslednjih pravil:",
+ "relationMsgFront": "Ujemanje",
+ "relationMsgTail": "",
+ "and": "in",
+ "or": "ali",
+
+ "addRuleButton": "Dodaj pravilo",
+ "waiAddRuleButton": "Dodaj novo pravilo",
+ "removeRuleButton": "Odstrani pravilo",
+ "waiRemoveRuleButtonTemplate": "Odstrani pravilo ${0}",
+
+ "cancelButton": "Prekliči",
+ "waiCancelButton": "Prekliči to pogovorno okno",
+ "clearButton": "Počisti",
+ "waiClearButton": "Počisti filter",
+ "filterButton": "Filter",
+ "waiFilterButton": "Predloži filter",
+
+ "columnSelectLabel": "Stolpec",
+ "waiColumnSelectTemplate": "Stolpec za pravilo ${0}",
+ "conditionSelectLabel": "Pogoj",
+ "waiConditionSelectTemplate": "Pogoj za pravilo ${0}",
+ "valueBoxLabel": "Vrednost",
+ "waiValueBoxTemplate": "Vnesite vrednost za filter pravila ${0}",
+
+ "rangeTo": "do",
+ "rangeTemplate": "od ${0} do ${1}",
+
+ "statusTipHeaderColumn": "Stolpec",
+ "statusTipHeaderCondition": "Pravila",
+ "statusTipTitle": "Vrstica za filtriranje",
+ "statusTipMsg": "Kliknite vrstico za filtriranje tukaj, da prefiltrirate vrednosti v ${0}.",
+ "anycolumn": "katerikoli stolpec",
+ "statusTipTitleNoFilter": "Vrstica za filtriranje",
+ "statusTipTitleHasFilter": "Filter",
+ "statusTipRelAny": "Ujemanje s katerimkoli pravilom.",
+ "statusTipRelAll": "Ujemanje z vsemi pravili.",
+
+ "defaultItemsName": "postavke",
+ "filterBarMsgHasFilterTemplate": "Prikazanih je ${0} od ${1} ${2}.",
+ "filterBarMsgNoFilterTemplate": "Uveljavljen ni noben filter.",
+
+ "filterBarDefButton": "Definiraj filter",
+ "waiFilterBarDefButton": "Filtriraj tabelo",
+ "a11yFilterBarDefButton": "Filtriraj ...",
+ "filterBarClearButton": "Počisti filter",
+ "waiFilterBarClearButton": "Počisti filter",
+ "closeFilterBarBtn": "Zapri vrstico za filtriranje",
+
+ "clearFilterMsg": "S tem boste odstranili filter in prikazali se bodo vsi razpoložljivi zapisi.",
+ "anyColumnOption": "Katerikoli stolpec",
+
+ "trueLabel": "True",
+ "falseLabel": "False"
+})
+//end v1.x content
+);
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/sl/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/sl/Pagination.js
new file mode 100644
index 0000000..5ea9222
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/sl/Pagination.js
@@ -0,0 +1,25 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/sl/Pagination", //begin v1.x content
+({
+ "descTemplate": "${2} - ${3} od ${1} ${0}",
+ "firstTip": "Prva stran",
+ "lastTip": "Zadnja stran",
+ "nextTip": "Naslednja stran",
+ "prevTip": "Prejšnja stran",
+ "itemTitle": "postavke",
+ "singularItemTitle": "postavka",
+ "pageStepLabelTemplate": "Stran ${0}",
+ "pageSizeLabelTemplate": "${0} postavk na stran",
+ "allItemsLabelTemplate": "Vse postavke",
+ "gotoButtonTitle": "Pojdi na specifično stran",
+ "dialogTitle": "Pojdi na stran",
+ "dialogIndication": "Podajte številko strani",
+ "pageCountIndication": " (${0} strani)",
+ "dialogConfirm": "Pojdi",
+ "dialogCancel": "Prekliči",
+ "all": "vse"
+})
+//end v1.x content
+);
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/sv/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/sv/EnhancedGrid.js
new file mode 100644
index 0000000..dd6d606
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/sv/EnhancedGrid.js
@@ -0,0 +1,17 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/sv/EnhancedGrid", //begin v1.x content
+({
+ singleSort: "Enkel sortering",
+ nestedSort: "Nästlad sortering",
+ ascending: "Stigande",
+ descending: "Fallande",
+ sortingState: "${0} - ${1}",
+ unsorted: "Sortera inte den här kolumnen",
+ indirectSelectionRadio: "Rad ${0}, ett enda val, alternativruta",
+ indirectSelectionCheckBox: "Rad ${0}, flera val, kryssruta",
+ selectAll: "Markera alla "
+})
+//end v1.x content
+);
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/sv/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/sv/Filter.js
new file mode 100644
index 0000000..2a58c48
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/sv/Filter.js
@@ -0,0 +1,89 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/sv/Filter", //begin v1.x content
+({
+ "clearFilterDialogTitle": "Rensa filter",
+ "filterDefDialogTitle": "Filter",
+ "ruleTitleTemplate": "Regel ${0}",
+
+ "conditionEqual": "lika med",
+ "conditionNotEqual": "inte lika med",
+ "conditionLess": "är mindre än",
+ "conditionLessEqual": "mindre eller lika med",
+ "conditionLarger": "är större än",
+ "conditionLargerEqual": "större än eller lika med",
+ "conditionContains": "innehåller",
+ "conditionIs": "är",
+ "conditionStartsWith": "börjar med",
+ "conditionEndWith": "slutar med",
+ "conditionNotContain": "innehåller inte",
+ "conditionIsNot": "är inte",
+ "conditionNotStartWith": "börjar inte med",
+ "conditionNotEndWith": "slutar inte med",
+ "conditionBefore": "före",
+ "conditionAfter": "efter",
+ "conditionRange": "intervall",
+ "conditionIsEmpty": "är tom",
+
+ "all": "alla",
+ "any": "någon",
+ "relationAll": "alla regler",
+ "waiRelAll": "Matcha alla följande regler:",
+ "relationAny": "någon regel",
+ "waiRelAny": "Matcha någon av följande regler:",
+ "relationMsgFront": "Matcha",
+ "relationMsgTail": "",
+ "and": "och",
+ "or": "eller",
+
+ "addRuleButton": "Lägg till regel",
+ "waiAddRuleButton": "Lägg till en ny regel",
+ "removeRuleButton": "Ta bort regel",
+ "waiRemoveRuleButtonTemplate": "Ta bort regel ${0}",
+
+ "cancelButton": "Avbryt",
+ "waiCancelButton": "Avbryt dialogen",
+ "clearButton": "Rensa",
+ "waiClearButton": "Rensa filtret",
+ "filterButton": "Filtrera",
+ "waiFilterButton": "Filtrera",
+
+ "columnSelectLabel": "Kolumn",
+ "waiColumnSelectTemplate": "Kolumn för regel ${0}",
+ "conditionSelectLabel": "Villkor",
+ "waiConditionSelectTemplate": "Villkor för regel ${0}",
+ "valueBoxLabel": "Värde",
+ "waiValueBoxTemplate": "Ange värde för filtrering efter regeln ${0}",
+
+ "rangeTo": "till",
+ "rangeTemplate": "från ${0} till ${1}",
+
+ "statusTipHeaderColumn": "Kolumn",
+ "statusTipHeaderCondition": "Regler",
+ "statusTipTitle": "Filterfält",
+ "statusTipMsg": "Klicka på filterfältet om du vill filtrera värden i ${0}.",
+ "anycolumn": "alla kolumner",
+ "statusTipTitleNoFilter": "Filterfält",
+ "statusTipTitleHasFilter": "Filter",
+ "statusTipRelAny": "Matcha någon regel.",
+ "statusTipRelAll": "Matcha alla regler.",
+
+ "defaultItemsName": "objekt",
+ "filterBarMsgHasFilterTemplate": "${0} av ${1} ${2} visas.",
+ "filterBarMsgNoFilterTemplate": "Inget filter tillämpat",
+
+ "filterBarDefButton": "Definiera filter",
+ "waiFilterBarDefButton": "Filtrera tabellen",
+ "a11yFilterBarDefButton": "Filter...",
+ "filterBarClearButton": "Rensa filter",
+ "waiFilterBarClearButton": "Rensa filtret",
+ "closeFilterBarBtn": "Stäng filterfält",
+
+ "clearFilterMsg": "Tar bort filtret och visar alla tillgängliga poster.",
+ "anyColumnOption": "Alla kolumner",
+
+ "trueLabel": "Sant",
+ "falseLabel": "Falskt"
+})
+//end v1.x content
+);
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/sv/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/sv/Pagination.js
new file mode 100644
index 0000000..472d5e8
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/sv/Pagination.js
@@ -0,0 +1,24 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/sv/Pagination", //begin v1.x content
+({
+ "descTemplate": "${2} - ${3} av ${1} ${0}",
+ "firstTip": "Första sidan",
+ "lastTip": "Sista sidan",
+ "nextTip": "Nästa sida",
+ "prevTip": "Föregående sida",
+ "itemTitle": "objekt",
+ "singularItemTitle": "objekt",
+ "pageStepLabelTemplate": "Sida ${0}",
+ "pageSizeLabelTemplate": "${0} objekt per sida",
+ "allItemsLabelTemplate": "Alla objekt",
+ "gotoButtonTitle": "Gå till en viss sida",
+ "dialogTitle": "Gå till sidan",
+ "dialogIndication": "Ange sidnummer",
+ "pageCountIndication": " (${0} sidor)",
+ "dialogConfirm": "Gå",
+ "dialogCancel": "Avbryt",
+ "all": "alla"
+})
+//end v1.x content
+);
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/th/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/th/EnhancedGrid.js
new file mode 100644
index 0000000..d0bd82c
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/th/EnhancedGrid.js
@@ -0,0 +1,17 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/th/EnhancedGrid", //begin v1.x content
+({
+ singleSort: "เรียงลำดับแบบเดี่ยว",
+ nestedSort: "เรียงลำดับที่ซับซ้อน",
+ ascending: "จากน้อยไปหามาก",
+ descending: "จากมากไปหาน้อย",
+ sortingState: "${0} - ${1}",
+ unsorted: "ห้ามเรียงลำดับคอลัมน์นี้",
+ indirectSelectionRadio: "แถว ${0}, การเลือกเดียว, กล่องวิทยุ",
+ indirectSelectionCheckBox: "แถว ${0}, การเลือกจำนวนมาก, เช็กบ็อกซ์",
+ selectAll: "เลือกทั้งหมด"
+})
+//end v1.x content
+);
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/th/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/th/Filter.js
new file mode 100644
index 0000000..cb3f948
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/th/Filter.js
@@ -0,0 +1,89 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/th/Filter", //begin v1.x content
+({
+ "clearFilterDialogTitle": "ลบตัวกรอง",
+ "filterDefDialogTitle": "ตัวกรอง",
+ "ruleTitleTemplate": "กฏ ${0}",
+
+ "conditionEqual": "เท่ากับ",
+ "conditionNotEqual": "ไม่เท่ากับ",
+ "conditionLess": "น้อยกว่า",
+ "conditionLessEqual": "น้อยกว่าหรือเท่ากับ",
+ "conditionLarger": "มากกว่า",
+ "conditionLargerEqual": "มากกว่าหรือเท่ากับ",
+ "conditionContains": "ประกอบด้วย",
+ "conditionIs": "เป็น",
+ "conditionStartsWith": "เริ่มต้นด้วย",
+ "conditionEndWith": "ลงท้ายด้วย",
+ "conditionNotContain": "ไม่ประกอบด้วย",
+ "conditionIsNot": "ไม่",
+ "conditionNotStartWith": "ไม่เริ่มต้นด้วย",
+ "conditionNotEndWith": "ไม่ลงท้ายด้วย",
+ "conditionBefore": "ก่อน",
+ "conditionAfter": "หลัง",
+ "conditionRange": "ช่วง",
+ "conditionIsEmpty": "ว่างอยู่",
+
+ "all": "ทั้งหมด",
+ "any": "ใด",
+ "relationAll": "กฏทั้งหมด",
+ "waiRelAll": "ตรงกับกฏทั้งหมดต่อไปนี้:",
+ "relationAny": "กฏใดๆ",
+ "waiRelAny": "ตรงกับกฏใดๆต่อไปนี้:",
+ "relationMsgFront": "ตรงกับ",
+ "relationMsgTail": "",
+ "and": "และ",
+ "or": "หรือ",
+
+ "addRuleButton": "เพิ่มกฏ",
+ "waiAddRuleButton": "เพิ่มกฏใหม่",
+ "removeRuleButton": "ลบกฏ",
+ "waiRemoveRuleButtonTemplate": "ลบกฏ ${0}",
+
+ "cancelButton": "ยกเลิก",
+ "waiCancelButton": "ยกเลิกไดอะล็อกนี้",
+ "clearButton": "ลบ",
+ "waiClearButton": "ลบตัวกรอง",
+ "filterButton": "ตัวกรอง",
+ "waiFilterButton": "ส่งตัวกรอง",
+
+ "columnSelectLabel": "คอลัมน์",
+ "waiColumnSelectTemplate": "คอลัมน์สำหรับกฏ ${0}",
+ "conditionSelectLabel": "เงื่อนไข",
+ "waiConditionSelectTemplate": "เงื่อนไขสำหรับกฏ ${0}",
+ "valueBoxLabel": "ค่า",
+ "waiValueBoxTemplate": "ป้อนค่าให้กับตัวกรองสำหรับกฏ ${0}",
+
+ "rangeTo": "ถึง",
+ "rangeTemplate": "จาก ${0} ถึง ${1}",
+
+ "statusTipHeaderColumn": "คอลัมน์",
+ "statusTipHeaderCondition": "กฏ",
+ "statusTipTitle": "แถบตัวกรอง",
+ "statusTipMsg": "คลิกที่แถบตัวกรองที่นี่เพื่อกรองค่าใน ${0}",
+ "anycolumn": "คอลัมน์ใดๆ",
+ "statusTipTitleNoFilter": "แถบตัวกรอง",
+ "statusTipTitleHasFilter": "ตัวกรอง",
+ "statusTipRelAny": "ตรงกับกฏใดๆ",
+ "statusTipRelAll": "ตรงกับทุกกฏ",
+
+ "defaultItemsName": "ไอเท็ม",
+ "filterBarMsgHasFilterTemplate": "${0} ของ ${1} ${2} จะถูกแสดง",
+ "filterBarMsgNoFilterTemplate": "ไม่นำตัวกรองไปใช้",
+
+ "filterBarDefButton": "กำหนดตัวกรอง",
+ "waiFilterBarDefButton": "กรองตาราง",
+ "a11yFilterBarDefButton": "ตัวกรอง...",
+ "filterBarClearButton": "ลบตัวกรอง",
+ "waiFilterBarClearButton": "ลบตัวกรอง",
+ "closeFilterBarBtn": "ปิดแถบตัวกรอง",
+
+ "clearFilterMsg": "ซึ่งจะลบตัวกรองออกและแสดงเร็กคอร์ดที่พร้อมใช้งานทั้งหมด",
+ "anyColumnOption": "คอลัมน์ใดๆ",
+
+ "trueLabel": "จริง",
+ "falseLabel": "เท็จ"
+})
+//end v1.x content
+);
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/th/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/th/Pagination.js
new file mode 100644
index 0000000..b3d536e
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/th/Pagination.js
@@ -0,0 +1,24 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/th/Pagination", //begin v1.x content
+({
+ "descTemplate": "${2} - ${3} จาก ${1} ${0}",
+ "firstTip": "หน้าแรก",
+ "lastTip": "หน้าสุดท้าย",
+ "nextTip": "หน้าถัดไป",
+ "prevTip": "หน้าก่อนหน้านี้",
+ "itemTitle": "ไอเท็ม",
+ "singularItemTitle": "ไอเท็ม",
+ "pageStepLabelTemplate": "หน้า ${0}",
+ "pageSizeLabelTemplate": "${0} ไอเท็มต่อหน้า",
+ "allItemsLabelTemplate": "รายการ ทั้งหมด",
+ "gotoButtonTitle": "ไปที่หน้าที่ระบุ",
+ "dialogTitle": "ไปที่หน้า",
+ "dialogIndication": "ระบุหมายเลขหน้า",
+ "pageCountIndication": " (${0} หน้า)",
+ "dialogConfirm": "ไปที่",
+ "dialogCancel": "ยกเลิก",
+ "all": "ทั้งหมด"
+})
+//end v1.x content
+);
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/tr/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/tr/EnhancedGrid.js
new file mode 100644
index 0000000..78c566b
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/tr/EnhancedGrid.js
@@ -0,0 +1,17 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/tr/EnhancedGrid", //begin v1.x content
+({
+ singleSort: "Tekli Sıralama",
+ nestedSort: "İç İçe Sıralama",
+ ascending: "Artan Düzende",
+ descending: "Azalan Düzende",
+ sortingState: "${0} - ${1}",
+ unsorted: "Bu sütunu sıralama",
+ indirectSelectionRadio: "Satır ${0}, tek seçimli, radyo düğmesi",
+ indirectSelectionCheckBox: "Satır ${0}, çok seçimli, radyo düğmesi",
+ selectAll: "Tümünü seç"
+})
+//end v1.x content
+);
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/tr/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/tr/Filter.js
new file mode 100644
index 0000000..06ed5e7
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/tr/Filter.js
@@ -0,0 +1,89 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/tr/Filter", //begin v1.x content
+({
+ "clearFilterDialogTitle": "Süzgeci Kaldır",
+ "filterDefDialogTitle": "Süzgeç",
+ "ruleTitleTemplate": "Kural ${0}",
+
+ "conditionEqual": "eşittir",
+ "conditionNotEqual": "eşit değildir",
+ "conditionLess": "küçüktür",
+ "conditionLessEqual": "küçüktür veya eşittir",
+ "conditionLarger": "büyüktür",
+ "conditionLargerEqual": "büyüktür veya eşittir",
+ "conditionContains": "içerir",
+ "conditionIs": "şudur",
+ "conditionStartsWith": "şununla başlar",
+ "conditionEndWith": "şununla biter",
+ "conditionNotContain": "içermez",
+ "conditionIsNot": "şu değildir",
+ "conditionNotStartWith": "şununla başlamaz",
+ "conditionNotEndWith": "şununla bitmez",
+ "conditionBefore": "önce",
+ "conditionAfter": "sonra",
+ "conditionRange": "aralık",
+ "conditionIsEmpty": "boş",
+
+ "all": "tümü",
+ "any": "herhangi biri",
+ "relationAll": "tüm kurallar",
+ "waiRelAll": "Aşağıdaki tüm kurallarla eşleştir",
+ "relationAny": "kuralların herhangi biri",
+ "waiRelAny": "Aşağıdaki kuralların herhangi biri ile eşleştir",
+ "relationMsgFront": "Eşleştir",
+ "relationMsgTail": "",
+ "and": "ve",
+ "or": "veya",
+
+ "addRuleButton": "Kural Ekle",
+ "waiAddRuleButton": "Yeni bir kural ekle",
+ "removeRuleButton": "Kuralı Kaldır",
+ "waiRemoveRuleButtonTemplate": "${0} kuralını kaldır",
+
+ "cancelButton": "İptal",
+ "waiCancelButton": "Bu iletişim kutusunu iptal et",
+ "clearButton": "Kaldır",
+ "waiClearButton": "Süzgeci kaldır",
+ "filterButton": "Süzgeç",
+ "waiFilterButton": "Süzgeci gönder",
+
+ "columnSelectLabel": "Sütun",
+ "waiColumnSelectTemplate": "${0} kuralı için sütun",
+ "conditionSelectLabel": "Koşul",
+ "waiConditionSelectTemplate": "${0} kuralı için koşul",
+ "valueBoxLabel": "Değer",
+ "waiValueBoxTemplate": "${0} kuralı için süzülecek değeri girin",
+
+ "rangeTo": "bitiş",
+ "rangeTemplate": "${0} - ${1}",
+
+ "statusTipHeaderColumn": "Sütun",
+ "statusTipHeaderCondition": "Kurallar",
+ "statusTipTitle": "Süzgeç Çubuğu",
+ "statusTipMsg": "${0} içindeki değerlere göre süzmek için burada süzgeç çubuğunu tıklatın.",
+ "anycolumn": "herhangi bir sütun",
+ "statusTipTitleNoFilter": "Süzgeç Çubuğu",
+ "statusTipTitleHasFilter": "Süzgeç",
+ "statusTipRelAny": "Herhangi bir kuralı eşleştir.",
+ "statusTipRelAll": "Bütün kuralları eşleştir.",
+
+ "defaultItemsName": "öğe",
+ "filterBarMsgHasFilterTemplate": "${0} / ${1} ${2} gösteriliyor.",
+ "filterBarMsgNoFilterTemplate": "Süzgeç uygulanmadı",
+
+ "filterBarDefButton": "Süzgeç tanımla",
+ "waiFilterBarDefButton": "Tabloyu süz",
+ "a11yFilterBarDefButton": "Süz...",
+ "filterBarClearButton": "Süzgeci kaldır",
+ "waiFilterBarClearButton": "Süzgeci kaldır",
+ "closeFilterBarBtn": "Süzgeç çubuğunu kapat",
+
+ "clearFilterMsg": "Bu seçenek süzgeci kaldırır ve tüm kullanılabilir kayıtları gösterir.",
+ "anyColumnOption": "Herhangi Bir Sütun",
+
+ "trueLabel": "Doğru",
+ "falseLabel": "Yanlış"
+})
+//end v1.x content
+);
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/tr/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/tr/Pagination.js
new file mode 100644
index 0000000..94eb9a2
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/tr/Pagination.js
@@ -0,0 +1,24 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/tr/Pagination", //begin v1.x content
+({
+ "descTemplate": "${2} - ${3} / ${1} ${0}",
+ "firstTip": "İlk Sayfa",
+ "lastTip": "Son Sayfa",
+ "nextTip": "Sonraki Sayfa",
+ "prevTip": "Önceki Sayfa",
+ "itemTitle": "öğe",
+ "singularItemTitle": "öğe",
+ "pageStepLabelTemplate": "Sayfa ${0}",
+ "pageSizeLabelTemplate": "Sayfa başına ${0} öğe",
+ "allItemsLabelTemplate": "Tüm öğeler",
+ "gotoButtonTitle": "Belirli bir sayfaya git",
+ "dialogTitle": "Sayfaya Git",
+ "dialogIndication": "Sayfa numarasını belirtin",
+ "pageCountIndication": " (${0} sayfa)",
+ "dialogConfirm": "Git",
+ "dialogCancel": "İptal",
+ "all": "tümü"
+})
+//end v1.x content
+);
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/zh-tw/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/zh-tw/EnhancedGrid.js
new file mode 100644
index 0000000..d25ffdb
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/zh-tw/EnhancedGrid.js
@@ -0,0 +1,17 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/zh-tw/EnhancedGrid", //begin v1.x content
+({
+ singleSort: "單一排序",
+ nestedSort: "巢狀排序",
+ ascending: "遞增",
+ descending: "降冪",
+ sortingState: "${0} - ${1}",
+ unsorted: "請勿對此欄執行排序",
+ indirectSelectionRadio: "第 ${0} 行,單一選項,圓鈕框",
+ indirectSelectionCheckBox: "第 ${0} 行,多重選項,勾選框",
+ selectAll: "全選"
+})
+//end v1.x content
+);
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/zh-tw/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/zh-tw/Filter.js
new file mode 100644
index 0000000..4488b78
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/zh-tw/Filter.js
@@ -0,0 +1,89 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/zh-tw/Filter", //begin v1.x content
+({
+ "clearFilterDialogTitle": "清除過濾器",
+ "filterDefDialogTitle": "過濾器",
+ "ruleTitleTemplate": "規則 ${0}",
+
+ "conditionEqual": "等於",
+ "conditionNotEqual": "不等於",
+ "conditionLess": "是小於",
+ "conditionLessEqual": "小於或等於",
+ "conditionLarger": "是大於",
+ "conditionLargerEqual": "大於或等於",
+ "conditionContains": "內容",
+ "conditionIs": "是",
+ "conditionStartsWith": "開始於",
+ "conditionEndWith": "結束於",
+ "conditionNotContain": "不包含",
+ "conditionIsNot": "不是",
+ "conditionNotStartWith": "不開始於",
+ "conditionNotEndWith": "不結束於",
+ "conditionBefore": "之前",
+ "conditionAfter": "之後",
+ "conditionRange": "範圍",
+ "conditionIsEmpty": "為空",
+
+ "all": "全部",
+ "any": "任何",
+ "relationAll": "所有規則",
+ "waiRelAll": "符合下列所有規則:",
+ "relationAny": "任何規則",
+ "waiRelAny": "符合下列任何規則:",
+ "relationMsgFront": "符合",
+ "relationMsgTail": "",
+ "and": "和",
+ "or": "或",
+
+ "addRuleButton": "新增規則",
+ "waiAddRuleButton": "新增規則",
+ "removeRuleButton": "移除規則",
+ "waiRemoveRuleButtonTemplate": "移除規則 ${0}",
+
+ "cancelButton": "取消",
+ "waiCancelButton": "取消此對話",
+ "clearButton": "清除",
+ "waiClearButton": "清除過濾器",
+ "filterButton": "過濾器",
+ "waiFilterButton": "提交過濾器",
+
+ "columnSelectLabel": "直欄",
+ "waiColumnSelectTemplate": "規則 ${0} 的直欄",
+ "conditionSelectLabel": "條件",
+ "waiConditionSelectTemplate": "規則 ${0} 的條件",
+ "valueBoxLabel": "值",
+ "waiValueBoxTemplate": "輸入要針對規則 ${0} 過濾的值",
+
+ "rangeTo": "至",
+ "rangeTemplate": "從 ${0} 至 ${1}",
+
+ "statusTipHeaderColumn": "直欄",
+ "statusTipHeaderCondition": "規則",
+ "statusTipTitle": "過濾器列",
+ "statusTipMsg": "按一下這裡的過濾器列以過濾 ${0} 中的值。",
+ "anycolumn": "任何直欄",
+ "statusTipTitleNoFilter": "過濾器列",
+ "statusTipTitleHasFilter": "過濾器",
+ "statusTipRelAny": "符合任何規則。",
+ "statusTipRelAll": "符合所有規則。",
+
+ "defaultItemsName": "項目",
+ "filterBarMsgHasFilterTemplate": "顯示 ${1} ${2} 之 ${0}。",
+ "filterBarMsgNoFilterTemplate": "未套用過濾器",
+
+ "filterBarDefButton": "定義過濾器",
+ "waiFilterBarDefButton": "過濾表格",
+ "a11yFilterBarDefButton": "過濾器...",
+ "filterBarClearButton": "清除過濾器",
+ "waiFilterBarClearButton": "清除過濾器",
+ "closeFilterBarBtn": "關閉過濾器列",
+
+ "clearFilterMsg": "這將會移除過濾器並顯示所有的可用記錄。",
+ "anyColumnOption": "任何直欄",
+
+ "trueLabel": "True",
+ "falseLabel": "False"
+})
+//end v1.x content
+);
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/zh-tw/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/zh-tw/Pagination.js
new file mode 100644
index 0000000..8f29af0
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/zh-tw/Pagination.js
@@ -0,0 +1,25 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/zh-tw/Pagination", //begin v1.x content
+({
+ "descTemplate": "${2} - ${3} / ${1} ${0}",
+ "firstTip": "首頁",
+ "lastTip": "末頁",
+ "nextTip": "下一頁",
+ "prevTip": "上一頁",
+ "itemTitle": "項目",
+ "singularItemTitle": "項目",
+ "pageStepLabelTemplate": "第 ${0} 頁",
+ "pageSizeLabelTemplate": "每頁 ${0} 個項目",
+ "allItemsLabelTemplate": "所有項目",
+ "gotoButtonTitle": "跳至特定頁面",
+ "dialogTitle": "跳至頁面",
+ "dialogIndication": "指定頁碼",
+ "pageCountIndication": "(${0} 頁)",
+ "dialogConfirm": "執行",
+ "dialogCancel": "取消",
+ "all": "全部"
+})
+//end v1.x content
+);
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/zh/EnhancedGrid.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/zh/EnhancedGrid.js
new file mode 100644
index 0000000..6494ae4
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/zh/EnhancedGrid.js
@@ -0,0 +1,17 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/zh/EnhancedGrid", //begin v1.x content
+({
+ singleSort: "单层排序",
+ nestedSort: "嵌套排序",
+ ascending: "升序",
+ descending: "降序",
+ sortingState: "${0} - ${1}",
+ unsorted: "请勿对此列进行排序",
+ indirectSelectionRadio: "第 ${0} 行,单选,单选框",
+ indirectSelectionCheckBox: "第 ${0} 行,多选,复选框",
+ selectAll: "全部选中"
+})
+//end v1.x content
+);
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/zh/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/zh/Filter.js
new file mode 100644
index 0000000..f0f9f2b
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/zh/Filter.js
@@ -0,0 +1,89 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/zh/Filter", //begin v1.x content
+({
+ "clearFilterDialogTitle": "清除过滤器",
+ "filterDefDialogTitle": "过滤器",
+ "ruleTitleTemplate": "规则 ${0}",
+
+ "conditionEqual": "等于",
+ "conditionNotEqual": "不等于",
+ "conditionLess": "小于",
+ "conditionLessEqual": "小于或等于",
+ "conditionLarger": "大于",
+ "conditionLargerEqual": "大于或等于",
+ "conditionContains": "包含",
+ "conditionIs": "是",
+ "conditionStartsWith": "开始于",
+ "conditionEndWith": "结束于",
+ "conditionNotContain": "不包含",
+ "conditionIsNot": "非",
+ "conditionNotStartWith": "不是开始于",
+ "conditionNotEndWith": "不是结束于",
+ "conditionBefore": "先于",
+ "conditionAfter": "后于",
+ "conditionRange": "范围",
+ "conditionIsEmpty": "为空",
+
+ "all": "全部",
+ "any": "任何",
+ "relationAll": "所有规则",
+ "waiRelAll": "符合以下所有规则:",
+ "relationAny": "任何规则",
+ "waiRelAny": "符合以下任何规则:",
+ "relationMsgFront": "符合",
+ "relationMsgTail": "",
+ "and": "和",
+ "or": "或",
+
+ "addRuleButton": "添加规则",
+ "waiAddRuleButton": "添加新规则",
+ "removeRuleButton": "除去规则",
+ "waiRemoveRuleButtonTemplate": "除去规则 ${0}",
+
+ "cancelButton": "取消",
+ "waiCancelButton": "取消该对话",
+ "clearButton": "清除",
+ "waiClearButton": "清除过滤器",
+ "filterButton": "过滤器",
+ "waiFilterButton": "提交过滤器",
+
+ "columnSelectLabel": "列",
+ "waiColumnSelectTemplate": "规则 ${0} 的列",
+ "conditionSelectLabel": "条件",
+ "waiConditionSelectTemplate": "规则 ${0} 的条件",
+ "valueBoxLabel": "值",
+ "waiValueBoxTemplate": "将规则 ${0} 的值输入过滤器",
+
+ "rangeTo": "到",
+ "rangeTemplate": "从 ${0} 到 ${1}",
+
+ "statusTipHeaderColumn": "列",
+ "statusTipHeaderCondition": "规则",
+ "statusTipTitle": "过滤器栏",
+ "statusTipMsg": "单击此处的过滤器栏以过滤 ${0} 中的值。",
+ "anycolumn": "任何列",
+ "statusTipTitleNoFilter": "过滤器栏",
+ "statusTipTitleHasFilter": "过滤器",
+ "statusTipRelAny": "与任何规则匹配。",
+ "statusTipRelAll": "与所有规则匹配。",
+
+ "defaultItemsName": "项目",
+ "filterBarMsgHasFilterTemplate": "显示的 ${1} ${2} 的 ${0}。",
+ "filterBarMsgNoFilterTemplate": "未使用过滤器",
+
+ "filterBarDefButton": "定义过滤器",
+ "waiFilterBarDefButton": "过滤表",
+ "a11yFilterBarDefButton": "过滤器...",
+ "filterBarClearButton": "清除过滤器",
+ "waiFilterBarClearButton": "清除过滤器",
+ "closeFilterBarBtn": "关闭过滤器栏",
+
+ "clearFilterMsg": "该操作将除去过滤器并显示所有现有记录。",
+ "anyColumnOption": "任何列",
+
+ "trueLabel": "True",
+ "falseLabel": "False"
+})
+//end v1.x content
+);
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/nls/zh/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/nls/zh/Pagination.js
new file mode 100644
index 0000000..1e1b5c6
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/nls/zh/Pagination.js
@@ -0,0 +1,25 @@
+//>>built
+define(
+"dojox/grid/enhanced/nls/zh/Pagination", //begin v1.x content
+({
+ "descTemplate": "${1} 个${0}中的 ${2} - ${3}",
+ "firstTip": "第一页",
+ "lastTip": "最后一页",
+ "nextTip": "下一页",
+ "prevTip": "上一页",
+ "itemTitle": "项目",
+ "singularItemTitle": "项",
+ "pageStepLabelTemplate": "第 ${0} 页",
+ "pageSizeLabelTemplate": "每页的 ${0} 项目",
+ "allItemsLabelTemplate": "所有项目",
+ "gotoButtonTitle": "转到指定页面",
+ "dialogTitle": "转到页面",
+ "dialogIndication": "指定页数",
+ "pageCountIndication": "(${0} 页)",
+ "dialogConfirm": "确定",
+ "dialogCancel": "取消",
+ "all": "全部"
+})
+//end v1.x content
+);
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/AutoScroll.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/AutoScroll.js
new file mode 100644
index 0000000..0dcb466
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/AutoScroll.js
@@ -0,0 +1,182 @@
+//>>built
+define("dojox/grid/enhanced/plugins/AutoScroll", [
+ "dojo/_base/declare",
+ "dojo/_base/array",
+ "dojo/_base/lang",
+ "dojo/_base/html",
+ "dojo/_base/window",
+ "../_Plugin",
+ "../../_RowSelector",
+ "../../EnhancedGrid"
+], function(declare, array, lang, html, win, _Plugin, _RowSelector, EnhancedGrid){
+
+var AutoScroll = declare("dojox.grid.enhanced.plugins.AutoScroll", _Plugin, {
+ // summary:
+ // Provides horizontal and vertical auto-scroll for grid.
+
+ // name: String
+ // Plugin name
+ name: "autoScroll",
+
+ // autoScrollInterval: Integer
+ // The time interval (in miliseconds) between 2 scrolling.
+ autoScrollInterval: 1000,
+
+ // autoScrollMargin: Integer
+ // The width (in pixel) of the margin area where autoscroll can be triggered.
+ autoScrollMargin: 30,
+
+ constructor: function(grid, args){
+ this.grid = grid;
+ this.readyForAutoScroll = false;
+ this._scrolling = false;
+ args = lang.isObject(args) ? args : {};
+ if("interval" in args){
+ this.autoScrollInterval = args.interval;
+ }
+ if("margin" in args){
+ this.autoScrollMargin = args.margin;
+ }
+ this._initEvents();
+ this._mixinGrid();
+ },
+ _initEvents: function(){
+ var g = this.grid;
+ this.connect(g, "onCellMouseDown", function(){
+ this.readyForAutoScroll = true;
+ });
+ this.connect(g, "onHeaderCellMouseDown", function(){
+ this.readyForAutoScroll = true;
+ });
+ this.connect(g, "onRowSelectorMouseDown", function(){
+ this.readyForAutoScroll = true;
+ });
+ this.connect(win.doc, "onmouseup", function(evt){
+ this._manageAutoScroll(true);
+ this.readyForAutoScroll = false;
+ });
+ this.connect(win.doc, "onmousemove", function(evt){
+ if(this.readyForAutoScroll){
+ this._event = evt;
+ var gridPos = html.position(g.domNode),
+ hh = g._getHeaderHeight(),
+ margin = this.autoScrollMargin,
+ ey = evt.clientY, ex = evt.clientX,
+ gy = gridPos.y, gx = gridPos.x,
+ gh = gridPos.h, gw = gridPos.w;
+ if(ex >= gx && ex <= gx + gw){
+ if(ey >= gy + hh && ey < gy + hh + margin){
+ this._manageAutoScroll(false, true, false);
+ return;
+ }else if(ey > gy + gh - margin && ey <= gy + gh){
+ this._manageAutoScroll(false, true, true);
+ return;
+ }else if(ey >= gy && ey <= gy + gh){
+ var withinSomeview = array.some(g.views.views, function(view, i){
+ if(view instanceof _RowSelector){
+ return false;
+ }
+ var viewPos = html.position(view.domNode);
+ if(ex < viewPos.x + margin && ex >= viewPos.x){
+ this._manageAutoScroll(false, false, false, view);
+ return true;
+ }else if(ex > viewPos.x + viewPos.w - margin && ex < viewPos.x + viewPos.w){
+ this._manageAutoScroll(false, false, true, view);
+ return true;
+ }
+ return false;
+ }, this);
+ if(withinSomeview){
+ return;
+ }
+ }
+ }
+ //stop autoscroll.
+ this._manageAutoScroll(true);
+ }
+ });
+ },
+ _mixinGrid: function(){
+ var g = this.grid;
+ g.onStartAutoScroll = function(/*isVertical, isForward*/){};
+ g.onEndAutoScroll = function(/*isVertical, isForward, view, scrollToRowIndex, event*/){};
+ },
+ _fireEvent: function(eventName, args){
+ var g = this.grid;
+ switch(eventName){
+ case "start":
+ g.onStartAutoScroll.apply(g, args);
+ break;
+ case "end":
+ g.onEndAutoScroll.apply(g, args);
+ break;
+ }
+ },
+ _manageAutoScroll: function(toStop, isVertical, isForward, view){
+ if(toStop){
+ this._scrolling = false;
+ clearInterval(this._handler);
+ }else if(!this._scrolling){
+ this._scrolling = true;
+ this._fireEvent("start", [isVertical, isForward, view]);
+ this._autoScroll(isVertical, isForward, view);
+ this._handler = setInterval(lang.hitch(this, "_autoScroll", isVertical, isForward, view), this.autoScrollInterval);
+ }
+ },
+ _autoScroll: function(isVertical, isForward, view){
+ var g = this.grid,
+ target = null;
+ if(isVertical){
+ var targetRow = g.scroller.firstVisibleRow + (isForward ? 1 : -1);
+ if(targetRow >= 0 && targetRow < g.rowCount){
+ g.scrollToRow(targetRow);
+ target = targetRow;
+ }
+ }else{
+ target = this._scrollColumn(isForward, view);
+ }
+ if(target !== null){
+ this._fireEvent("end", [isVertical, isForward, view, target, this._event]);
+ }
+ },
+ _scrollColumn: function(isForward, view){
+ var node = view.scrollboxNode,
+ target = null;
+ if(node.clientWidth < node.scrollWidth){
+ var cells = array.filter(this.grid.layout.cells, function(cell){
+ return !cell.hidden;
+ });
+ var viewPos = html.position(view.domNode);
+ var limit, edge, headerPos, i;
+ if(isForward){
+ limit = node.clientWidth;
+ for(i = 0; i < cells.length; ++i){
+ headerPos = html.position(cells[i].getHeaderNode());
+ edge = headerPos.x - viewPos.x + headerPos.w;
+ if(edge > limit){
+ target = cells[i].index;
+ node.scrollLeft += edge - limit + 10;
+ break;
+ }
+ }
+ }else{
+ limit = 0;
+ for(i = cells.length - 1; i >= 0; --i){
+ headerPos = html.position(cells[i].getHeaderNode());
+ edge = headerPos.x - viewPos.x;
+ if(edge < limit){
+ target = cells[i].index;
+ node.scrollLeft += edge - limit - 10;
+ break;
+ }
+ }
+ }
+ }
+ return target;
+ }
+});
+
+EnhancedGrid.registerPlugin(AutoScroll);
+
+return AutoScroll;
+});
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/CellMerge.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/CellMerge.js
new file mode 100644
index 0000000..7284ace
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/CellMerge.js
@@ -0,0 +1,276 @@
+//>>built
+define("dojox/grid/enhanced/plugins/CellMerge", [
+ "dojo/_base/declare",
+ "dojo/_base/array",
+ "dojo/_base/lang",
+ "dojo/_base/html",
+ "../_Plugin",
+ "../../EnhancedGrid"
+], function(declare, array, lang, html, _Plugin, EnhancedGrid){
+
+var CellMerge = declare("dojox.grid.enhanced.plugins.CellMerge", _Plugin, {
+ // summary:
+ // This plugin provides functions to merge(un-merge) adjacent cells within one row.
+ // Acceptable plugin paramters:
+ // 1. mergedCells: Array
+ // An array of objects with structure:
+ // {
+ // row: function(Integer)|Integer
+ // If it's a function, it's a predicate to decide which rows are to be merged.
+ // It takes an integer (the row index), and should return true or false;
+ // start: Integer
+ // The column index of the left most cell that shall be merged.
+ // end: Integer
+ // The column index of the right most cell that shall be merged.
+ // major: Integer
+ // The column index of the cell whose content should be used as the content of the merged cell.
+ // It must be larger than or equal to the startColumnIndex, and less than or equal to the endColumnIndex.
+ // If it is omitted, the content of the leading edge (left-most for ltr, right most for rtl) cell will be used.
+ // }
+
+ // name: String
+ // Plugin name
+ name: "cellMerge",
+
+ constructor: function(grid, args){
+ this.grid = grid;
+ this._records = [];
+ this._merged = {};
+ if(args && lang.isObject(args)){
+ this._setupConfig(args.mergedCells);
+ }
+ this._initEvents();
+ this._mixinGrid();
+ },
+ //----------------Public----------------------------
+ mergeCells: function(rowTester, startColumnIndex, endColumnIndex, majorColumnIndex){
+ // summary:
+ // Merge cells from *startColumnIndex* to *endColumnIndex* at rows that make *rowTester* return true,
+ // using the content of the cell at *majorColumnIndex*
+ // tags:
+ // public
+ // rowTester: function(Integer)|Integer
+ // If it's a function, it's a predicate to decide which rows are to be merged.
+ // It takes an integer (the row index), and should return true or false;
+ // startColumnIndex: Integer
+ // The column index of the left most cell that shall be merged.
+ // endColumnIndex: Integer
+ // The column index of the right most cell that shall be merged.
+ // majorColumnIndex: Integer?
+ // The column index of the cell whose content should be used as the content of the merged cell.
+ // It must be larger than or equal to the startColumnIndex, and less than or equal to the endColumnIndex.
+ // If it is omitted, the content of the leading edge (left-most for ltr, right most for rtl) cell will be used.
+ // return: Object | null
+ // A handler for the merged cells created by a call of this function.
+ // This handler can be used later to unmerge cells using the function unmergeCells
+ // If the merge is not valid, returns null;
+ var item = this._createRecord({
+ "row": rowTester,
+ "start": startColumnIndex,
+ "end": endColumnIndex,
+ "major": majorColumnIndex
+ });
+ if(item){
+ this._updateRows(item);
+ }
+ return item;
+ },
+ unmergeCells: function(mergeHandler){
+ // summary:
+ // Unmerge the cells that are merged by the *mergeHandler*, which represents a call to the function mergeCells.
+ // tags:
+ // public
+ // mergeHandler: object
+ // A handler for the merged cells created by a call of function mergeCells.
+ var idx;
+ if(mergeHandler && (idx = array.indexOf(this._records, mergeHandler)) >= 0){
+ this._records.splice(idx, 1);
+ this._updateRows(mergeHandler);
+ }
+ },
+ getMergedCells: function(){
+ // summary:
+ // Get all records of currently merged cells.
+ // tags:
+ // public
+ // return: Array
+ // An array of records for merged-cells.
+ // The record has the following structure:
+ // {
+ // "row": 1, //the row index
+ // "start": 2, //the start column index
+ // "end": 4, //the end column index
+ // "major": 3, //the major column index
+ // "handle": someHandle, //The handler that covers this merge cell record.
+ // }
+ var res = [];
+ for(var i in this._merged){
+ res = res.concat(this._merged[i]);
+ }
+ return res;
+ },
+ getMergedCellsByRow: function(rowIndex){
+ // summary:
+ // Get the records of currently merged cells at the given row.
+ // tags:
+ // public
+ // return: Array
+ // An array of records for merged-cells. See docs of getMergedCells.
+ return this._merged[rowIndex] || [];
+ },
+
+ //----------------Private--------------------------
+ _setupConfig: function(config){
+ array.forEach(config, this._createRecord, this);
+ },
+ _initEvents: function(){
+ array.forEach(this.grid.views.views, function(view){
+ this.connect(view, "onAfterRow", lang.hitch(this, "_onAfterRow", view.index));
+ }, this);
+ },
+ _mixinGrid: function(){
+ var g = this.grid;
+ g.mergeCells = lang.hitch(this, "mergeCells");
+ g.unmergeCells = lang.hitch(this, "unmergeCells");
+ g.getMergedCells = lang.hitch(this, "getMergedCells");
+ g.getMergedCellsByRow = lang.hitch(this, "getMergedCellsByRow");
+ },
+ _getWidth: function(colIndex){
+ var node = this.grid.layout.cells[colIndex].getHeaderNode();
+ return html.position(node).w;
+ },
+ _onAfterRow: function(viewIdx, rowIndex, subrows){
+ try{
+ if(rowIndex < 0){
+ return;
+ }
+ var result = [], i, j, len = this._records.length,
+ cells = this.grid.layout.cells;
+ //Apply merge-cell requests one by one.
+ for(i = 0; i < len; ++i){
+ var item = this._records[i];
+ var storeItem = this.grid._by_idx[rowIndex];
+ if(item.view == viewIdx && item.row(rowIndex, storeItem && storeItem.item, this.grid.store)){
+ var res = {
+ record: item,
+ hiddenCells: [],
+ totalWidth: 0,
+ majorNode: cells[item.major].getNode(rowIndex),
+ majorHeaderNode: cells[item.major].getHeaderNode()
+ };
+ //Calculated the width of merged cell.
+ for(j = item.start; j <= item.end; ++j){
+ var w = this._getWidth(j, rowIndex);
+ res.totalWidth += w;
+ if(j != item.major){
+ res.hiddenCells.push(cells[j].getNode(rowIndex));
+ }
+ }
+ //If width is valid, remember it. There may be multiple merges within one row.
+ if(subrows.length != 1 || res.totalWidth > 0){
+ //Remove conflicted merges.
+ for(j = result.length - 1; j >= 0; --j){
+ var r = result[j].record;
+ if((r.start >= item.start && r.start <= item.end) ||
+ (r.end >= item.start && r.end <= item.end)){
+ result.splice(j, 1);
+ }
+ }
+ result.push(res);
+ }
+ }
+ }
+ this._merged[rowIndex] = [];
+ array.forEach(result, function(res){
+ array.forEach(res.hiddenCells, function(node){
+ html.style(node, "display", "none");
+ });
+ var pbm = html.marginBox(res.majorHeaderNode).w - html.contentBox(res.majorHeaderNode).w;
+ var tw = res.totalWidth;
+
+ //Tricky for WebKit.
+ if(!html.isWebKit){
+ tw -= pbm;
+ }
+
+ html.style(res.majorNode, "width", tw + "px");
+ //In case we're dealing with multiple subrows.
+ res.majorNode.setAttribute("colspan", res.hiddenCells.length + 1);
+
+ this._merged[rowIndex].push({
+ "row": rowIndex,
+ "start": res.record.start,
+ "end": res.record.end,
+ "major": res.record.major,
+ "handle": res.record
+ });
+ }, this);
+ }catch(e){
+ console.warn("CellMerge._onAfterRow() error: ", rowIndex, e);
+ }
+ },
+ _createRecord: function(item){
+ if(this._isValid(item)){
+ item = {
+ "row": item.row,
+ "start": item.start,
+ "end": item.end,
+ "major": item.major
+ };
+ var cells = this.grid.layout.cells;
+ item.view = cells[item.start].view.index;
+ item.major = typeof item.major == "number" && !isNaN(item.major) ? item.major : item.start;
+ if(typeof item.row == "number"){
+ var r = item.row;
+ item.row = function(rowIndex){
+ return rowIndex === r;
+ };
+ }else if(typeof item.row == "string"){
+ var id = item.row;
+ item.row = function(rowIndex, storeItem, store){
+ try{
+ if(store && storeItem && store.getFeatures()['dojo.data.api.Identity']){
+ return store.getIdentity(storeItem) == id;
+ }
+ }catch(e){
+ console.error(e);
+ }
+ return false;
+ };
+ }
+ if(lang.isFunction(item.row)){
+ this._records.push(item);
+ return item;
+ }
+ }
+ return null;
+ },
+ _isValid: function(item){
+ var cells = this.grid.layout.cells,
+ colCount = cells.length;
+ return (lang.isObject(item) && ("row" in item) && ("start" in item) && ("end" in item) &&
+ item.start >= 0 && item.start < colCount &&
+ item.end > item.start && item.end < colCount &&
+ cells[item.start].view.index == cells[item.end].view.index &&
+ cells[item.start].subrow == cells[item.end].subrow &&
+ !(typeof item.major == "number" && (item.major < item.start || item.major > item.end)));
+ },
+ _updateRows: function(item){
+ var min = null;
+ for(var i = 0, count = this.grid.rowCount; i < count; ++i){
+ var storeItem = this.grid._by_idx[i];
+ if(storeItem && item.row(i, storeItem && storeItem.item, this.grid.store)){
+ this.grid.views.updateRow(i);
+ if(min === null){ min = i; }
+ }
+ }
+ if(min >= 0){
+ this.grid.scroller.rowHeightChanged(min);
+ }
+ }
+});
+
+EnhancedGrid.registerPlugin(CellMerge);
+
+return CellMerge;
+});
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Cookie.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Cookie.js
new file mode 100644
index 0000000..d0160f7
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Cookie.js
@@ -0,0 +1,362 @@
+//>>built
+define("dojox/grid/enhanced/plugins/Cookie", [
+ "dojo/_base/declare",
+ "dojo/_base/array",
+ "dojo/_base/lang",
+ "dojo/_base/sniff",
+ "dojo/_base/html",
+ "dojo/_base/json",
+ "dojo/_base/window",
+ "dojo/_base/unload",
+ "dojo/cookie",
+ "../_Plugin",
+ "../../_RowSelector",
+ "../../EnhancedGrid",
+ "../../cells/_base"
+], function(declare, array, lang, has, html, json, win, unload, cookie, _Plugin, _RowSelector, EnhancedGrid){
+
+ var gridCells = lang.getObject("dojox.grid.cells");
+
+ // Generate a cookie key for the given grid.
+ var _cookieKeyBuilder = function(grid){
+ return window.location + "/" + grid.id;
+ };
+
+ //Utilities:
+ var _getCellsFromStructure = function(structure){
+ var cells = [];
+ if(!lang.isArray(structure)){
+ structure = [structure];
+ }
+ array.forEach(structure,function(viewDef){
+ if(lang.isArray(viewDef)){
+ viewDef = {"cells" : viewDef};
+ }
+ var rows = viewDef.rows || viewDef.cells;
+ if(lang.isArray(rows)){
+ if(!lang.isArray(rows[0])){
+ rows = [rows];
+ }
+ array.forEach(rows, function(row){
+ if(lang.isArray(row)){
+ array.forEach(row, function(cell){
+ cells.push(cell);
+ });
+ }
+ });
+ }
+ });
+ return cells;
+ };
+
+ // Persist column width
+ var _loadColWidth = function(colWidths, grid){
+ if(lang.isArray(colWidths)){
+ var oldFunc = grid._setStructureAttr;
+ grid._setStructureAttr = function(structure){
+ if(!grid._colWidthLoaded){
+ grid._colWidthLoaded = true;
+ var cells = _getCellsFromStructure(structure);
+ for(var i = cells.length - 1; i >= 0; --i){
+ if(typeof colWidths[i] == "number"){
+ cells[i].width = colWidths[i] + "px";
+ }else if(colWidths[i] == 'hidden'){
+ cells[i].hidden = true;
+ }
+ }
+ }
+ oldFunc.call(grid, structure);
+ grid._setStructureAttr = oldFunc;
+ };
+ }
+ };
+
+
+ var _saveColWidth = function(grid){
+ return array.map(array.filter(grid.layout.cells, function(cell){
+ return !(cell.isRowSelector || cell instanceof gridCells.RowIndex);
+ }), function(cell){
+ return cell.hidden ? 'hidden' : html[has("webkit") ? "marginBox" : "contentBox"](cell.getHeaderNode()).w;
+ });
+ };
+
+ // Persist column order
+ var _loadColumnOrder = function(colOrder, grid){
+ if(colOrder && array.every(colOrder, function(viewInfo){
+ return lang.isArray(viewInfo) && array.every(viewInfo, function(subrowInfo){
+ return lang.isArray(subrowInfo) && subrowInfo.length > 0;
+ });
+ })){
+ var oldFunc = grid._setStructureAttr;
+ var isCell = function(def){
+ return ("name" in def || "field" in def || "get" in def);
+ };
+ var isView = function(def){
+ return (def !== null && lang.isObject(def) &&
+ ("cells" in def || "rows" in def || ("type" in def && !isCell(def))));
+ };
+ grid._setStructureAttr = function(structure){
+ if(!grid._colOrderLoaded){
+ grid._colOrderLoaded = true;
+ grid._setStructureAttr = oldFunc;
+ structure = lang.clone(structure);
+ if(lang.isArray(structure) && !array.some(structure, isView)){
+ structure = [{ cells: structure }];
+ }else if(isView(structure)){
+ structure = [structure];
+ }
+ var cells = _getCellsFromStructure(structure);
+ array.forEach(lang.isArray(structure) ? structure : [structure], function(viewDef, viewIdx){
+ var cellArray = viewDef;
+ if(lang.isArray(viewDef)){
+ viewDef.splice(0, viewDef.length);
+ }else{
+ delete viewDef.rows;
+ cellArray = viewDef.cells = [];
+ }
+ array.forEach(colOrder[viewIdx], function(subrow){
+ array.forEach(subrow, function(cellInfo){
+ var i, cell;
+ for(i = 0; i < cells.length; ++i){
+ cell = cells[i];
+ if(json.toJson({'name':cell.name,'field':cell.field}) == json.toJson(cellInfo)){
+ break;
+ }
+ }
+ if(i < cells.length){
+ cellArray.push(cell);
+ }
+ });
+ });
+ });
+ }
+ oldFunc.call(grid, structure);
+ };
+ }
+ };
+
+ var _saveColumnOrder = function(grid){
+ var colOrder = array.map(array.filter(grid.views.views, function(view){
+ return !(view instanceof _RowSelector);
+ }), function(view){
+ return array.map(view.structure.cells, function(subrow){
+ return array.map(array.filter(subrow, function(cell){
+ return !(cell.isRowSelector || cell instanceof gridCells.RowIndex);
+ }), function(cell){
+ return {
+ "name": cell.name,
+ "field": cell.field
+ };
+ });
+ });
+ });
+ return colOrder;
+ };
+
+ // Persist sorting order
+ var _loadSortOrder = function(sortOrder, grid){
+ try{
+ if(lang.isObject(sortOrder)){
+ grid.setSortIndex(sortOrder.idx, sortOrder.asc);
+ }
+ }catch(e){
+ //setSortIndex will finally call _fetch, some exceptions will be throw
+ //'cause the grid hasn't be fully loaded now. Just ignore them.
+ }
+ };
+
+ var _saveSortOrder = function(grid){
+ return {
+ idx: grid.getSortIndex(),
+ asc: grid.getSortAsc()
+ };
+ };
+
+ if(!has("ie")){
+ // Now in non-IE, widgets are no longer destroyed on page unload,
+ // so we have to destroy it manually to trigger saving cookie.
+ unload.addOnWindowUnload(function(){
+ array.forEach(dijit.findWidgets(win.body()), function(widget){
+ if(widget instanceof EnhancedGrid && !widget._destroyed){
+ widget.destroyRecursive();
+ }
+ });
+ });
+ }
+
+ var Cookie = declare("dojox.grid.enhanced.plugins.Cookie", _Plugin, {
+ // summary:
+ // This plugin provides a way to persist some grid features in cookie.
+ // Default persistable features are:
+ // column width: "columnWidth" (handler name)
+ // column order: "columnOrder"
+ // sorting order: "sortOrder"
+ //
+ // Grid users can define new persistable features
+ // by calling the following before grid is initialized (that is, during "preInit");
+ // | grid.addCookieHandler({
+ // | name: "a name for the new persistable feature",
+ // | onLoad: function(savedObject, grid){
+ // | //load the cookie.
+ // | },
+ // | onSave: function(grid){
+ // | //save the cookie.
+ // | }
+ // | });
+
+ // name: String
+ // Plugin name
+ name: "cookie",
+
+ _cookieEnabled: true,
+
+ constructor: function(grid, args){
+ this.grid = grid;
+ args = (args && lang.isObject(args)) ? args : {};
+ this.cookieProps = args.cookieProps;
+ this._cookieHandlers = [];
+ this._mixinGrid();
+
+ //Column width & simple sorting & column reorder are base grid features, so they must be supported.
+ this.addCookieHandler({
+ name: "columnWidth",
+ onLoad: _loadColWidth,
+ onSave: _saveColWidth
+ });
+ this.addCookieHandler({
+ name: "columnOrder",
+ onLoad: _loadColumnOrder,
+ onSave: _saveColumnOrder
+ });
+ this.addCookieHandler({
+ name: "sortOrder",
+ onLoad: _loadSortOrder,
+ onSave: _saveSortOrder
+ });
+
+ array.forEach(this._cookieHandlers, function(handler){
+ if(args[handler.name] === false){
+ handler.enable = false;
+ }
+ }, this);
+ },
+ destroy:function(){
+ this._saveCookie();
+ this._cookieHandlers = null;
+ this.inherited(arguments);
+ },
+ _mixinGrid: function(){
+ var g = this.grid;
+ g.addCookieHandler = lang.hitch(this, "addCookieHandler");
+ g.removeCookie = lang.hitch(this, "removeCookie");
+ g.setCookieEnabled = lang.hitch(this, "setCookieEnabled");
+ g.getCookieEnabled = lang.hitch(this, "getCookieEnabled");
+ },
+ _saveCookie: function(){
+ if(this.getCookieEnabled()){
+ var ck = {},
+ chs = this._cookieHandlers,
+ cookieProps = this.cookieProps,
+ cookieKey = _cookieKeyBuilder(this.grid);
+ for(var i = chs.length-1; i >= 0; --i){
+ if(chs[i].enabled){
+ //Do the real saving work here.
+ ck[chs[i].name] = chs[i].onSave(this.grid);
+ }
+ }
+ cookieProps = lang.isObject(this.cookieProps) ? this.cookieProps : {};
+ cookie(cookieKey, json.toJson(ck), cookieProps);
+ }else{
+ this.removeCookie();
+ }
+ },
+ onPreInit: function(){
+ var grid = this.grid,
+ chs = this._cookieHandlers,
+ cookieKey = _cookieKeyBuilder(grid),
+ ck = cookie(cookieKey);
+ if(ck){
+ ck = json.fromJson(ck);
+ for(var i = 0; i < chs.length; ++i){
+ if(chs[i].name in ck && chs[i].enabled){
+ //Do the real loading work here.
+ chs[i].onLoad(ck[chs[i].name], grid);
+ }
+ }
+ }
+ this._cookie = ck || {};
+ this._cookieStartedup = true;
+ },
+ addCookieHandler: function(args){
+ // summary:
+ // If a grid plugin wants cookie service, call this.
+ // This must be called during preInit.
+ // args: Object
+ // An object with the following structure:
+ // | {
+ // | name: "some-string",
+ // | onLoad: /* void */ function(/* object */partOfCookie, /* EDG */grid){...},
+ // | onSave: /* object */ function(/* EDG */grid){...}
+ // | }
+ if(args.name){
+ var dummy = function(){};
+ args.onLoad = args.onLoad || dummy;
+ args.onSave = args.onSave || dummy;
+ if(!("enabled" in args)){
+ args.enabled = true;
+ }
+ for(var i = this._cookieHandlers.length - 1; i >= 0; --i){
+ if(this._cookieHandlers[i].name == args.name){
+ this._cookieHandlers.splice(i, 1);
+ }
+ }
+ this._cookieHandlers.push(args);
+ if(this._cookieStartedup && args.name in this._cookie){
+ args.onLoad(this._cookie[args.name], this.grid);
+ }
+ }
+ },
+ removeCookie: function(){
+ // summary:
+ // Remove cookie for this grid.
+ var key = _cookieKeyBuilder(this.grid);
+ cookie(key, null, {expires: -1});
+ },
+ setCookieEnabled: function(cookieName, enabled){
+ // summary:
+ // A setter to enable|disable cookie support for a particular Grid feature.
+ // cookieName: String?
+ // Name of a cookie handler if provided, otherwise for all cookies.
+ // enabled: Boolean
+ if(typeof cookieName == 'string'){
+ var chs = this._cookieHandlers;
+ for(var i = chs.length - 1; i >= 0; --i){
+ if(chs[i].name === cookieName){
+ chs[i].enabled = !!enabled;
+ }
+ }
+ }else{
+ this._cookieEnabled = !!cookieName;
+ if(!this._cookieEnabled){ this.removeCookie(); }
+ }
+ },
+ getCookieEnabled: function(cookieName){
+ // summary:
+ // A getter to check cookie support of a particular Grid feature.
+ // cookieName: String?
+ // Name of a cookie handler if provided, otherwise for all cookies.
+ if(lang.isString(cookieName)){
+ var chs = this._cookieHandlers;
+ for(var i = chs.length - 1; i >= 0; --i){
+ if(chs[i].name == cookieName){ return chs[i].enabled; }
+ }
+ return false;
+ }
+ return this._cookieEnabled;
+ }
+ });
+
+ EnhancedGrid.registerPlugin(Cookie, {"preInit": true});
+
+ return Cookie;
+});
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Dialog.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Dialog.js
new file mode 100644
index 0000000..97dbbd4
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Dialog.js
@@ -0,0 +1,40 @@
+//>>built
+define("dojox/grid/enhanced/plugins/Dialog", [
+ "dojo/_base/declare",
+ "dojo/_base/html",
+ "dojo/window",
+ "dijit/Dialog"
+], function(declare, html, win, Dialog){
+
+return declare("dojox.grid.enhanced.plugins.Dialog", Dialog, {
+ refNode: null,
+ _position: function(){
+ if(this.refNode && !this._relativePosition){
+ var refPos = html.position(html.byId(this.refNode)),
+ thisPos = html.position(this.domNode),
+ viewPort = win.getBox();
+ if(thisPos.w && thisPos.h){
+ if(refPos.x < 0){
+ refPos.x = 0;
+ }
+ if(refPos.x + refPos.w > viewPort.w){
+ refPos.w = viewPort.w - refPos.x;
+ }
+ if(refPos.y < 0){
+ refPos.y = 0;
+ }
+ if(refPos.y + refPos.h > viewPort.h){
+ refPos.h = viewPort.h - refPos.y;
+ }
+ refPos.x = refPos.x + refPos.w / 2 - thisPos.w / 2;
+ refPos.y = refPos.y + refPos.h / 2 - thisPos.h / 2;
+ if(refPos.x >= 0 && refPos.x + thisPos.w <= viewPort.w &&
+ refPos.y >= 0 && refPos.y + thisPos.h <= viewPort.h){
+ this._relativePosition = refPos;
+ }
+ }
+ }
+ this.inherited(arguments);
+ }
+});
+});
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/DnD.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/DnD.js
new file mode 100644
index 0000000..e9306ed
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/DnD.js
@@ -0,0 +1,1094 @@
+//>>built
+define("dojox/grid/enhanced/plugins/DnD", [
+ "dojo/_base/kernel",
+ "dojo/_base/declare",
+ "dojo/_base/connect",
+ "dojo/_base/array",
+ "dojo/_base/lang",
+ "dojo/_base/html",
+ "dojo/_base/json",
+ "dojo/_base/window",
+ "dojo/query",
+ "dojo/keys",
+ "dojo/dnd/Source",
+ "dojo/dnd/Avatar",
+ "../_Plugin",
+ "../../EnhancedGrid",
+ "./Selector",
+ "./Rearrange",
+ "dojo/dnd/Manager"
+], function(dojo, declare, connect, array, lang, html, json, win, query, keys, Source, Avatar, _Plugin, EnhancedGrid){
+
+var _devideToArrays = function(a){
+ a.sort(function(v1, v2){
+ return v1 - v2;
+ });
+ var arr = [[a[0]]];
+ for(var i = 1, j = 0; i < a.length; ++i){
+ if(a[i] == a[i-1] + 1){
+ arr[j].push(a[i]);
+ }else{
+ arr[++j] = [a[i]];
+ }
+ }
+ return arr;
+ },
+ _joinToArray = function(arrays){
+ var a = arrays[0];
+ for(var i = 1; i < arrays.length; ++i){
+ a = a.concat(arrays[i]);
+ }
+ return a;
+ };
+var GridDnDElement = declare("dojox.grid.enhanced.plugins.GridDnDElement", null, {
+ constructor: function(dndPlugin){
+ this.plugin = dndPlugin;
+ this.node = html.create("div");
+ this._items = {};
+ },
+ destroy: function(){
+ this.plugin = null;
+ html.destroy(this.node);
+ this.node = null;
+ this._items = null;
+ },
+ createDnDNodes: function(dndRegion){
+ this.destroyDnDNodes();
+ var acceptType = ["grid/" + dndRegion.type + "s"];
+ var itemNodeIdBase = this.plugin.grid.id + "_dndItem";
+ array.forEach(dndRegion.selected, function(range, i){
+ var id = itemNodeIdBase + i;
+ this._items[id] = {
+ "type": acceptType,
+ "data": range,
+ "dndPlugin": this.plugin
+ };
+ this.node.appendChild(html.create("div", {
+ "id": id
+ }));
+ }, this);
+ },
+ getDnDNodes: function(){
+ return array.map(this.node.childNodes, function(node){
+ return node;
+ });
+ },
+ destroyDnDNodes: function(){
+ html.empty(this.node);
+ this._items = {};
+ },
+ getItem: function(nodeId){
+ return this._items[nodeId];
+ }
+});
+var GridDnDSource = declare("dojox.grid.enhanced.plugins.GridDnDSource", Source,{
+ accept: ["grid/cells", "grid/rows", "grid/cols"],
+ constructor: function(node, param){
+ this.grid = param.grid;
+ this.dndElem = param.dndElem;
+ this.dndPlugin = param.dnd;
+ this.sourcePlugin = null;
+ },
+ destroy: function(){
+ this.inherited(arguments);
+ this.grid = null;
+ this.dndElem = null;
+ this.dndPlugin = null;
+ this.sourcePlugin = null;
+ },
+ getItem: function(nodeId){
+ return this.dndElem.getItem(nodeId);
+ },
+ checkAcceptance: function(source, nodes){
+ if(this != source && nodes[0]){
+ var item = source.getItem(nodes[0].id);
+ if(item.dndPlugin){
+ var type = item.type;
+ for(var j = 0; j < type.length; ++j){
+ if(type[j] in this.accept){
+ if(this.dndPlugin._canAccept(item.dndPlugin)){
+ this.sourcePlugin = item.dndPlugin;
+ }else{
+ return false;
+ }
+ break;
+ }
+ }
+ }else if("grid/rows" in this.accept){
+ var rows = [];
+ array.forEach(nodes, function(node){
+ var item = source.getItem(node.id);
+ if(item.data && array.indexOf(item.type, "grid/rows") >= 0){
+ var rowData = item.data;
+ if(typeof item.data == "string"){
+ rowData = json.fromJson(item.data);
+ }
+ if(rowData){
+ rows.push(rowData);
+ }
+ }
+ });
+ if(rows.length){
+ this.sourcePlugin = {
+ _dndRegion: {
+ type: "row",
+ selected: [rows]
+ }
+ };
+ }else{
+ return false;
+ }
+ }
+ }
+ return this.inherited(arguments);
+ },
+ onDraggingOver: function(){
+ this.dndPlugin.onDraggingOver(this.sourcePlugin);
+ },
+ onDraggingOut: function(){
+ this.dndPlugin.onDraggingOut(this.sourcePlugin);
+ },
+ onDndDrop: function(source, nodes, copy, target){
+ //this.inherited(arguments);
+ this.onDndCancel();
+ if(this != source && this == target){
+ this.dndPlugin.onDragIn(this.sourcePlugin, copy);
+ }
+ }
+});
+
+var GridDnDAvatar = declare("dojox.grid.enhanced.plugins.GridDnDAvatar", Avatar, {
+ construct: function(){
+ // summary:
+ // constructor function;
+ // it is separate so it can be (dynamically) overwritten in case of need
+ this._itemType = this.manager._dndPlugin._dndRegion.type;
+ this._itemCount = this._getItemCount();
+
+ this.isA11y = html.hasClass(win.body(), "dijit_a11y");
+ var a = html.create("table", {
+ "border": "0",
+ "cellspacing": "0",
+ "class": "dojoxGridDndAvatar",
+ "style": {
+ position: "absolute",
+ zIndex: "1999",
+ margin: "0px"
+ }
+ }),
+ source = this.manager.source,
+ b = html.create("tbody", null, a),
+ tr = html.create("tr", null, b),
+ td = html.create("td", {
+ "class": "dojoxGridDnDIcon"
+ }, tr);
+ if(this.isA11y){
+ html.create("span", {
+ "id" : "a11yIcon",
+ "innerHTML" : this.manager.copy ? '+' : "<"
+ }, td);
+ }
+ td = html.create("td", {
+ "class" : "dojoxGridDnDItemIcon " + this._getGridDnDIconClass()
+ }, tr);
+ td = html.create("td", null, tr);
+ html.create("span", {
+ "class": "dojoxGridDnDItemCount",
+ "innerHTML": source.generateText ? this._generateText() : ""
+ }, td);
+ // we have to set the opacity on IE only after the node is live
+ html.style(tr, {
+ "opacity": 0.9
+ });
+ this.node = a;
+ },
+ _getItemCount: function(){
+ var selected = this.manager._dndPlugin._dndRegion.selected,
+ count = 0;
+ switch(this._itemType){
+ case "cell":
+ selected = selected[0];
+ var cells = this.manager._dndPlugin.grid.layout.cells,
+ colCount = selected.max.col - selected.min.col + 1,
+ rowCount = selected.max.row - selected.min.row + 1;
+ if(colCount > 1){
+ for(var i = selected.min.col; i <= selected.max.col; ++i){
+ if(cells[i].hidden){
+ --colCount;
+ }
+ }
+ }
+ count = colCount * rowCount;
+ break;
+ case "row":
+ case "col":
+ count = _joinToArray(selected).length;
+ }
+ return count;
+ },
+ _getGridDnDIconClass: function(){
+ return {
+ "row": ["dojoxGridDnDIconRowSingle", "dojoxGridDnDIconRowMulti"],
+ "col": ["dojoxGridDnDIconColSingle", "dojoxGridDnDIconColMulti"],
+ "cell": ["dojoxGridDnDIconCellSingle", "dojoxGridDnDIconCellMulti"]
+ }[this._itemType][this._itemCount == 1 ? 0 : 1];
+ },
+ _generateText: function(){
+ // summary:
+ // generates a proper text to reflect copying or moving of items
+ return "(" + this._itemCount + ")";
+ }
+});
+var DnD = declare("dojox.grid.enhanced.plugins.DnD", _Plugin, {
+ // summary:
+ // Provide drag and drop for grid columns/rows/cells within grid and out of grid.
+ // The store of grid must implement dojo.data.api.Write.
+ // DnD selected columns:
+ // Support moving within grid, moving/copying out of grid to a non-grid DnD target.
+ // DnD selected rows:
+ // Support moving within grid, moving/copying out of grid to any DnD target.
+ // DnD selected cells (in rectangle shape only):
+ // Support moving/copying within grid, moving/copying out of grid to any DnD target.
+ //
+
+ // name: String,
+ // plugin name;
+ name: "dnd",
+
+ _targetAnchorBorderWidth: 2,
+ _copyOnly: false,
+ _config: {
+ "row":{
+ "within":true,
+ "in":true,
+ "out":true
+ },
+ "col":{
+ "within":true,
+ "in":true,
+ "out":true
+ },
+ "cell":{
+ "within":true,
+ "in":true,
+ "out":true
+ }
+ },
+ constructor: function(grid, args){
+ this.grid = grid;
+ this._config = lang.clone(this._config);
+ args = lang.isObject(args) ? args : {};
+ this.setupConfig(args.dndConfig);
+ this._copyOnly = !!args.copyOnly;
+
+ //Get the plugins we are dependent on.
+ this._mixinGrid();
+ this.selector = grid.pluginMgr.getPlugin("selector");
+ this.rearranger = grid.pluginMgr.getPlugin("rearrange");
+ //TODO: waiting for a better plugin framework to pass args to dependent plugins.
+ this.rearranger.setArgs(args);
+
+ //Initialized the components we need.
+ this._clear();
+ this._elem = new GridDnDElement(this);
+ this._source = new GridDnDSource(this._elem.node, {
+ "grid": grid,
+ "dndElem": this._elem,
+ "dnd": this
+ });
+ this._container = query(".dojoxGridMasterView", this.grid.domNode)[0];
+ this._initEvents();
+ },
+ destroy: function(){
+ this.inherited(arguments);
+ this._clear();
+ this._source.destroy();
+ this._elem.destroy();
+ this._container = null;
+ this.grid = null;
+ this.selector = null;
+ this.rearranger = null;
+ this._config = null;
+ },
+ _mixinGrid: function(){
+ // summary:
+ // Provide APIs for grid.
+ this.grid.setupDnDConfig = lang.hitch(this, "setupConfig");
+ this.grid.dndCopyOnly = lang.hitch(this, "copyOnly");
+ },
+ setupConfig: function(config){
+ // summary:
+ // Configure which DnD functionalities are needed.
+ // Combination of any item from type set ("row", "col", "cell")
+ // and any item from mode set("within", "in", "out") is configurable.
+ //
+ // "row", "col", "cell" are straitforward, while the other 3 are explained below:
+ // "within": DnD within grid, that is, column/row reordering and cell moving/copying.
+ // "in": Whether allowed to accept rows/cells (currently not support columns) from another grid.
+ // "out": Whether allowed to drag out of grid, to another grid or even to any other DnD target.
+ //
+ // If not provided in the config, will use the default.
+ // When declared together, Mode set has higher priority than type set.
+ // config: Object
+ // DnD configuration object.
+ // See the examples below.
+ // example:
+ // The following code disables row DnD within grid,
+ // but still can drag rows out of grid or drag rows from other gird.
+ // | setUpConfig({
+ // | "row": {
+ // | "within": false
+ // | }
+ // | });
+ //
+ // The opposite way is also okay:
+ // | setUpConfig({
+ // | "within": {
+ // | "row": false
+ // | }
+ // | });
+ //
+ // And if you'd like to disable/enable a whole set, here's a shortcut:
+ // | setUpConfig({
+ // | "cell", true,
+ // | "out": false
+ // | });
+ //
+ // Because mode has higher priority than type, the following will disable row dnd within grid:
+ // | setUpConfig({
+ // | "within", {
+ // | "row": false;
+ // | },
+ // | "row", {
+ // | "within": true
+ // | }
+ // | });
+ if(config && lang.isObject(config)){
+ var firstLevel = ["row", "col", "cell"],
+ secondLevel = ["within", "in", "out"],
+ cfg = this._config;
+ array.forEach(firstLevel, function(type){
+ if(type in config){
+ var t = config[type];
+ if(t && lang.isObject(t)){
+ array.forEach(secondLevel, function(mode){
+ if(mode in t){
+ cfg[type][mode] = !!t[mode];
+ }
+ });
+ }else{
+ array.forEach(secondLevel, function(mode){
+ cfg[type][mode] = !!t;
+ });
+ }
+ }
+ });
+ array.forEach(secondLevel, function(mode){
+ if(mode in config){
+ var m = config[mode];
+ if(m && lang.isObject(m)){
+ array.forEach(firstLevel, function(type){
+ if(type in m){
+ cfg[type][mode] = !!m[type];
+ }
+ });
+ }else{
+ array.forEach(firstLevel, function(type){
+ cfg[type][mode] = !!m;
+ });
+ }
+ }
+ });
+ }
+ },
+ copyOnly: function(isCopyOnly){
+ // summary:
+ // Setter/getter of this._copyOnly.
+ if(typeof isCopyOnly != "undefined"){
+ this._copyOnly = !!isCopyOnly;
+ }
+ return this._copyOnly;
+ },
+ _isOutOfGrid: function(evt){
+ var gridPos = html.position(this.grid.domNode), x = evt.clientX, y = evt.clientY;
+ return y < gridPos.y || y > gridPos.y + gridPos.h ||
+ x < gridPos.x || x > gridPos.x + gridPos.w;
+ },
+ _onMouseMove: function(evt){
+ if(this._dndRegion && !this._dnding && !this._externalDnd){
+ this._dnding = true;
+ this._startDnd(evt);
+ }else{
+ if(this._isMouseDown && !this._dndRegion){
+ delete this._isMouseDown;
+ this._oldCursor = html.style(win.body(), "cursor");
+ html.style(win.body(), "cursor", "not-allowed");
+ }
+ //TODO: should implement as mouseenter/mouseleave
+ //But we have an avatar under mouse when dnd, and this will cause a lot of mouseenter in FF.
+ var isOut = this._isOutOfGrid(evt);
+ if(!this._alreadyOut && isOut){
+ this._alreadyOut = true;
+ if(this._dnding){
+ this._destroyDnDUI(true, false);
+ }
+ this._moveEvent = evt;
+ this._source.onOutEvent();
+ }else if(this._alreadyOut && !isOut){
+ this._alreadyOut = false;
+ if(this._dnding){
+ this._createDnDUI(evt, true);
+ }
+ this._moveEvent = evt;
+ this._source.onOverEvent();
+ }
+ }
+ },
+ _onMouseUp: function(){
+ if(!this._extDnding && !this._isSource){
+ var isInner = this._dnding && !this._alreadyOut;
+ if(isInner && this._config[this._dndRegion.type]["within"]){
+ this._rearrange();
+ }
+ this._endDnd(isInner);
+ }
+ html.style(win.body(), "cursor", this._oldCursor || "");
+ delete this._isMouseDown;
+ },
+ _initEvents: function(){
+ var g = this.grid, s = this.selector;
+ this.connect(win.doc, "onmousemove", "_onMouseMove");
+ this.connect(win.doc, "onmouseup", "_onMouseUp");
+
+ this.connect(g, "onCellMouseOver", function(evt){
+ if(!this._dnding && !s.isSelecting() && !evt.ctrlKey){
+ this._dndReady = s.isSelected("cell", evt.rowIndex, evt.cell.index);
+ s.selectEnabled(!this._dndReady);
+ }
+ });
+ this.connect(g, "onHeaderCellMouseOver", function(evt){
+ if(this._dndReady){
+ s.selectEnabled(true);
+ }
+ });
+ this.connect(g, "onRowMouseOver", function(evt){
+ if(this._dndReady && !evt.cell){
+ s.selectEnabled(true);
+ }
+ });
+ this.connect(g, "onCellMouseDown", function(evt){
+ if(!evt.ctrlKey && this._dndReady){
+ this._dndRegion = this._getDnDRegion(evt.rowIndex, evt.cell.index);
+ this._isMouseDown = true;
+ }
+ });
+ this.connect(g, "onCellMouseUp", function(evt){
+ if(!this._dndReady && !s.isSelecting() && evt.cell){
+ this._dndReady = s.isSelected("cell", evt.rowIndex, evt.cell.index);
+ s.selectEnabled(!this._dndReady);
+ }
+ });
+ this.connect(g, "onCellClick", function(evt){
+ if(this._dndReady && !evt.ctrlKey && !evt.shiftKey){
+ s.select("cell", evt.rowIndex, evt.cell.index);
+ }
+ });
+ this.connect(g, "onEndAutoScroll", function(isVertical, isForward, view, target, evt){
+ if(this._dnding){
+ this._markTargetAnchor(evt);
+ }
+ });
+ this.connect(win.doc, "onkeydown", function(evt){
+ if(evt.keyCode == keys.ESCAPE){
+ this._endDnd(false);
+ }else if(evt.keyCode == keys.CTRL){
+ s.selectEnabled(true);
+ this._isCopy = true;
+ }
+ });
+ this.connect(win.doc, "onkeyup", function(evt){
+ if(evt.keyCode == keys.CTRL){
+ s.selectEnabled(!this._dndReady);
+ this._isCopy = false;
+ }
+ });
+ },
+ _clear: function(){
+ this._dndRegion = null;
+ this._target = null;
+ this._moveEvent = null;
+ this._targetAnchor = {};
+ this._dnding = false;
+ this._externalDnd = false;
+ this._isSource = false;
+ this._alreadyOut = false;
+ this._extDnding = false;
+ },
+ _getDnDRegion: function(rowIndex, colIndex){
+ var s = this.selector,
+ selected = s._selected,
+ flag = (!!selected.cell.length) | (!!selected.row.length << 1) | (!!selected.col.length << 2),
+ type;
+ switch(flag){
+ case 1:
+ type = "cell";
+ if(!this._config[type]["within"] && !this._config[type]["out"]){
+ return null;
+ }
+ var cells = this.grid.layout.cells,
+ getCount = function(range){
+ var hiddenColCnt = 0;
+ for(var i = range.min.col; i <= range.max.col; ++i){
+ if(cells[i].hidden){
+ ++hiddenColCnt;
+ }
+ }
+ return (range.max.row - range.min.row + 1) * (range.max.col - range.min.col + 1 - hiddenColCnt);
+ },
+ inRange = function(item, range){
+ return item.row >= range.min.row && item.row <= range.max.row &&
+ item.col >= range.min.col && item.col <= range.max.col;
+ },
+ range = {
+ max: {
+ row: -1,
+ col: -1
+ },
+ min: {
+ row: Infinity,
+ col: Infinity
+ }
+ };
+
+ array.forEach(selected[type], function(item){
+ if(item.row < range.min.row){
+ range.min.row = item.row;
+ }
+ if(item.row > range.max.row){
+ range.max.row = item.row;
+ }
+ if(item.col < range.min.col){
+ range.min.col = item.col;
+ }
+ if(item.col > range.max.col){
+ range.max.col = item.col;
+ }
+ });
+ if(array.some(selected[type], function(item){
+ return item.row == rowIndex && item.col == colIndex;
+ })){
+ if(getCount(range) == selected[type].length && array.every(selected[type], function(item){
+ return inRange(item, range);
+ })){
+ return {
+ "type": type,
+ "selected": [range],
+ "handle": {
+ "row": rowIndex,
+ "col": colIndex
+ }
+ };
+ }
+ }
+ return null;
+ case 2: case 4:
+ type = flag == 2 ? "row" : "col";
+ if(!this._config[type]["within"] && !this._config[type]["out"]){
+ return null;
+ }
+ var res = s.getSelected(type);
+ if(res.length){
+ return {
+ "type": type,
+ "selected": _devideToArrays(res),
+ "handle": flag == 2 ? rowIndex : colIndex
+ };
+ }
+ return null;
+ }
+ return null;
+ },
+ _startDnd: function(evt){
+ this._createDnDUI(evt);
+ },
+ _endDnd: function(destroySource){
+ this._destroyDnDUI(false, destroySource);
+ this._clear();
+ },
+ _createDnDUI: function(evt, isMovingIn){
+ //By default the master view of grid do not have height, because the children in it are all positioned absolutely.
+ //But we need it to contain avatars.
+ var viewPos = html.position(this.grid.views.views[0].domNode);
+ html.style(this._container, "height", viewPos.h + "px");
+ try{
+ //If moving in from out side, dnd source is already created.
+ if(!isMovingIn){
+ this._createSource(evt);
+ }
+ this._createMoveable(evt);
+ this._oldCursor = html.style(win.body(), "cursor");
+ html.style(win.body(), "cursor", "default");
+ }catch(e){
+ console.warn("DnD._createDnDUI() error:", e);
+ }
+ },
+ _destroyDnDUI: function(isMovingOut, destroySource){
+ try{
+ if(destroySource){
+ this._destroySource();
+ }
+ this._unmarkTargetAnchor();
+ if(!isMovingOut){
+ this._destroyMoveable();
+ }
+ html.style(win.body(), "cursor", this._oldCursor);
+ }catch(e){
+ console.warn("DnD._destroyDnDUI() error:", this.grid.id, e);
+ }
+ },
+ _createSource: function(evt){
+ this._elem.createDnDNodes(this._dndRegion);
+ var m = dojo.dnd.manager();
+ var oldMakeAvatar = m.makeAvatar;
+ m._dndPlugin = this;
+ m.makeAvatar = function(){
+ var avatar = new GridDnDAvatar(m);
+ delete m._dndPlugin;
+ return avatar;
+ };
+ m.startDrag(this._source, this._elem.getDnDNodes(), evt.ctrlKey);
+ m.makeAvatar = oldMakeAvatar;
+ m.onMouseMove(evt);
+ },
+ _destroySource: function(){
+ connect.publish("/dnd/cancel");
+ },
+ _createMoveable: function(evt){
+ if(!this._markTagetAnchorHandler){
+ this._markTagetAnchorHandler = this.connect(win.doc, "onmousemove", "_markTargetAnchor");
+ }
+ },
+ _destroyMoveable: function(){
+ this.disconnect(this._markTagetAnchorHandler);
+ delete this._markTagetAnchorHandler;
+ },
+ _calcColTargetAnchorPos: function(evt, containerPos){
+ // summary:
+ // Calculate the position of the column DnD avatar
+ var i, headPos, left, target, ex = evt.clientX,
+ cells = this.grid.layout.cells,
+ ltr = html._isBodyLtr(),
+ headers = this._getVisibleHeaders();
+ for(i = 0; i < headers.length; ++i){
+ headPos = html.position(headers[i].node);
+ if(ltr ? ((i === 0 || ex >= headPos.x) && ex < headPos.x + headPos.w) :
+ ((i === 0 || ex < headPos.x + headPos.w) && ex >= headPos.x)){
+ left = headPos.x + (ltr ? 0 : headPos.w);
+ break;
+ }else if(ltr ? (i === headers.length - 1 && ex >= headPos.x + headPos.w) :
+ (i === headers.length - 1 && ex < headPos.x)){
+ ++i;
+ left = headPos.x + (ltr ? headPos.w : 0);
+ break;
+ }
+ }
+ if(i < headers.length){
+ target = headers[i].cell.index;
+ if(this.selector.isSelected("col", target) && this.selector.isSelected("col", target - 1)){
+ var ranges = this._dndRegion.selected;
+ for(i = 0; i < ranges.length; ++i){
+ if(array.indexOf(ranges[i], target) >= 0){
+ target = ranges[i][0];
+ headPos = html.position(cells[target].getHeaderNode());
+ left = headPos.x + (ltr ? 0 : headPos.w);
+ break;
+ }
+ }
+ }
+ }else{
+ target = cells.length;
+ }
+ this._target = target;
+ return left - containerPos.x;
+ },
+ _calcRowTargetAnchorPos: function(evt, containerPos){
+ // summary:
+ // Calculate the position of the row DnD avatar
+ var g = this.grid, top, i = 0,
+ cells = g.layout.cells;
+ while(cells[i].hidden){ ++i; }
+ var cell = g.layout.cells[i],
+ rowIndex = g.scroller.firstVisibleRow,
+ cellNode = cell.getNode(rowIndex);
+ if(!cellNode){
+ //if the target grid is empty, set to -1
+ //which will be processed in Rearrange
+ this._target = -1;
+ return 0; //position of the insert bar
+ }
+ var nodePos = html.position(cellNode);
+ while(nodePos.y + nodePos.h < evt.clientY){
+ if(++rowIndex >= g.rowCount){
+ break;
+ }
+ nodePos = html.position(cell.getNode(rowIndex));
+ }
+ if(rowIndex < g.rowCount){
+ if(this.selector.isSelected("row", rowIndex) && this.selector.isSelected("row", rowIndex - 1)){
+ var ranges = this._dndRegion.selected;
+ for(i = 0; i < ranges.length; ++i){
+ if(array.indexOf(ranges[i], rowIndex) >= 0){
+ rowIndex = ranges[i][0];
+ nodePos = html.position(cell.getNode(rowIndex));
+ break;
+ }
+ }
+ }
+ top = nodePos.y;
+ }else{
+ top = nodePos.y + nodePos.h;
+ }
+ this._target = rowIndex;
+ return top - containerPos.y;
+ },
+ _calcCellTargetAnchorPos: function(evt, containerPos, targetAnchor){
+ // summary:
+ // Calculate the position of the cell DnD avatar
+ var s = this._dndRegion.selected[0],
+ origin = this._dndRegion.handle,
+ g = this.grid, ltr = html._isBodyLtr(),
+ cells = g.layout.cells, headPos,
+ minPos, maxPos, headers,
+ height, width, left, top,
+ minCol, maxCol, i,
+ preSpan = origin.col - s.min.col,
+ postSpan = s.max.col - origin.col,
+ leftTopDiv, rightBottomDiv;
+ if(!targetAnchor.childNodes.length){
+ leftTopDiv = html.create("div", {
+ "class": "dojoxGridCellBorderLeftTopDIV"
+ }, targetAnchor);
+ rightBottomDiv = html.create("div", {
+ "class": "dojoxGridCellBorderRightBottomDIV"
+ }, targetAnchor);
+ }else{
+ leftTopDiv = query(".dojoxGridCellBorderLeftTopDIV", targetAnchor)[0];
+ rightBottomDiv = query(".dojoxGridCellBorderRightBottomDIV", targetAnchor)[0];
+ }
+ for(i = s.min.col + 1; i < origin.col; ++i){
+ if(cells[i].hidden){
+ --preSpan;
+ }
+ }
+ for(i = origin.col + 1; i < s.max.col; ++i){
+ if(cells[i].hidden){
+ --postSpan;
+ }
+ }
+ headers = this._getVisibleHeaders();
+ //calc width
+ for(i = preSpan; i < headers.length - postSpan; ++i){
+ headPos = html.position(headers[i].node);
+ if((evt.clientX >= headPos.x && evt.clientX < headPos.x + headPos.w) || //within in this column
+ //prior to this column, but within range
+ (i == preSpan && (ltr ? evt.clientX < headPos.x : evt.clientX >= headPos.x + headPos.w)) ||
+ //post to this column, but within range
+ (i == headers.length - postSpan - 1 && (ltr ? evt.clientX >= headPos.x + headPos.w : evt < headPos.x))){
+ minCol = headers[i - preSpan];
+ maxCol = headers[i + postSpan];
+ minPos = html.position(minCol.node);
+ maxPos = html.position(maxCol.node);
+ minCol = minCol.cell.index;
+ maxCol = maxCol.cell.index;
+ left = ltr ? minPos.x : maxPos.x;
+ width = ltr ? (maxPos.x + maxPos.w - minPos.x) : (minPos.x + minPos.w - maxPos.x);
+ break;
+ }
+ }
+ //calc height
+ i = 0;
+ while(cells[i].hidden){ ++i; }
+ var cell = cells[i],
+ rowIndex = g.scroller.firstVisibleRow,
+ nodePos = html.position(cell.getNode(rowIndex));
+ while(nodePos.y + nodePos.h < evt.clientY){
+ if(++rowIndex < g.rowCount){
+ nodePos = html.position(cell.getNode(rowIndex));
+ }else{
+ break;
+ }
+ }
+ var minRow = rowIndex >= origin.row - s.min.row ? rowIndex - origin.row + s.min.row : 0;
+ var maxRow = minRow + s.max.row - s.min.row;
+ if(maxRow >= g.rowCount){
+ maxRow = g.rowCount - 1;
+ minRow = maxRow - s.max.row + s.min.row;
+ }
+ minPos = html.position(cell.getNode(minRow));
+ maxPos = html.position(cell.getNode(maxRow));
+ top = minPos.y;
+ height = maxPos.y + maxPos.h - minPos.y;
+ this._target = {
+ "min":{
+ "row": minRow,
+ "col": minCol
+ },
+ "max":{
+ "row": maxRow,
+ "col": maxCol
+ }
+ };
+ var anchorBorderSize = (html.marginBox(leftTopDiv).w - html.contentBox(leftTopDiv).w) / 2;
+ var leftTopCellPos = html.position(cells[minCol].getNode(minRow));
+ html.style(leftTopDiv, {
+ "width": (leftTopCellPos.w - anchorBorderSize) + "px",
+ "height": (leftTopCellPos.h - anchorBorderSize) + "px"
+ });
+ var rightBottomCellPos = html.position(cells[maxCol].getNode(maxRow));
+ html.style(rightBottomDiv, {
+ "width": (rightBottomCellPos.w - anchorBorderSize) + "px",
+ "height": (rightBottomCellPos.h - anchorBorderSize) + "px"
+ });
+ return {
+ h: height,
+ w: width,
+ l: left - containerPos.x,
+ t: top - containerPos.y
+ };
+ },
+ _markTargetAnchor: function(evt){
+ try{
+ var t = this._dndRegion.type;
+ if(this._alreadyOut || (this._dnding && !this._config[t]["within"]) || (this._extDnding && !this._config[t]["in"])){
+ return;
+ }
+ var height, width, left, top,
+ targetAnchor = this._targetAnchor[t],
+ pos = html.position(this._container);
+ if(!targetAnchor){
+ targetAnchor = this._targetAnchor[t] = html.create("div", {
+ "class": (t == "cell") ? "dojoxGridCellBorderDIV" : "dojoxGridBorderDIV"
+ });
+ html.style(targetAnchor, "display", "none");
+ this._container.appendChild(targetAnchor);
+ }
+ switch(t){
+ case "col":
+ height = pos.h;
+ width = this._targetAnchorBorderWidth;
+ left = this._calcColTargetAnchorPos(evt, pos);
+ top = 0;
+ break;
+ case "row":
+ height = this._targetAnchorBorderWidth;
+ width = pos.w;
+ left = 0;
+ top = this._calcRowTargetAnchorPos(evt, pos);
+ break;
+ case "cell":
+ var cellPos = this._calcCellTargetAnchorPos(evt, pos, targetAnchor);
+ height = cellPos.h;
+ width = cellPos.w;
+ left = cellPos.l;
+ top = cellPos.t;
+ }
+ if(typeof height == "number" && typeof width == "number" && typeof left == "number" && typeof top == "number"){
+ html.style(targetAnchor, {
+ "height": height + "px",
+ "width": width + "px",
+ "left": left + "px",
+ "top": top + "px"
+ });
+ html.style(targetAnchor, "display", "");
+ }else{
+ this._target = null;
+ }
+ }catch(e){
+ console.warn("DnD._markTargetAnchor() error:",e);
+ }
+ },
+ _unmarkTargetAnchor: function(){
+ if(this._dndRegion){
+ var targetAnchor = this._targetAnchor[this._dndRegion.type];
+ if(targetAnchor){
+ html.style(this._targetAnchor[this._dndRegion.type], "display", "none");
+ }
+ }
+ },
+ _getVisibleHeaders: function(){
+ return array.map(array.filter(this.grid.layout.cells, function(cell){
+ return !cell.hidden;
+ }), function(cell){
+ return {
+ "node": cell.getHeaderNode(),
+ "cell": cell
+ };
+ });
+ },
+ _rearrange: function(){
+ if(this._target === null){
+ return;
+ }
+ var t = this._dndRegion.type;
+ var ranges = this._dndRegion.selected;
+ if(t === "cell"){
+ this.rearranger[(this._isCopy || this._copyOnly) ? "copyCells" : "moveCells"](ranges[0], this._target === -1 ? null : this._target);
+ }else{
+ this.rearranger[t == "col" ? "moveColumns" : "moveRows"](_joinToArray(ranges), this._target === -1 ? null: this._target);
+ }
+ this._target = null;
+ },
+ onDraggingOver: function(sourcePlugin){
+ if(!this._dnding && sourcePlugin){
+ sourcePlugin._isSource = true;
+ this._extDnding = true;
+ if(!this._externalDnd){
+ this._externalDnd = true;
+ this._dndRegion = this._mapRegion(sourcePlugin.grid, sourcePlugin._dndRegion);
+ }
+ this._createDnDUI(this._moveEvent,true);
+ this.grid.pluginMgr.getPlugin("autoScroll").readyForAutoScroll = true;
+ }
+ },
+ _mapRegion: function(srcGrid, dndRegion){
+ if(dndRegion.type === "cell"){
+ var srcRange = dndRegion.selected[0];
+ var cells = this.grid.layout.cells;
+ var srcCells = srcGrid.layout.cells;
+ var c, cnt = 0;
+ for(c = srcRange.min.col; c <= srcRange.max.col; ++c){
+ if(!srcCells[c].hidden){
+ ++cnt;
+ }
+ }
+ for(c = 0; cnt > 0; ++c){
+ if(!cells[c].hidden){
+ --cnt;
+ }
+ }
+ var region = lang.clone(dndRegion);
+ region.selected[0].min.col = 0;
+ region.selected[0].max.col = c - 1;
+ for(c = srcRange.min.col; c <= dndRegion.handle.col; ++c){
+ if(!srcCells[c].hidden){
+ ++cnt;
+ }
+ }
+ for(c = 0; cnt > 0; ++c){
+ if(!cells[c].hidden){
+ --cnt;
+ }
+ }
+ region.handle.col = c;
+ }
+ return dndRegion;
+ },
+ onDraggingOut: function(sourcePlugin){
+ if(this._externalDnd){
+ this._extDnding = false;
+ this._destroyDnDUI(true, false);
+ if(sourcePlugin){
+ sourcePlugin._isSource = false;
+ }
+ }
+ },
+ onDragIn: function(sourcePlugin, isCopy){
+ var success = false;
+ if(this._target !== null){
+ var type = sourcePlugin._dndRegion.type;
+ var ranges = sourcePlugin._dndRegion.selected;
+ switch(type){
+ case "cell":
+ this.rearranger.changeCells(sourcePlugin.grid, ranges[0], this._target);
+ break;
+ case "row":
+ var range = _joinToArray(ranges);
+ this.rearranger.insertRows(sourcePlugin.grid, range, this._target);
+ break;
+ }
+ success = true;
+ }
+ this._endDnd(true);
+ if(sourcePlugin.onDragOut){
+ sourcePlugin.onDragOut(success && !isCopy);
+ }
+ },
+ onDragOut: function(isMove){
+ if(isMove && !this._copyOnly){
+ var type = this._dndRegion.type;
+ var ranges = this._dndRegion.selected;
+ switch(type){
+ case "cell":
+ this.rearranger.clearCells(ranges[0]);
+ break;
+ case "row":
+ this.rearranger.removeRows(_joinToArray(ranges));
+ break;
+ }
+ }
+ this._endDnd(true);
+ },
+ _canAccept: function(sourcePlugin){
+ if(!sourcePlugin){
+ return false;
+ }
+ var srcRegion = sourcePlugin._dndRegion;
+ var type = srcRegion.type;
+ if(!this._config[type]["in"] || !sourcePlugin._config[type]["out"]){
+ return false;
+ }
+ var g = this.grid;
+ var ranges = srcRegion.selected;
+ var colCnt = array.filter(g.layout.cells, function(cell){
+ return !cell.hidden;
+ }).length;
+ var rowCnt = g.rowCount;
+ var res = true;
+ switch(type){
+ case "cell":
+ ranges = ranges[0];
+ res = g.store.getFeatures()["dojo.data.api.Write"] &&
+ (ranges.max.row - ranges.min.row) <= rowCnt &&
+ array.filter(sourcePlugin.grid.layout.cells, function(cell){
+ return cell.index >= ranges.min.col && cell.index <= ranges.max.col && !cell.hidden;
+ }).length <= colCnt;
+ //intentional drop through - don't break
+ case "row":
+ if(sourcePlugin._allDnDItemsLoaded()){
+ return res;
+ }
+ }
+ return false;
+ },
+ _allDnDItemsLoaded: function(){
+ if(this._dndRegion){
+ var type = this._dndRegion.type,
+ ranges = this._dndRegion.selected,
+ rows = [];
+ switch(type){
+ case "cell":
+ for(var i = ranges[0].min.row, max = ranges[0].max.row; i <= max; ++i){
+ rows.push(i);
+ }
+ break;
+ case "row":
+ rows = _joinToArray(ranges);
+ break;
+ default:
+ return false;
+ }
+ var cache = this.grid._by_idx;
+ return array.every(rows, function(rowIndex){
+ return !!cache[rowIndex];
+ });
+ }
+ return false;
+ }
+});
+
+EnhancedGrid.registerPlugin(DnD/*name:'dnd'*/, {
+ "dependency": ["selector", "rearrange"]
+});
+
+return DnD;
+});
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Exporter.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Exporter.js
new file mode 100644
index 0000000..fe12206
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Exporter.js
@@ -0,0 +1,243 @@
+//>>built
+define("dojox/grid/enhanced/plugins/Exporter", [
+ "dojo/_base/declare",
+ "dojo/_base/array",
+ "dojo/_base/lang",
+ "../_Plugin",
+ "../../_RowSelector",
+ "../../EnhancedGrid",
+ "../../cells/_base"
+], function(declare, array, lang, _Plugin, _RowSelector, EnhancedGrid){
+
+var gridCells = lang.getObject("dojox.grid.cells");
+
+var Exporter = declare("dojox.grid.enhanced.plugins.Exporter", _Plugin, {
+ // summary:
+ // Provide functions to export the grid data into a given format.
+ //
+ // Acceptable plugin parameters:
+ // 1. exportFormatter: function(data, cell, rowIndex, item)
+ // Provide a way to customize how data should look in exported string.
+ // Note that usually the formatter of grid cell should not be used here (it can return HTML or even widget).
+ // example:
+ // | function onExported(exported_text){
+ // | //custom code here...
+ // | }
+ // | dijit.byId("my_grid_id").exportTo("csv", //registered export format, mandatory
+ // | { //the whole object is optional.
+ // | fetchArgs: {start:0,count:1000}, //keywordArgs for fetch, optional
+ // | writerArgs: {separator:';'}, //export writer specific arguments, optional
+ // | },
+ // | function(str){
+ // | //call back function, mandatory
+ // | });
+ // | var result = dijit.byId("my_grid_id").exportSelectedTo("table", //registered export format, mandatory
+ // | {separator:'|'} //export writer specific arguments, optional
+ // | );
+ //
+
+ // name: String
+ // Plugin name.
+ name: "exporter",
+
+ constructor: function(grid, args){
+ // summary:
+ // only newed by _Plugin
+ // grid: EnhancedGrid
+ // The grid to plug in to.
+ this.grid = grid;
+ this.formatter = (args && lang.isObject(args)) && args.exportFormatter;
+ this._mixinGrid();
+ },
+ _mixinGrid: function(){
+ var g = this.grid;
+ g.exportTo = lang.hitch(this, this.exportTo);
+ g.exportGrid = lang.hitch(this, this.exportGrid);
+ g.exportSelected = lang.hitch(this, this.exportSelected);
+ g.setExportFormatter = lang.hitch(this, this.setExportFormatter);
+ },
+ setExportFormatter: function(formatter){
+ this.formatter = formatter;
+ },
+ exportGrid: function(type, args, onExported){
+ // summary:
+ // Export required rows(fetchArgs) to a kind of format(type)
+ // using the corresponding writer with given arguments(writerArgs),
+ // then pass the exported text to a given function(onExported).
+ // tags:
+ // public
+ // type: string
+ // A registered export format name
+ // args: object?
+ // includes:
+ // {
+ // fetchArgs: object?
+ // Any arguments for store.fetch
+ // writerArgs: object?
+ // Arguments for the given format writer
+ // }
+ // onExported: function(string)
+ // Call back function when export result is ready
+ if(lang.isFunction(args)){
+ onExported = args;
+ args = {};
+ }
+ if(!lang.isString(type) || !lang.isFunction(onExported)){
+ return;
+ }
+ args = args || {};
+ var g = this.grid, _this = this,
+ writer = this._getExportWriter(type, args.writerArgs),
+ fetchArgs = (args.fetchArgs && lang.isObject(args.fetchArgs)) ? args.fetchArgs : {},
+ oldFunc = fetchArgs.onComplete;
+ if(g.store){
+ fetchArgs.onComplete = function(items, request){
+ if(oldFunc){
+ oldFunc(items, request);
+ }
+ onExported(_this._goThroughGridData(items, writer));
+ };
+ fetchArgs.sort = fetchArgs.sort || g.getSortProps();
+ g._storeLayerFetch(fetchArgs);
+ }else{
+ //Data is defined directly in the structure;
+ var start = fetchArgs.start || 0,
+ count = fetchArgs.count || -1,
+ items = [];
+ for(var i = start; i != start + count && i < g.rowCount; ++i){
+ items.push(g.getItem(i));
+ }
+ onExported(this._goThroughGridData(items, writer));
+ }
+ },
+ exportSelected: function(type, writerArgs){
+ // summary:
+ // Only export selected rows.
+ // tags:
+ // public
+ // type: string
+ // A registered export format name
+ // writerArgs: object?
+ // Arguments for the given format writer
+ // returns: string
+ // The exported string
+ if(!lang.isString(type)){
+ return "";
+ }
+ var writer = this._getExportWriter(type, writerArgs);
+ return this._goThroughGridData(this.grid.selection.getSelected(), writer); //String
+ },
+ _buildRow: function(/* object */arg_obj,/* ExportWriter */writer){
+ // summary:
+ // Use the given export writer(writer) to go through a single row
+ // which is given in the context object(arg_obj).
+ // tags:
+ // private
+ // returns:
+ // undefined
+ var _this = this;
+ array.forEach(arg_obj._views, function(view, vIdx){
+ arg_obj.view = view;
+ arg_obj.viewIdx = vIdx;
+ if(writer.beforeView(arg_obj)){
+ array.forEach(view.structure.cells, function(subrow, srIdx){
+ arg_obj.subrow = subrow;
+ arg_obj.subrowIdx = srIdx;
+ if(writer.beforeSubrow(arg_obj)){
+ array.forEach(subrow, function(cell, cIdx){
+ if(arg_obj.isHeader && _this._isSpecialCol(cell)){
+ arg_obj.spCols.push(cell.index);
+ }
+ arg_obj.cell = cell;
+ arg_obj.cellIdx = cIdx;
+ writer.handleCell(arg_obj);
+ });
+ writer.afterSubrow(arg_obj);
+ }
+ });
+ writer.afterView(arg_obj);
+ }
+ });
+ },
+ _goThroughGridData: function(/* Array */items,/* ExportWriter */writer){
+ // summary:
+ // Use the given export writer(writer) to go through the grid structure
+ // and the given rows(items), then return the writer output.
+ // tags:
+ // private
+ var grid = this.grid,
+ views = array.filter(grid.views.views, function(view){
+ return !(view instanceof _RowSelector);
+ }),
+ arg_obj = {
+ 'grid': grid,
+ 'isHeader': true,
+ 'spCols': [],
+ '_views': views,
+ 'colOffset': (views.length < grid.views.views.length ? -1 : 0)
+ };
+ //go through header
+ if(writer.beforeHeader(grid)){
+ this._buildRow(arg_obj,writer);
+ writer.afterHeader();
+ }
+ //go through content
+ arg_obj.isHeader = false;
+ if(writer.beforeContent(items)){
+ array.forEach(items, function(item, rIdx){
+ arg_obj.row = item;
+ arg_obj.rowIdx = rIdx;
+ if(writer.beforeContentRow(arg_obj)){
+ this._buildRow(arg_obj, writer);
+ writer.afterContentRow(arg_obj);
+ }
+ }, this);
+ writer.afterContent();
+ }
+ return writer.toString();
+ },
+ _isSpecialCol: function(/* dojox.grid.__CellDef */header_cell){
+ // summary:
+ // Row selectors and row indexes should be recognized and handled separately.
+ // tags:
+ // private
+ return header_cell.isRowSelector || header_cell instanceof gridCells.RowIndex; //Boolean
+ },
+ _getExportWriter: function(/* string */ fileType, /* object? */ writerArgs){
+ // summary:
+ // Use the given export format type(fileType)
+ // and writer arguments(writerArgs) to create
+ // a ExportWriter and return it.
+ // tags:
+ // private
+ var writerName, cls,
+ expCls = Exporter;
+ if(expCls.writerNames){
+ writerName = expCls.writerNames[fileType.toLowerCase()];
+ cls = lang.getObject(writerName);
+ if(cls){
+ var writer = new cls(writerArgs);
+ writer.formatter = this.formatter;
+ return writer; //ExportWriter
+ }else{
+ throw new Error('Please make sure class "' + writerName + '" is required.');
+ }
+ }
+ throw new Error('The writer for "' + fileType + '" has not been registered.');
+ }
+});
+
+Exporter.registerWriter = function(/* string */fileType,/* string */writerClsName){
+ // summary:
+ // Register a writer(writerClsName) to a export format type(fileType).
+ // This function separates the Exporter from all kinds of writers.
+ // tags:
+ // public
+ Exporter.writerNames = Exporter.writerNames || {};
+ Exporter.writerNames[fileType] = writerClsName;
+};
+
+EnhancedGrid.registerPlugin(Exporter/*name:'exporter'*/);
+
+return Exporter;
+});
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Filter.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Filter.js
new file mode 100644
index 0000000..a68a00f
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Filter.js
@@ -0,0 +1,173 @@
+//>>built
+define("dojox/grid/enhanced/plugins/Filter", [
+ "dojo/_base/declare",
+ "dojo/_base/lang",
+ "dojo/i18n",
+ "../_Plugin",
+ "./Dialog",
+ "./filter/FilterLayer",
+ "./filter/FilterBar",
+ "./filter/FilterDefDialog",
+ "./filter/FilterStatusTip",
+ "./filter/ClearFilterConfirm",
+ "../../EnhancedGrid",
+ "dojo/i18n!../nls/Filter"
+], function(declare, lang, i18n, _Plugin, Dialog, layers, FilterBar, FilterDefDialog, FilterStatusTip, ClearFilterConfirm, EnhancedGrid){
+
+ var Filter = declare("dojox.grid.enhanced.plugins.Filter", _Plugin, {
+ // summary:
+ // Provide filter functionality for grid.
+ //
+ // Acceptable plugin parameters:
+ // 1. itemsName: string
+ // the name shown on the filter bar.
+ // 2. statusTipTimeout: number
+ // when does the status tip show.
+ // 3. ruleCount: number
+ // default to 3, should not change to more. The Claro theme limits it.
+ // 4. disabledConditions: object
+ // If you don't need all of the conditions provided for a data type,
+ // you can explicitly declare them here:
+ // e.g.: disabledConditions: {string: ["contains", "is"], number: ["equalto"], ...}
+ // 5. isServerSide: boolean
+ // Whether to use server side filtering. Default to false.
+ // 6. isStateful: boolean
+ // If isServerSide is true, set the server side filter to be stateful or not. default to false.
+ // 7. url: string
+ // If using stateful, this is the url to send commands. default to store.url.
+ // 8. ruleCountToConfirmClearFilter: Integer | null |Infinity
+ // If the filter rule count is larger than or equal to this value, then a confirm dialog will show when clearing filter.
+ // If set to less than 1 or null, then always show the confirm dialog.
+ // If set to Infinity, then never show the confirm dialog.
+ // Default value is 2.
+ //
+ // Acceptable cell parameters defined in layout:
+ // 1. filterable: boolean
+ // The column is not filterable only when this is set to false explicitly.
+ // 2. datatype: string
+ // The data type of this column. Can be "string", "number", "date", "time", "boolean".
+ // Default to "string".
+ // 3. autoComplete: boolean
+ // If need auto-complete in the ComboBox for String type, set this to true.
+ // 4. dataTypeArgs: object
+ // Some arguments helping convert store data to something the filter UI understands.
+ // Different data type arguments can be provided to different data types.
+ // For date/time, this is a dojo.date.locale.__FormatOptions, so the DataTimeBox can understand the store data.
+ // For boolean, this object contains:
+ // trueLabel: string
+ // A label to display in the filter definition dialog for true value. Default to "True".
+ // falseLable: string
+ // A label to display in the filter definition dialog for false value. Default to "False".
+ // 5. disabledConditions: object
+ // If you don't need all of the conditions provided by the filter UI on this column, you can explicitly say it out here.
+ // e.g.: disabledConditions: ["contains", "is"]
+ // This will disable the "contains" condition for this column, if this column is of string type.
+ // For full set of conditions, please refer to dojox.grid.enhanced.plugins.filter.FilterDefDialog._setupData.
+ // example:
+ // | <div dojoType="dojox.grid.EnhancedGrid" plugins="{GridFilter: true}" ...></div>
+ // | or provide some parameters:
+ // | <div dojoType="dojox.grid.EnhancedGrid" plugins="{GridFilter: {itemsName: 'songs'}}" ...></div>
+ // | Customize columns for filter:
+ // | var layout = [
+ // | ...
+ // | //define a column to be un-filterable in layout/structure
+ // | {field: "Genre", filterable: false, ...}
+ // | //define a column of type string and supports autoComplete when you type in filter conditions.
+ // | {field: "Writer", datatype: "string", autoCommplete: true, ...}
+ // | //define a column of type date and the data in store has format: "yyyy/M/d"
+ // | {field: "Publish Date", datatype: "date", dataTypeArgs: {datePattern: "yyyy/M/d"}, ...}
+ // | //disable some conditions for a column
+ // | {field: "Track", disabledConditions: ["equalto","notequalto"], ...}
+ // | ...
+ // | ];
+
+ // name: String
+ // plugin name
+ name: "filter",
+
+ constructor: function(grid, args){
+ // summary:
+ // See constructor of dojox.grid.enhanced._Plugin.
+ this.grid = grid;
+ this.nls = i18n.getLocalization("dojox.grid.enhanced", "Filter");
+
+ args = this.args = lang.isObject(args) ? args : {};
+ if(typeof args.ruleCount != 'number' || args.ruleCount < 0){
+ args.ruleCount = 3;
+ }
+ var rc = this.ruleCountToConfirmClearFilter = args.ruleCountToConfirmClearFilter;
+ if(rc === undefined){
+ this.ruleCountToConfirmClearFilter = 2;
+ }
+
+ //Install filter layer
+ this._wrapStore();
+
+ //Install UI components
+ var obj = { "plugin": this };
+ this.clearFilterDialog = new Dialog({
+ refNode: this.grid.domNode,
+ title: this.nls["clearFilterDialogTitle"],
+ content: new ClearFilterConfirm(obj)
+ });
+ this.filterDefDialog = new FilterDefDialog(obj);
+ this.filterBar = new FilterBar(obj);
+ this.filterStatusTip = new FilterStatusTip(obj);
+
+ //Expose the layer event to grid.
+ grid.onFilterDefined = function(){};
+ this.connect(grid.layer("filter"), "onFilterDefined", function(filter){
+ grid.onFilterDefined(grid.getFilter(), grid.getFilterRelation());
+ });
+ },
+ destroy: function(){
+ this.inherited(arguments);
+ try{
+ this.grid.unwrap("filter");
+ this.filterBar.destroyRecursive();
+ this.filterBar = null;
+ this.clearFilterDialog.destroyRecursive();
+ this.clearFilterDialog = null;
+ this.filterStatusTip.destroy();
+ this.filterStatusTip = null;
+ this.filterDefDialog.destroy();
+ this.filterDefDialog = null;
+ this.grid = null;
+ this.nls = null;
+ this.args = null;
+ }catch(e){
+ console.warn("Filter.destroy() error:",e);
+ }
+ },
+ _wrapStore: function(){
+ var g = this.grid;
+ var args = this.args;
+ var filterLayer = args.isServerSide ? new layers.ServerSideFilterLayer(args) :
+ new layers.ClientSideFilterLayer({
+ cacheSize: args.filterCacheSize,
+ fetchAll: args.fetchAllOnFirstFilter,
+ getter: this._clientFilterGetter
+ });
+ layers.wrap(g, "_storeLayerFetch", filterLayer);
+
+ this.connect(g, "_onDelete", lang.hitch(filterLayer, "invalidate"));
+ },
+ onSetStore: function(store){
+ this.filterDefDialog.clearFilter(true);
+ },
+ _clientFilterGetter: function(/* data item */ datarow,/* cell */cell, /* int */rowIndex){
+ // summary:
+ // Define the grid-specific way to get data from a row.
+ // Argument "cell" is provided by FilterDefDialog when defining filter expressions.
+ // Argument "rowIndex" is provided by FilterLayer when checking a row.
+ // FilterLayer also provides a forth argument: "store", which is grid.store,
+ // but we don't need it here.
+ return cell.get(rowIndex, datarow);
+ }
+ });
+
+ EnhancedGrid.registerPlugin(Filter/*name:'filter'*/);
+
+ return Filter;
+
+});
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/GridSource.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/GridSource.js
new file mode 100644
index 0000000..18c393c
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/GridSource.js
@@ -0,0 +1,155 @@
+//>>built
+define("dojox/grid/enhanced/plugins/GridSource", [
+ "dojo/_base/declare",
+ "dojo/_base/array",
+ "dojo/_base/lang",
+ "dojo/dnd/Source",
+ "./DnD"
+], function(declare, array, lang, Source, DnD){
+
+var _joinToArray = function(arrays){
+ var a = arrays[0];
+ for(var i = 1; i < arrays.length; ++i){
+ a = a.concat(arrays[i]);
+ }
+ return a;
+};
+
+var GridDnDSource = lang.getObject("dojox.grid.enhanced.plugins.GridDnDSource");
+
+return declare("dojox.grid.enhanced.plugins.GridSource", Source, {
+ // summary:
+ // A special source that can accept grid contents.
+ // Only for non-grid widgets or domNodes.
+ accept: ["grid/cells", "grid/rows", "grid/cols", "text"],
+
+ // insertNodesForGrid:
+ // If you'd like to insert some sort of nodes into your dnd source, turn this on,
+ // and override getCellContent/getRowContent/getColumnContent
+ // to populate the dnd data in your desired format.
+ insertNodesForGrid: false,
+
+ markupFactory: function(params, node){
+ cls = lang.getObject("dojox.grid.enhanced.plugins.GridSource");
+ return new cls(node, params);
+ },
+ checkAcceptance: function(source, nodes){
+ if(source instanceof GridDnDSource){
+ if(nodes[0]){
+ var item = source.getItem(nodes[0].id);
+ if(item && (array.indexOf(item.type, "grid/rows") >= 0 || array.indexOf(item.type, "grid/cells") >= 0) &&
+ !source.dndPlugin._allDnDItemsLoaded()){
+ return false;
+ }
+ }
+ this.sourcePlugin = source.dndPlugin;
+ }
+ return this.inherited(arguments);
+ },
+ onDraggingOver: function(){
+ if(this.sourcePlugin){
+ this.sourcePlugin._isSource = true;
+ }
+ },
+ onDraggingOut: function(){
+ if(this.sourcePlugin){
+ this.sourcePlugin._isSource = false;
+ }
+ },
+ onDropExternal: function(source, nodes, copy){
+ if(source instanceof GridDnDSource){
+ var ranges = array.map(nodes, function(node){
+ return source.getItem(node.id).data;
+ });
+ var item = source.getItem(nodes[0].id);
+ var grid = item.dndPlugin.grid;
+ var type = item.type[0];
+ var range;
+ try{
+ switch(type){
+ case "grid/cells":
+ nodes[0].innerHTML = this.getCellContent(grid, ranges[0].min, ranges[0].max) || "";
+ this.onDropGridCells(grid, ranges[0].min, ranges[0].max);
+ break;
+ case "grid/rows":
+ range = _joinToArray(ranges);
+ nodes[0].innerHTML = this.getRowContent(grid, range) || "";
+ this.onDropGridRows(grid, range);
+ break;
+ case "grid/cols":
+ range = _joinToArray(ranges);
+ nodes[0].innerHTML = this.getColumnContent(grid, range) || "";
+ this.onDropGridColumns(grid, range);
+ break;
+ }
+ if(this.insertNodesForGrid){
+ this.selectNone();
+ this.insertNodes(true, [nodes[0]], this.before, this.current);
+ }
+ item.dndPlugin.onDragOut(!copy);
+ }catch(e){
+ console.warn("GridSource.onDropExternal() error:",e);
+ }
+ }else{
+ this.inherited(arguments);
+ }
+ },
+ getCellContent: function(grid, leftTopCell, rightBottomCell){
+ // summary:
+ // Fill node innerHTML for dnd grid cells.
+ // sample code:
+ // var cells = grid.layout.cells;
+ // var store = grid.store;
+ // var cache = grid._by_idx;
+ // var res = "Grid Cells from " + grid.id + ":<br/>";
+ // for(var r = leftTopCell.row; r <= rightBottomCell.row; ++r){
+ // for(var c = leftTopCell.col; c <= rightBottomCell.col; ++c){
+ // res += store.getValue(cache[r].item, cells[c].field) + ", ";
+ // }
+ // res = res.substring(0, res.length - 2) + ";<br/>";
+ // }
+ // return res;
+ },
+ getRowContent: function(grid, rowIndexes){
+ // summary:
+ // Fill node innerHTML for dnd grid rows.
+ // sample code:
+ // var cells = grid.layout.cells;
+ // var store = grid.store;
+ // var cache = grid._by_idx;
+ // var res = "Grid Rows from " + grid.id + ":<br/>";
+ // for(var i = 0; i < rowIndexes.length; ++i){
+ // var r = rowIndexes[i];
+ // res += "Row " + r + ": ";
+ // for(var j = 0; j < cells.length; ++j){
+ // if(!cells[j].hidden){
+ // res += store.getValue(cache[r].item, cells[j].field) + ", ";
+ // }
+ // }
+ // res = res.substring(0, res.length - 2) + ";<br/>";
+ // }
+ // return res;
+ },
+ getColumnContent: function(grid, colIndexes){
+ // summary:
+ // Fill node innerHTML for dnd grid columns.
+ // sample code:
+ // var cells = grid.layout.cells;
+ // var res = "Grid Columns from " + grid.id + ":";
+ // for(var i = 0; i < colIndexes.length; ++i){
+ // var c = colIndexes[i];
+ // res += (cells[c].name || cells[c].field) + ", ";
+ // }
+ // return res.substring(0, res.length - 2);
+ },
+ onDropGridCells: function(grid, leftTopCell, rightBottomCell){
+
+ },
+ onDropGridRows: function(grid, rowIndexes){
+
+ },
+ onDropGridColumns: function(grid, colIndexes){
+
+ }
+});
+});
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/IndirectSelection.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/IndirectSelection.js
new file mode 100644
index 0000000..3b41e84
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/IndirectSelection.js
@@ -0,0 +1,626 @@
+//>>built
+define("dojox/grid/enhanced/plugins/IndirectSelection", [
+ "dojo/_base/declare",
+ "dojo/_base/array",
+ "dojo/_base/event",
+ "dojo/_base/lang",
+ "dojo/_base/html",
+ "dojo/_base/window",
+ "dojo/_base/connect",
+ "dojo/_base/sniff",
+ "dojo/query",
+ "dojo/keys",
+ "dojo/string",
+ "../_Plugin",
+ "../../EnhancedGrid",
+ "../../cells/dijit"
+], function(declare, array, evt, lang, html, win, connect, has, query, keys, string, _Plugin, EnhancedGrid){
+
+var gridCells = lang.getObject("dojox.grid.cells");
+
+var RowSelector = declare("dojox.grid.cells.RowSelector", gridCells._Widget, {
+ // summary:
+ // Common attributes & functions for row selectors(Radio|CheckBox)
+
+ //inputType: String
+ // Input type - Radio|CheckBox
+ inputType: "",
+
+ //map: Object
+ // Cache div refs of radio|checkbox to avoid querying each time
+ map: null,
+
+ //disabledMap: Object
+ // Cache index of disabled rows
+ disabledMap: null,
+
+ //isRowSelector: Boolean
+ // Marker of indirectSelection cell(column)
+ isRowSelector: true,
+
+ //_connects: Array
+ // List of all connections.
+ _connects: null,
+
+ //_subscribes: Array
+ // List of all subscribes.
+ _subscribes: null,
+
+ //checkedText: String
+ // Checked character for high contrast mode
+ checkedText: '&#10003;',
+
+ //unCheckedText: String
+ // Unchecked character for high contrast mode
+ unCheckedText: 'O',
+
+ constructor: function(){
+ this.map = {}; this.disabledMap = {}, this.disabledCount= 0;
+ this._connects = []; this._subscribes = [];
+ this.inA11YMode = html.hasClass(win.body(), "dijit_a11y");
+
+ this.baseClass = "dojoxGridRowSelector dijitReset dijitInline dijit" + this.inputType;
+ this.checkedClass = " dijit" + this.inputType + "Checked";
+ this.disabledClass = " dijit" + this.inputType + "Disabled";
+ this.checkedDisabledClass = " dijit" + this.inputType + "CheckedDisabled";
+ this.statusTextClass = " dojoxGridRowSelectorStatusText";//a11y use
+
+ this._connects.push(connect.connect(this.grid, 'dokeyup', this, '_dokeyup'));
+ this._connects.push(connect.connect(this.grid.selection, 'onSelected', this, '_onSelected'));
+ this._connects.push(connect.connect(this.grid.selection, 'onDeselected', this, '_onDeselected'));
+ this._connects.push(connect.connect(this.grid.scroller, 'invalidatePageNode', this, '_pageDestroyed'));
+ this._connects.push(connect.connect(this.grid, 'onCellClick', this, '_onClick'));
+ this._connects.push(connect.connect(this.grid, 'updateRow', this, '_onUpdateRow'));
+ },
+ formatter: function(data, rowIndex, scope){
+ // summary:
+ // Overwritten, see dojox.grid.cells._Widget
+ var _this = scope;
+ var clazz = _this.baseClass;
+ var checked = _this.getValue(rowIndex);
+ var disabled = !!_this.disabledMap[rowIndex];//normalize 'undefined'
+
+ if(checked){
+ clazz += _this.checkedClass;
+ if(disabled){ clazz += _this.checkedDisabledClass; }
+ }else if(disabled){
+ clazz += _this.disabledClass;
+ }
+ return ["<div tabindex = -1 ",
+ "id = '" + _this.grid.id + "_rowSelector_" + rowIndex + "' ",
+ "name = '" + _this.grid.id + "_rowSelector' class = '" + clazz + "' ",
+ "role = 'presentation' aria-pressed = '" + checked + "' aria-disabled = '" + disabled +
+ "' aria-label = '" + string.substitute(_this.grid._nls["indirectSelection" + _this.inputType], [rowIndex + 1]) + "'>",
+ "<span class = '" + _this.statusTextClass + "'>" + (checked ? _this.checkedText : _this.unCheckedText) + "</span>",
+ "</div>"].join("");
+ },
+ setValue: function(rowIndex, inValue){
+ // summary:
+ // Overwritten, see dojox.grid.cells._Widget
+ // Simply return, no action
+ },
+ getValue: function(rowIndex){
+ // summary:
+ // Overwritten, see dojox.grid.cells._Widget
+ return this.grid.selection.isSelected(rowIndex);
+ },
+ toggleRow: function(index, value){
+ // summary:
+ // toggle checked | unchecked state for given row
+ // index: Integer
+ // Row index
+ // value: Boolean
+ // True - checked | False - unchecked
+ this._nativeSelect(index, value);
+ },
+ setDisabled: function(index, disabled){
+ // summary:
+ // toggle disabled | enabled state for given row
+ // idx: Integer
+ // Row index
+ // disabled: Boolean
+ // True - disabled | False - enabled
+ if(index < 0){ return; }
+ this._toggleDisabledStyle(index, disabled);
+ },
+ disabled: function(index){
+ // summary:
+ // Check if one row is disabled
+ return !!this.disabledMap[index];
+ },
+ _onClick: function(e){
+ // summary:
+ // When mouse click on the selector cell, select/deselect the row.
+ if(e.cell === this){
+ this._selectRow(e);
+ }
+ },
+ _dokeyup: function(e){
+ // summary:
+ // Event handler for key up event
+ // - from dojox.grid.enhanced._Events.dokeyup()
+ // e: Event
+ // Key up event
+ if(e.cellIndex == this.index && e.rowIndex >= 0 && e.keyCode == keys.SPACE){
+ this._selectRow(e);
+ }
+ },
+ focus: function(rowIndex){
+ // summary:
+ // Set focus to given row
+ // rowIndex: Integer
+ // Target row
+ var selector = this.map[rowIndex];
+ if(selector){ selector.focus(); }
+ },
+ _focusEndingCell: function(rowIndex, cellIndex){
+ // summary:
+ // Set focus to the ending grid cell(rowIndex,cellIndex) when swipe selection finished
+ // rowIndex: Integer
+ // Row index
+ // cellIndex: Integer
+ // Column index
+ var cell = this.grid.getCell(cellIndex);
+ this.grid.focus.setFocusCell(cell, rowIndex);
+ },
+ _nativeSelect: function(index, value){
+ // summary:
+ // Use grid's native selection
+ this.grid.selection[value ? 'select' : 'deselect'](index);
+ },
+ _onSelected: function(index){
+ // summary:
+ // Triggered when a row is selected
+ this._toggleCheckedStyle(index, true);
+ },
+ _onDeselected: function(index){
+ // summary:
+ // Triggered when a row is deselected
+ this._toggleCheckedStyle(index, false);
+ },
+ _onUpdateRow: function(index){
+ // summary:
+ // Clear cache when row is re-built.
+ delete this.map[index];
+ },
+ _toggleCheckedStyle: function(index, value){
+ // summary:
+ // Change css styles for checked | unchecked
+ var selector = this._getSelector(index);
+ if(selector){
+ html.toggleClass(selector, this.checkedClass, value);
+ if(this.disabledMap[index]){
+ html.toggleClass(selector, this.checkedDisabledClass, value);
+ }
+ selector.setAttribute("aria-pressed", value);
+ if(this.inA11YMode){
+ selector.firstChild.innerHTML = (value ? this.checkedText : this.unCheckedText);
+ }
+ }
+ },
+ _toggleDisabledStyle: function(index, disabled){
+ // summary:
+ // Change css styles for disabled | enabled
+ var selector = this._getSelector(index);
+ if(selector){
+ html.toggleClass(selector, this.disabledClass, disabled);
+ if(this.getValue(index)){
+ html.toggleClass(selector, this.checkedDisabledClass, disabled);
+ }
+ selector.setAttribute("aria-disabled", disabled);
+ }
+ this.disabledMap[index] = disabled;
+ if(index >= 0){
+ this.disabledCount += disabled ? 1 : -1;
+ }
+ },
+ _getSelector: function(index){
+ // summary:
+ // Find selector for given row caching it if 1st time found
+ var selector = this.map[index];
+ if(!selector){//use accurate query for better performance
+ var rowNode = this.view.rowNodes[index];
+ if(rowNode){
+ selector = query('.dojoxGridRowSelector', rowNode)[0];
+ if(selector){ this.map[index] = selector; }
+ }
+ }
+ return selector;
+ },
+ _pageDestroyed: function(pageIndex){
+ // summary:
+ // Explicitly empty map cache when a page destroyed
+ // See dojox.grid._Scroller.invalidatePageNode()
+ // pageIndex: Integer
+ // Index of destroyed page
+ var rowsPerPage = this.grid.scroller.rowsPerPage;
+ var start = pageIndex * rowsPerPage, end = start + rowsPerPage - 1;
+ for(var i = start; i <= end; i++){
+ if(!this.map[i]){continue;}
+ html.destroy(this.map[i]);
+ delete this.map[i];
+ }
+ //console.log("Page ",pageIndex, " destroyed, Map=",this.map);
+ },
+ destroy: function(){
+ for(var i in this.map){
+ html.destroy(this.map[i]);
+ delete this.map[i];
+ }
+ for(i in this.disabledMap){ delete this.disabledMap[i]; }
+ array.forEach(this._connects, connect.disconnect);
+ array.forEach(this._subscribes, connect.unsubscribe);
+ delete this._connects;
+ delete this._subscribes;
+ //console.log('Single(Multiple)RowSelector.destroy() executed!');
+ }
+});
+
+var SingleRowSelector = declare("dojox.grid.cells.SingleRowSelector", RowSelector, {
+ // summary:
+ // IndirectSelection cell(column) for single selection mode, using styles of dijit.form.RadioButton
+ inputType: "Radio",
+
+ _selectRow: function(e){
+ // summary:
+ // Select the target row
+ // e: Event
+ // Event fired on the target row
+ var index = e.rowIndex;
+ if(this.disabledMap[index]){ return; }
+ this._focusEndingCell(index, 0);
+ this._nativeSelect(index, !this.grid.selection.selected[index]);
+ }
+});
+
+var MultipleRowSelector = declare("dojox.grid.cells.MultipleRowSelector", RowSelector, {
+ // summary:
+ // Indirect selection cell for multiple or extended mode, using dijit.form.CheckBox
+ inputType: "CheckBox",
+
+ //swipeStartRowIndex: Integer
+ // Start row index for swipe selection
+ swipeStartRowIndex: -1,
+
+ //swipeMinRowIndex: Integer
+ // Min row index for swipe selection
+ swipeMinRowIndex: -1,
+
+ //swipeMinRowIndex: Integer
+ // Max row index for swipe selection
+ swipeMaxRowIndex: -1,
+
+ //toSelect: Boolean
+ // new state for selection
+ toSelect: false,
+
+ //lastClickRowIdx: Integer
+ // Row index for last click, used for range selection via Shift + click
+ lastClickRowIdx: -1,
+
+ //toggleAllTrigerred: Boolean
+ // Whether toggle all has been triggered or not
+ toggleAllTrigerred: false,
+
+ unCheckedText: '&#9633;',
+
+ constructor: function(){
+ this._connects.push(connect.connect(win.doc, 'onmouseup', this, '_domouseup'));
+ this._connects.push(connect.connect(this.grid, 'onRowMouseOver', this, '_onRowMouseOver'));
+ this._connects.push(connect.connect(this.grid.focus, 'move', this, '_swipeByKey'));
+ this._connects.push(connect.connect(this.grid, 'onCellMouseDown', this, '_onMouseDown'));
+ if(this.headerSelector){//option set by user to add a select-all checkbox in column header
+ this._connects.push(connect.connect(this.grid.views, 'render', this, '_addHeaderSelector'));
+ this._connects.push(connect.connect(this.grid, '_onFetchComplete', this, '_addHeaderSelector'));
+ this._connects.push(connect.connect(this.grid, 'onSelectionChanged', this, '_onSelectionChanged'));
+ this._connects.push(connect.connect(this.grid, 'onKeyDown', this, function(e){
+ if(e.rowIndex == -1 && e.cellIndex == this.index && e.keyCode == keys.SPACE){
+ this._toggletHeader();//TBD - a better way
+ }
+ }));
+ }
+ },
+ toggleAllSelection:function(checked){
+ // summary:
+ // Toggle select all|deselect all
+ // checked: Boolean
+ // True - select all, False - deselect all
+ var grid = this.grid, selection = grid.selection;
+ if(checked){
+ selection.selectRange(0, grid.rowCount-1);
+ }else{
+ selection.deselectAll();
+ }
+ this.toggleAllTrigerred = true;
+ },
+ _onMouseDown: function(e){
+ if(e.cell == this){
+ this._startSelection(e.rowIndex);
+ evt.stop(e);
+ }
+ },
+ _onRowMouseOver: function(e){
+ // summary:
+ // Event fired when mouse moves over a data row(outside of this column).
+ // - from dojox.grid.enhanced._Events.onRowMouseOver()
+ // e: Event
+ // Decorated event object which contains reference to grid, cell, and rowIndex
+ this._updateSelection(e, 0);
+ },
+ _domouseup: function(e){
+ // summary:
+ // Event handler for mouse up event - from dojo.doc.domouseup()
+ // e: Event
+ // Mouse up event
+ if(has("ie")){
+ this.view.content.decorateEvent(e);//TODO - why only e in IE hasn't been decorated?
+ }
+ var inSwipeSelection = e.cellIndex >= 0 && this.inSwipeSelection() && !this.grid.edit.isEditRow(e.rowIndex);
+ if(inSwipeSelection){
+ this._focusEndingCell(e.rowIndex, e.cellIndex);
+ }
+ this._finishSelect();
+ },
+ _dokeyup: function(e){
+ // summary:
+ // Event handler for key up event
+ // - from dojox.grid.enhanced._Events.dokeyup()
+ // e: Event
+ // Key up event
+ this.inherited(arguments);
+ if(!e.shiftKey){
+ this._finishSelect();
+ }
+ },
+ _startSelection: function(rowIndex){
+ // summary:
+ // Initialize parameters to start a new swipe selection
+ // rowIndex: Integer
+ // Index of the start row
+ this.swipeStartRowIndex = this.swipeMinRowIndex = this.swipeMaxRowIndex = rowIndex;
+ this.toSelect = !this.getValue(rowIndex);
+ },
+ _updateSelection: function(e, delta){
+ // summary:
+ // Update row selections, fired during a swipe selection
+ // e: Event
+ // Event of the current row,
+ // delta: Integer
+ // Row index delta, used for swipe selection via Shift + Arrow key
+ // 0: not via key, -1 : Shift + Up, 1 : Shift + Down
+ if(!this.inSwipeSelection()){ return; }
+
+ var byKey = delta !== 0;//whether via Shift + Arrow Key
+ var currRow = e.rowIndex, deltaRow = currRow - this.swipeStartRowIndex + delta;
+ if(deltaRow > 0 && this.swipeMaxRowIndex < currRow + delta){
+ this.swipeMaxRowIndex = currRow + delta;
+ }
+ if(deltaRow < 0 && this.swipeMinRowIndex > currRow + delta){
+ this.swipeMinRowIndex = currRow + delta;
+ }
+
+ var min = deltaRow > 0 ? this.swipeStartRowIndex : currRow + delta;
+ var max = deltaRow > 0 ? currRow + delta : this.swipeStartRowIndex;
+ for(var i = this.swipeMinRowIndex; i <= this.swipeMaxRowIndex; i++){
+ if(this.disabledMap[i] || i < 0){ continue; }
+ if(i >= min && i <= max){//deltaRow != 0 || this.toSelect
+ this._nativeSelect(i, this.toSelect);
+ }else if(!byKey){
+ this._nativeSelect(i, !this.toSelect);
+ }
+ }
+ },
+ _swipeByKey: function(rowOffset, colOffset, e){
+ // summary:
+ // Update row selections, fired when Shift + Cursor is used for swipe selection
+ // See dojox.grid.enhanced._Events.onKeyDown
+ // e: Event
+ // Event of the current row,
+ // rowOffset: Integer
+ // Row offset, used for swipe selection via Shift + Cursor
+ // -1 : Shift + Up, 1 : Shift + Down
+ if(!e || rowOffset === 0 || !e.shiftKey || e.cellIndex != this.index ||
+ this.grid.focus.rowIndex < 0){ //TBD - e.rowIndex == 0 && delta == -1
+ return;
+ }
+ var rowIndex = e.rowIndex;
+ if(this.swipeStartRowIndex < 0){
+ //A new swipe selection starts via Shift + Arrow key
+ this.swipeStartRowIndex = rowIndex;
+ if(rowOffset > 0){//Shift + Down
+ this.swipeMaxRowIndex = rowIndex + rowOffset;
+ this.swipeMinRowIndex = rowIndex;
+ }else{//Shift + UP
+ this.swipeMinRowIndex = rowIndex + rowOffset;
+ this.swipeMaxRowIndex = rowIndex;
+ }
+ this.toSelect = this.getValue(rowIndex);
+ }
+ this._updateSelection(e, rowOffset);
+ },
+ _finishSelect: function(){
+ // summary:
+ // Reset parameters to end a swipe selection
+ this.swipeStartRowIndex = -1;
+ this.swipeMinRowIndex = -1;
+ this.swipeMaxRowIndex = -1;
+ this.toSelect = false;
+ },
+ inSwipeSelection: function(){
+ // summary:
+ // Check if during a swipe selection
+ // return: Boolean
+ // Whether in swipe selection
+ return this.swipeStartRowIndex >= 0;
+ },
+ _nativeSelect: function(index, value){
+ // summary:
+ // Overwritten
+ this.grid.selection[value ? 'addToSelection' : 'deselect'](index);
+ },
+ _selectRow: function(e){
+ // summary:
+ // Select the target row or range or rows
+ // e: Event
+ // Event fired on the target row
+ var rowIndex = e.rowIndex;
+ if(this.disabledMap[rowIndex]){ return; }
+ evt.stop(e);
+ this._focusEndingCell(rowIndex, 0);
+
+ var delta = rowIndex - this.lastClickRowIdx;
+ var newValue = !this.grid.selection.selected[rowIndex];
+ if(this.lastClickRowIdx >= 0 && !e.ctrlKey && !e.altKey && e.shiftKey){
+ var min = delta > 0 ? this.lastClickRowIdx : rowIndex;
+ var max = delta > 0 ? rowIndex : this.lastClickRowIdx;
+ for(var i = min; i >= 0 && i <= max; i++){
+ this._nativeSelect(i, newValue);
+ }
+ }else{
+ this._nativeSelect(rowIndex, newValue);
+ }
+ this.lastClickRowIdx = rowIndex;
+ },
+ getValue: function(rowIndex){
+ // summary:
+ // Overwritten
+ if(rowIndex == -1){//header selector
+ var g = this.grid;
+ return g.rowCount > 0 && g.rowCount <= g.selection.getSelectedCount();
+ }
+ return this.inherited(arguments);
+ },
+ _addHeaderSelector: function(){
+ // summary:
+ // Add selector in column header for selecting|deselecting all
+ var headerCellNode = this.view.getHeaderCellNode(this.index);
+ if(!headerCellNode){ return; }
+ html.empty(headerCellNode);
+ var g = this.grid;
+ var selector = headerCellNode.appendChild(html.create("div", {
+ 'aria-label': g._nls["selectAll"],
+ "tabindex": -1, "id": g.id + "_rowSelector_-1", "class": this.baseClass, "role": "presentation",
+ "innerHTML": "<span class = '" + this.statusTextClass +
+ "'></span><span style='height: 0; width: 0; overflow: hidden; display: block;'>" +
+ g._nls["selectAll"] + "</span>"
+ }));
+ this.map[-1] = selector;
+ var idx = this._headerSelectorConnectIdx;
+ if(idx !== undefined){
+ connect.disconnect(this._connects[idx]);
+ this._connects.splice(idx, 1);
+ }
+ this._headerSelectorConnectIdx = this._connects.length;
+ this._connects.push(connect.connect(selector, 'onclick', this, '_toggletHeader'));
+ this._onSelectionChanged();
+ },
+ _toggletHeader: function(){
+ // summary:
+ // Toggle state for head selector
+ if(!!this.disabledMap[-1]){ return; }
+ this.grid._selectingRange = true;
+ this.toggleAllSelection(!this.getValue(-1));
+ this._onSelectionChanged();
+ this.grid._selectingRange = false;
+ },
+ _onSelectionChanged: function(){
+ // summary:
+ // Update header selector anytime selection changed
+ var g = this.grid;
+ if(!this.map[-1] || g._selectingRange){ return; }
+ g.allItemsSelected = this.getValue(-1);
+ this._toggleCheckedStyle(-1, g.allItemsSelected);
+ },
+ _toggleDisabledStyle: function(index, disabled){
+ // summary:
+ // Overwritten
+ this.inherited(arguments);
+ if(this.headerSelector){
+ var allDisabled = (this.grid.rowCount == this.disabledCount);
+ if(allDisabled != !!this.disabledMap[-1]){//only if needed
+ arguments[0] = -1;
+ arguments[1] = allDisabled;
+ this.inherited(arguments);
+ }
+ }
+ }
+});
+
+var IndirectSelection = declare("dojox.grid.enhanced.plugins.IndirectSelection", _Plugin, {
+ // summary:
+ // A handy way for adding check boxe/radio button for rows, and selecting rows by swiping(or keyboard)
+
+ // description:
+ // For better rendering performance, div(images) are used to simulate radio button|check boxes
+ //
+ // example:
+ // <div dojoType="dojox.grid.EnhancedGrid" plugins="{indirectSelection: true}" ...></div>
+ // or <div dojoType="dojox.grid.EnhancedGrid" plugins="{indirectSelection: {name: 'xxx', width:'30px', styles:'text-align: center;'}}" ...></div>
+
+ //name: String
+ // Plugin name
+ name: "indirectSelection",
+
+ constructor: function(){
+ //Hook layout.setStructure(), so that indirectSelection is always included
+ var layout = this.grid.layout;
+ this.connect(layout, 'setStructure', lang.hitch(layout, this.addRowSelectCell, this.option));
+ },
+ addRowSelectCell: function(option){
+ // summary:
+ // Add indirectSelection cell(mapped to a column of radio button|check boxes)
+ if(!this.grid.indirectSelection || this.grid.selectionMode == 'none'){
+ return;
+ }
+ var rowSelectCellAdded = false, inValidFields = ['get', 'formatter', 'field', 'fields'],
+ defaultCellDef = {type: MultipleRowSelector, name: '', width:'30px', styles:'text-align: center;'};
+ if(option.headerSelector){ option.name = ''; }//mutual conflicting attrs
+
+ if(this.grid.rowSelectCell){//remove the existed one
+ this.grid.rowSelectCell.destroy();
+ }
+
+ array.forEach(this.structure, function(view){
+ var cells = view.cells;
+ if(cells && cells.length > 0 && !rowSelectCellAdded){
+ var firstRow = cells[0];
+ if(firstRow[0] && firstRow[0].isRowSelector){
+ console.debug('addRowSelectCell() - row selector cells already added, return.');
+ rowSelectCellAdded = true;
+ return;
+ }
+ var selectDef, cellType = this.grid.selectionMode == 'single' ? SingleRowSelector : MultipleRowSelector;
+ selectDef = lang.mixin(defaultCellDef, option, {type: cellType, editable: false, notselectable: true, filterable: false, navigatable: true, nosort: true});
+ array.forEach(inValidFields, function(field){//remove invalid fields
+ if(field in selectDef){ delete selectDef[field]; }
+ });
+ if(cells.length > 1){ selectDef.rowSpan = cells.length; }//for complicate layout
+ array.forEach(this.cells, function(cell, i){
+ if(cell.index >= 0){
+ cell.index += 1;
+ //console.debug('cell '+ (cell.index - 1) + ' is updated to index ' + cell.index);
+ }else{
+ console.warn('Error:IndirectSelection.addRowSelectCell()- cell ' + i + ' has no index!');
+ }
+ });
+ var rowSelectCell = this.addCellDef(0, 0, selectDef);
+ rowSelectCell.index = 0;
+ firstRow.unshift(rowSelectCell);
+ this.cells.unshift(rowSelectCell);
+ this.grid.rowSelectCell = rowSelectCell;
+ rowSelectCellAdded = true;
+ }
+ }, this);
+ this.cellCount = this.cells.length;
+ },
+ destroy: function(){
+ this.grid.rowSelectCell.destroy();
+ delete this.grid.rowSelectCell;
+ this.inherited(arguments);
+ }
+});
+
+EnhancedGrid.registerPlugin(IndirectSelection/*name:'indirectSelection'*/, {"preInit": true});
+
+return IndirectSelection;
+});
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Menu.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Menu.js
new file mode 100644
index 0000000..e65ac7b
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Menu.js
@@ -0,0 +1,134 @@
+//>>built
+define("dojox/grid/enhanced/plugins/Menu", [
+ "dojo/_base/declare",
+ "dojo/_base/array",
+ "dojo/_base/lang",
+ "dojo/_base/html",
+ "dojo/_base/event",
+ "dojo/keys",
+ "../_Plugin",
+ "../../EnhancedGrid"
+], function(declare, array, lang, html, evt, keys, _Plugin, EnhancedGrid){
+
+var Menu = declare("dojox.grid.enhanced.plugins.Menu", _Plugin, {
+ // summary:
+ // Provides context menu support, including header menu, row menu, cell menu and selected region menu
+ // example:
+ // <div dojoType="dojox.grid.EnhancedGrid"
+ // plugins="{menus:{headerMenu:"headerMenuId", rowMenu:"rowMenuId", cellMenu:"cellMenuId",
+ // selectedRegionMenu:"selectedRegionMenuId"}}" ...>
+ // </div>
+
+ //name: String
+ // Plugin name
+ name: "menus",
+
+ //name: [const] Array
+ // menu types
+ types: ['headerMenu', 'rowMenu', 'cellMenu', 'selectedRegionMenu'],
+
+ constructor: function(){
+ var g = this.grid;
+ g.showMenu = lang.hitch(g, this.showMenu);
+ g._setRowMenuAttr = lang.hitch(this, '_setRowMenuAttr');
+ g._setCellMenuAttr = lang.hitch(this, '_setCellMenuAttr');
+ g._setSelectedRegionMenuAttr = lang.hitch(this, '_setSelectedRegionMenuAttr');
+ },
+ onStartUp: function(){
+ var type, option = this.option;
+ for(type in option){
+ if(array.indexOf(this.types, type) >= 0 && option[type]){
+ this._initMenu(type, option[type]);
+ }
+ }
+ },
+ _initMenu: function(/*String*/menuType, /*String | Widget(dijit.Menu)*/menu){
+ var g = this.grid;
+ if(!g[menuType]){//in case already created in _Grid.postCreate()
+ var m = this._getMenuWidget(menu);
+ if(!m){return;}
+ g.set(menuType, m);
+ if(menuType != "headerMenu"){
+ m._scheduleOpen = function(){return;};
+ }else{
+ g.setupHeaderMenu();
+ }
+ }
+ },
+ _getMenuWidget: function(/*String|Widget(dijit.Menu)*/menu){
+ // summary:
+ // Fetch the required menu widget(should already been created)
+ return (menu instanceof dijit.Menu) ? menu : dijit.byId(menu);
+ },
+ _setRowMenuAttr: function(/*Widget(dijit.Menu)*/menu){
+ // summary:
+ // Set row menu widget
+ this._setMenuAttr(menu, 'rowMenu');
+ },
+ _setCellMenuAttr: function(/*Widget(dijit.Menu)*/menu){
+ // summary:
+ // Set cell menu widget
+ this._setMenuAttr(menu, 'cellMenu');
+ },
+ _setSelectedRegionMenuAttr: function(/*Widget(dijit.Menu)*/menu){
+ // summary:
+ // Set row menu widget
+ this._setMenuAttr(menu, 'selectedRegionMenu');
+ },
+ _setMenuAttr: function(/*Widget(dijit.Menu)*/menu, /*String*/menuType){
+ // summary:
+ // Bind menus to Grid.
+ var g = this.grid, n = g.domNode;
+ if(!menu || !(menu instanceof dijit.Menu)){
+ console.warn(menuType, " of Grid ", g.id, " is not existed!");
+ return;
+ }
+ if(g[menuType]){
+ g[menuType].unBindDomNode(n);
+ }
+ g[menuType] = menu;
+ g[menuType].bindDomNode(n);
+ },
+ showMenu: function(/*Event*/e){
+ // summary:
+ // Show appropriate context menu
+ // Fired from dojox.grid.enhanced._Events.onRowContextMenu, 'this' scope - Grid
+ // TODO: test Shift-F10
+ var inSelectedRegion = (e.cellNode && html.hasClass(e.cellNode, 'dojoxGridRowSelected') ||
+ e.rowNode && (html.hasClass(e.rowNode, 'dojoxGridRowSelected') || html.hasClass(e.rowNode, 'dojoxGridRowbarSelected')));
+
+ if(inSelectedRegion && this.selectedRegionMenu){
+ this.onSelectedRegionContextMenu(e);
+ return;
+ }
+
+ var info = {target: e.target, coords: e.keyCode !== keys.F10 && "pageX" in e ? {x: e.pageX, y: e.pageY } : null};
+ if(this.rowMenu && (!this.cellMenu || this.selection.isSelected(e.rowIndex) || e.rowNode && html.hasClass(e.rowNode, 'dojoxGridRowbar'))){
+ this.rowMenu._openMyself(info);
+ evt.stop(e);
+ return;
+ }
+
+ if(this.cellMenu){
+ this.cellMenu._openMyself(info);
+ }
+ evt.stop(e);
+ },
+ destroy: function(){
+ // summary:
+ // Destroy all resources.
+ // _Grid.destroy() will unbind headerMenu
+ var g = this.grid;
+ if(g.headerMenu){g.headerMenu.unBindDomNode(g.viewsHeaderNode);}
+ if(g.rowMenu){g.rowMenu.unBindDomNode(g.domNode);}
+ if(g.cellMenu){g.cellMenu.unBindDomNode(g.domNode);}
+ if(g.selectedRegionMenu){g.selectedRegionMenu.destroy();}
+ this.inherited(arguments);
+ }
+});
+
+EnhancedGrid.registerPlugin(Menu/*name:'menus'*/);
+
+return Menu;
+
+});
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/NestedSorting.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/NestedSorting.js
new file mode 100644
index 0000000..a27cddb
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/NestedSorting.js
@@ -0,0 +1,610 @@
+//>>built
+define("dojox/grid/enhanced/plugins/NestedSorting", [
+ "dojo/_base/declare",
+ "dojo/_base/array",
+ "dojo/_base/connect",
+ "dojo/_base/lang",
+ "dojo/_base/html",
+ "dojo/_base/event",
+ "dojo/_base/window",
+ "dojo/keys",
+ "dojo/query",
+ "dojo/string",
+ "../_Plugin",
+ "../../EnhancedGrid"
+], function(declare, array, connect, lang, html, evt, win, keys, query, string, _Plugin, EnhancedGrid){
+
+var NestedSorting = declare("dojox.grid.enhanced.plugins.NestedSorting", _Plugin, {
+ // summary:
+ // Provides nested sorting feature
+ //
+ // description:
+ // A flexible way to control multiple column sorting, including
+ // 1. Set default sorting order
+ // 2. Disable sorting for certain columns
+ // 3. Set sorting order dynamically with JS API
+ //
+ // example:
+ // | <script type="text/javascript">
+ // | var grid = new dojox.grid.EnhancedGrid({plugins : {nestedSorting: true}},
+ // | sortFields: [{attribute: 'col4', descending: false},...],//set default sorting order
+ // | canSort: function(index, field){ return true},//disable sorting for a column
+ // | ... }, dojo.byId('gridDiv'));
+ // | grid.startup();
+ // | //set new sorting order
+ // | grid.setSortIndex([{attribute: 'col3', descending: true},...])
+ // | </script>
+
+ // name: String
+ // Plugin name
+ name: "nestedSorting",
+
+ _currMainSort: 'none',//'none'|'asc'|'desc'
+
+ _currRegionIdx: -1,
+
+ _a11yText: {
+ 'dojoxGridDescending' : '&#9662;',
+ 'dojoxGridAscending' : '&#9652;',
+ 'dojoxGridAscendingTip' : '&#1784;',
+ 'dojoxGridDescendingTip': '&#1783;',
+ 'dojoxGridUnsortedTip' : 'x' //'&#10006;'
+ },
+
+ constructor: function(){
+ this._sortDef = [];
+ this._sortData = {};
+ this._headerNodes = {};
+ //column index that are hidden, un-sortable or indirect selection etc.
+ this._excludedColIdx = [];
+ this.nls = this.grid._nls;
+ this.grid.setSortInfo = function(){};
+ this.grid.setSortIndex = lang.hitch(this, '_setGridSortIndex');
+ this.grid.getSortIndex = function(){};
+ this.grid.getSortProps = lang.hitch(this, 'getSortProps');
+ if(this.grid.sortFields){
+ this._setGridSortIndex(this.grid.sortFields, null, true);
+ }
+ this.connect(this.grid.views, 'render', '_initSort');//including column resize
+ this.initCookieHandler();
+ this.subscribe("dojox/grid/rearrange/move/" + this.grid.id, lang.hitch(this, '_onColumnDnD'));
+ },
+ onStartUp: function(){
+ //overwrite base Grid functions
+ this.inherited(arguments);
+ this.connect(this.grid, 'onHeaderCellClick', '_onHeaderCellClick');
+ this.connect(this.grid, 'onHeaderCellMouseOver', '_onHeaderCellMouseOver');
+ this.connect(this.grid, 'onHeaderCellMouseOut', '_onHeaderCellMouseOut');
+ },
+ _onColumnDnD: function(type, mapping){
+ // summary:
+ // Update nested sorting after column moved
+ if(type !== 'col'){return;}
+ var m = mapping, obj = {}, d = this._sortData, p;
+ var cr = this._getCurrentRegion();
+ this._blurRegion(cr);
+ var idx = this._getRegionHeader(cr).getAttribute('idx');
+ for(p in m){
+ if(d[p]){
+ obj[m[p]] = d[p];
+ delete d[p];
+ }
+ if(p === idx){
+ idx = m[p];
+ }
+ }
+ for(p in obj){
+ d[p] = obj[p];
+ }
+ var c = this._headerNodes[idx];
+ this._currRegionIdx = array.indexOf(this._getRegions(), c.firstChild);
+ this._initSort(false);
+ },
+ _setGridSortIndex: function(inIndex, inAsc, noRefresh){
+ if(lang.isArray(inIndex)){
+ var i, d, cell;
+ for(i = 0; i < inIndex.length; i++){
+ d = inIndex[i];
+ cell = this.grid.getCellByField(d.attribute);
+ if(!cell){
+ console.warn('Invalid sorting option, column ', d.attribute, ' not found.');
+ return;
+ }
+ if(cell['nosort'] || !this.grid.canSort(cell.index, cell.field)){
+ console.warn('Invalid sorting option, column ', d.attribute, ' is unsortable.');
+ return;
+ }
+ }
+ this.clearSort();
+ array.forEach(inIndex, function(d, i){
+ cell = this.grid.getCellByField(d.attribute);
+ this.setSortData(cell.index, 'index', i);
+ this.setSortData(cell.index, 'order', d.descending ? 'desc': 'asc');
+ }, this);
+ }else if(!isNaN(inIndex)){
+ if(inAsc === undefined){ return; }//header click from base DataGrid
+ this.setSortData(inIndex, 'order', inAsc ? 'asc' : 'desc');
+ }else{
+ return;
+ }
+ this._updateSortDef();
+ if(!noRefresh){
+ this.grid.sort();
+ }
+ },
+ getSortProps: function(){
+ // summary:
+ // Overwritten, see DataGrid.getSortProps()
+ return this._sortDef.length ? this._sortDef : null;
+ },
+ _initSort: function(postSort){
+ // summary:
+ // Initiate sorting
+ var g = this.grid, n = g.domNode, len = this._sortDef.length;
+ html.toggleClass(n, 'dojoxGridSorted', !!len);
+ html.toggleClass(n, 'dojoxGridSingleSorted', len === 1);
+ html.toggleClass(n, 'dojoxGridNestSorted', len > 1);
+ if(len > 0){
+ this._currMainSort = this._sortDef[0].descending ? 'desc' : 'asc';
+ }
+ var idx, excluded = this._excludedCoIdx = [];//reset it
+ //cache column index of hidden, un-sortable or indirect selection
+ this._headerNodes = query("th", g.viewsHeaderNode).forEach(function(n){
+ idx = parseInt(n.getAttribute('idx'), 10);
+ if(html.style(n, 'display') === 'none' || g.layout.cells[idx]['nosort'] || (g.canSort && !g.canSort(idx, g.layout.cells[idx]['field']))){
+ excluded.push(idx);
+ }
+ });
+ this._headerNodes.forEach(this._initHeaderNode, this);
+ this._initFocus();
+ if(postSort){
+ this._focusHeader();
+ }
+ },
+ _initHeaderNode: function(node){
+ // summary:
+ // Initiate sort for each header cell node
+ html.toggleClass(node, 'dojoxGridSortNoWrap', true);
+ var sortNode = query('.dojoxGridSortNode', node)[0];
+ if(sortNode){
+ html.toggleClass(sortNode, 'dojoxGridSortNoWrap', true);
+ }
+ if(array.indexOf(this._excludedCoIdx, node.getAttribute('idx')) >= 0){
+ html.addClass(node, 'dojoxGridNoSort');
+ return;
+ }
+ if(!query('.dojoxGridSortBtn', node).length){
+ //clear any previous connects
+ this._connects = array.filter(this._connects, function(conn){
+ if(conn._sort){
+ connect.disconnect(conn);
+ return false;
+ }
+ return true;
+ });
+ var n = html.create('a', {
+ className: 'dojoxGridSortBtn dojoxGridSortBtnNested',
+ title: string.substitute(this.nls.sortingState, [this.nls.nestedSort, this.nls.ascending]),
+ innerHTML: '1'
+ }, node.firstChild, 'last');
+ n.onmousedown = evt.stop;
+ n = html.create('a', {
+ className: 'dojoxGridSortBtn dojoxGridSortBtnSingle',
+ title: string.substitute(this.nls.sortingState, [this.nls.singleSort, this.nls.ascending])
+ }, node.firstChild, 'last');
+ n.onmousedown = evt.stop;
+ }else{
+ //deal with small height grid which doesn't re-render the grid after refresh
+ var a1 = query('.dojoxGridSortBtnSingle', node)[0];
+ var a2 = query('.dojoxGridSortBtnNested', node)[0];
+ a1.className = 'dojoxGridSortBtn dojoxGridSortBtnSingle';
+ a2.className = 'dojoxGridSortBtn dojoxGridSortBtnNested';
+ a2.innerHTML = '1';
+ html.removeClass(node, 'dojoxGridCellShowIndex');
+ html.removeClass(node.firstChild, 'dojoxGridSortNodeSorted');
+ html.removeClass(node.firstChild, 'dojoxGridSortNodeAsc');
+ html.removeClass(node.firstChild, 'dojoxGridSortNodeDesc');
+ html.removeClass(node.firstChild, 'dojoxGridSortNodeMain');
+ html.removeClass(node.firstChild, 'dojoxGridSortNodeSub');
+ }
+ this._updateHeaderNodeUI(node);
+ },
+ _onHeaderCellClick: function(e){
+ // summary
+ // See dojox.grid.enhanced._Events._onHeaderCellClick()
+ this._focusRegion(e.target);
+ if(html.hasClass(e.target, 'dojoxGridSortBtn')){
+ this._onSortBtnClick(e);
+ evt.stop(e);
+ this._focusRegion(this._getCurrentRegion());
+ }
+ },
+ _onHeaderCellMouseOver: function(e){
+ // summary
+ // See dojox.grid._Events._onHeaderCellMouseOver()
+ // When user mouseover other columns than sorted column in a single sorted grid,
+ // We need to show 1 in the sorted column
+ if(!e.cell){return; }
+ if(this._sortDef.length > 1){ return; }
+ if(this._sortData[e.cellIndex] && this._sortData[e.cellIndex].index === 0){ return; }
+ var p;
+ for(p in this._sortData){
+ if(this._sortData[p] && this._sortData[p].index === 0){
+ html.addClass(this._headerNodes[p], 'dojoxGridCellShowIndex');
+ break;
+ }
+ }
+ if(!html.hasClass(win.body(), 'dijit_a11y')){ return; }
+ //a11y support
+ var i = e.cell.index, node = e.cellNode;
+ var singleSortBtn = query('.dojoxGridSortBtnSingle', node)[0];
+ var nestedSortBtn = query('.dojoxGridSortBtnNested', node)[0];
+
+ var sortMode = 'none';
+ if(html.hasClass(this.grid.domNode, 'dojoxGridSingleSorted')){
+ sortMode = 'single';
+ }else if(html.hasClass(this.grid.domNode, 'dojoxGridNestSorted')){
+ sortMode = 'nested';
+ }
+ var nestedIndex = nestedSortBtn.getAttribute('orderIndex');
+ if(nestedIndex === null || nestedIndex === undefined){
+ nestedSortBtn.setAttribute('orderIndex', nestedSortBtn.innerHTML);
+ nestedIndex = nestedSortBtn.innerHTML;
+ }
+ if(this.isAsc(i)){
+ nestedSortBtn.innerHTML = nestedIndex + this._a11yText.dojoxGridDescending;
+ }else if(this.isDesc(i)){
+ nestedSortBtn.innerHTML = nestedIndex + this._a11yText.dojoxGridUnsortedTip;
+ }else{
+ nestedSortBtn.innerHTML = nestedIndex + this._a11yText.dojoxGridAscending;
+ }
+ if(this._currMainSort === 'none'){
+ singleSortBtn.innerHTML = this._a11yText.dojoxGridAscending;
+ }else if(this._currMainSort === 'asc'){
+ singleSortBtn.innerHTML = this._a11yText.dojoxGridDescending;
+ }else if(this._currMainSort === 'desc'){
+ singleSortBtn.innerHTML = this._a11yText.dojoxGridUnsortedTip;
+ }
+ },
+ _onHeaderCellMouseOut: function(e){
+ // summary
+ // See dojox.grid.enhanced._Events._onHeaderCellMouseOut()
+ var p;
+ for(p in this._sortData){
+ if(this._sortData[p] && this._sortData[p].index === 0){
+ html.removeClass(this._headerNodes[p], 'dojoxGridCellShowIndex');
+ break;
+ }
+ }
+ },
+ _onSortBtnClick: function(e){
+ // summary:
+ // If the click target is single sort button, do single sort.
+ // Else if the click target is nested sort button, do nest sort.
+ // Otherwise return.
+ var cellIdx = e.cell.index;
+ if(html.hasClass(e.target, 'dojoxGridSortBtnSingle')){
+ this._prepareSingleSort(cellIdx);
+ }else if(html.hasClass(e.target, 'dojoxGridSortBtnNested')){
+ this._prepareNestedSort(cellIdx);
+ }else{
+ return;
+ }
+ evt.stop(e);
+ this._doSort(cellIdx);
+ },
+ _doSort: function(cellIdx){
+ if(!this._sortData[cellIdx] || !this._sortData[cellIdx].order){
+ this.setSortData(cellIdx, 'order', 'asc'); //no sorting data
+ }else if(this.isAsc(cellIdx)){
+ this.setSortData(cellIdx, 'order', 'desc'); //change to 'desc'
+ }else if(this.isDesc(cellIdx)){
+ this.removeSortData(cellIdx); //remove from sorting sequence
+ }
+ this._updateSortDef();
+ this.grid.sort();
+ this._initSort(true);
+ },
+ setSortData: function(cellIdx, attr, value){
+ // summary:
+ // Set sorting data for a column.
+ var sd = this._sortData[cellIdx];
+ if(!sd){
+ sd = this._sortData[cellIdx] = {};
+ }
+ sd[attr] = value;
+ },
+ removeSortData: function(cellIdx){
+ var d = this._sortData, i = d[cellIdx].index, p;
+ delete d[cellIdx];
+ for(p in d){
+ if(d[p].index > i){
+ d[p].index--;
+ }
+ }
+ },
+ _prepareSingleSort: function(cellIdx){
+ // summary:
+ // Prepare the single sort, also called main sort, this will clear any existing sorting and just sort the grid by current column.
+ var d = this._sortData, p;
+ for(p in d){
+ delete d[p];
+ }
+ this.setSortData(cellIdx, 'index', 0);
+ this.setSortData(cellIdx, 'order', this._currMainSort === 'none' ? null : this._currMainSort);
+ if(!this._sortData[cellIdx] || !this._sortData[cellIdx].order){
+ this._currMainSort = 'asc';
+ }else if(this.isAsc(cellIdx)){
+ this._currMainSort = 'desc';
+ }else if(this.isDesc(cellIdx)){
+ this._currMainSort = 'none';
+ }
+ },
+ _prepareNestedSort: function(cellIdx){
+ // summary
+ // Prepare the nested sorting, this will order the column on existing sorting result.
+ var i = this._sortData[cellIdx] ? this._sortData[cellIdx].index : null;
+ if(i === 0 || !!i){ return; }
+ this.setSortData(cellIdx, 'index', this._sortDef.length);
+ },
+ _updateSortDef: function(){
+ this._sortDef.length = 0;
+ var d = this._sortData, p;
+ for(p in d){
+ this._sortDef[d[p].index] = {
+ attribute: this.grid.layout.cells[p].field,
+ descending: d[p].order === 'desc'
+ };
+ }
+ },
+ _updateHeaderNodeUI: function(node){
+ // summary:
+ // Update the column header UI based on current sorting state.
+ // Show indicator of the sorting order of the column, no order no indicator
+ var cell = this._getCellByNode(node);
+ var cellIdx = cell.index;
+ var data = this._sortData[cellIdx];
+ var sortNode = query('.dojoxGridSortNode', node)[0];
+ var singleSortBtn = query('.dojoxGridSortBtnSingle', node)[0];
+ var nestedSortBtn = query('.dojoxGridSortBtnNested', node)[0];
+
+ html.toggleClass(singleSortBtn, 'dojoxGridSortBtnAsc', this._currMainSort === 'asc');
+ html.toggleClass(singleSortBtn, 'dojoxGridSortBtnDesc', this._currMainSort === 'desc');
+ if(this._currMainSort === 'asc'){
+ singleSortBtn.title = string.substitute(this.nls.sortingState, [this.nls.singleSort, this.nls.descending]);
+ }else if(this._currMainSort === 'desc'){
+ singleSortBtn.title = string.substitute(this.nls.sortingState, [this.nls.singleSort, this.nls.unsorted]);
+ }else{
+ singleSortBtn.title = string.substitute(this.nls.sortingState, [this.nls.singleSort, this.nls.ascending]);
+ }
+
+ var _this = this;
+ function setWaiState(){
+ var columnInfo = 'Column ' + (cell.index + 1) + ' ' + cell.field;
+ var orderState = 'none';
+ var orderAction = 'ascending';
+ if(data){
+ orderState = data.order === 'asc' ? 'ascending' : 'descending';
+ orderAction = data.order === 'asc' ? 'descending' : 'none';
+ }
+ var a11ySingleLabel = columnInfo + ' - is sorted by ' + orderState;
+ var a11yNestedLabel = columnInfo + ' - is nested sorted by ' + orderState;
+ var a11ySingleLabelHover = columnInfo + ' - choose to sort by ' + orderAction;
+ var a11yNestedLabelHover = columnInfo + ' - choose to nested sort by ' + orderAction;
+
+ singleSortBtn.setAttribute("aria-label", a11ySingleLabel);
+ nestedSortBtn.setAttribute("aria-label", a11yNestedLabel);
+
+ var handles = [
+ _this.connect(singleSortBtn, "onmouseover", function(){
+ singleSortBtn.setAttribute("aria-label", a11ySingleLabelHover);
+ }),
+ _this.connect(singleSortBtn, "onmouseout", function(){
+ singleSortBtn.setAttribute("aria-label", a11ySingleLabel);
+ }),
+ _this.connect(nestedSortBtn, "onmouseover", function(){
+ nestedSortBtn.setAttribute("aria-label", a11yNestedLabelHover);
+ }),
+ _this.connect(nestedSortBtn, "onmouseout", function(){
+ nestedSortBtn.setAttribute("aria-label", a11yNestedLabel);
+ })
+ ];
+ array.forEach(handles, function(handle){ handle._sort = true; });
+ }
+ setWaiState();
+
+ var a11y = html.hasClass(win.body(), "dijit_a11y");
+ if(!data){
+ nestedSortBtn.innerHTML = this._sortDef.length + 1;
+ nestedSortBtn.title = string.substitute(this.nls.sortingState, [this.nls.nestedSort, this.nls.ascending]);
+ if(a11y){sortNode.innerHTML = this._a11yText.dojoxGridUnsortedTip;}
+ return;
+ }
+ if(data.index || (data.index === 0 && this._sortDef.length > 1)){
+ nestedSortBtn.innerHTML = data.index + 1;
+ }
+ html.addClass(sortNode, 'dojoxGridSortNodeSorted');
+ if(this.isAsc(cellIdx)){
+ html.addClass(sortNode, 'dojoxGridSortNodeAsc');
+ nestedSortBtn.title = string.substitute(this.nls.sortingState, [this.nls.nestedSort, this.nls.descending]);
+ if(a11y){sortNode.innerHTML = this._a11yText.dojoxGridAscendingTip;}
+ }else if(this.isDesc(cellIdx)){
+ html.addClass(sortNode, 'dojoxGridSortNodeDesc');
+ nestedSortBtn.title = string.substitute(this.nls.sortingState, [this.nls.nestedSort, this.nls.unsorted]);
+ if(a11y){sortNode.innerHTML = this._a11yText.dojoxGridDescendingTip;}
+ }
+ html.addClass(sortNode, (data.index === 0 ? 'dojoxGridSortNodeMain' : 'dojoxGridSortNodeSub'));
+ },
+ isAsc: function(cellIndex){
+ return this._sortData[cellIndex].order === 'asc';
+ },
+ isDesc: function(cellIndex){
+ return this._sortData[cellIndex].order === 'desc';
+ },
+ _getCellByNode: function(node){
+ var i;
+ for(i = 0; i < this._headerNodes.length; i++){
+ if(this._headerNodes[i] === node){
+ return this.grid.layout.cells[i];
+ }
+ }
+ return null;
+ },
+ clearSort: function(){
+ this._sortData = {};
+ this._sortDef.length = 0;
+ },
+
+ //persistence
+ initCookieHandler: function(){
+ if(this.grid.addCookieHandler){
+ this.grid.addCookieHandler({
+ name: "sortOrder",
+ onLoad: lang.hitch(this, '_loadNestedSortingProps'),
+ onSave: lang.hitch(this, '_saveNestedSortingProps')
+ });
+ }
+ },
+ _loadNestedSortingProps: function(sortInfo, grid){
+ this._setGridSortIndex(sortInfo);
+ },
+ _saveNestedSortingProps: function(grid){
+ return this.getSortProps();
+ },
+
+ //focus & keyboard
+ _initFocus: function(){
+ var f = this.focus = this.grid.focus;
+ this._focusRegions = this._getRegions();
+ if(!this._headerArea){
+ var area = this._headerArea = f.getArea('header');
+ area.onFocus = f.focusHeader = lang.hitch(this, '_focusHeader');
+ area.onBlur = f.blurHeader = f._blurHeader = lang.hitch(this, '_blurHeader');
+ area.onMove = lang.hitch(this, '_onMove');
+ area.onKeyDown = lang.hitch(this, '_onKeyDown');
+ area._regions = [];
+ area.getRegions = null;
+ this.connect(this.grid, 'onBlur', '_blurHeader');
+ }
+ },
+ _focusHeader: function(e){
+ // summary:
+ // Overwritten, see _FocusManager.focusHeader()
+ //delayed: Boolean
+ // If called from "this.focus._delayedHeaderFocus()"
+ if(this._currRegionIdx === -1){
+ this._onMove(0, 1, null);
+ }else{
+ this._focusRegion(this._getCurrentRegion());
+ }
+ try{
+ evt.stop(e);
+ }catch(e){}
+ return true;
+ },
+ _blurHeader: function(e){
+ this._blurRegion(this._getCurrentRegion());
+ return true;
+ },
+ _onMove: function(rowStep, colStep, e){
+ var curr = this._currRegionIdx || 0, regions = this._focusRegions;
+ var region = regions[curr + colStep];
+ if(!region){
+ return;
+ }else if(html.style(region, 'display') === 'none' || html.style(region, 'visibility') === 'hidden'){
+ //if the region is invisible, keep finding next
+ this._onMove(rowStep, colStep + (colStep > 0 ? 1 : -1), e);
+ return;
+ }
+ this._focusRegion(region);
+ //keep grid body scrolled by header
+ var view = this._getRegionView(region);
+ view.scrollboxNode.scrollLeft = view.headerNode.scrollLeft;
+ },
+ _onKeyDown: function(e, isBubble){
+ if(isBubble){
+ switch(e.keyCode){
+ case keys.ENTER:
+ case keys.SPACE:
+ if(html.hasClass(e.target, 'dojoxGridSortBtnSingle') ||
+ html.hasClass(e.target, 'dojoxGridSortBtnNested')){
+ this._onSortBtnClick(e);
+ }
+ }
+ }
+ },
+ _getRegionView: function(region){
+ var header = region;
+ while(header && !html.hasClass(header, 'dojoxGridHeader')){ header = header.parentNode; }
+ if(header){
+ return array.filter(this.grid.views.views, function(view){
+ return view.headerNode === header;
+ })[0] || null;
+ }
+ return null;
+ },
+ _getRegions: function(){
+ var regions = [], cells = this.grid.layout.cells;
+ this._headerNodes.forEach(function(n, i){
+ if(html.style(n, 'display') === 'none'){return;}
+ if(cells[i]['isRowSelector']){
+ regions.push(n);
+ return;
+ }
+ query('.dojoxGridSortNode,.dojoxGridSortBtnNested,.dojoxGridSortBtnSingle', n).forEach(function(node){
+ node.setAttribute('tabindex', 0);
+ regions.push(node);
+ });
+ },this);
+ return regions;
+ },
+ _focusRegion: function(region){
+ // summary
+ // Focus the given region
+ if(!region){return;}
+ var currRegion = this._getCurrentRegion();
+ if(currRegion && region !== currRegion){
+ this._blurRegion(currRegion);
+ }
+ var header = this._getRegionHeader(region);
+ html.addClass(header, 'dojoxGridCellSortFocus');
+ if(html.hasClass(region, 'dojoxGridSortNode')){
+ html.addClass(region, 'dojoxGridSortNodeFocus');
+ }else if(html.hasClass(region, 'dojoxGridSortBtn')){
+ html.addClass(region, 'dojoxGridSortBtnFocus');
+ }
+ region.focus();
+ this.focus.currentArea('header');
+ this._currRegionIdx = array.indexOf(this._focusRegions, region);
+ },
+ _blurRegion: function(region){
+ if(!region){return;}
+ var header = this._getRegionHeader(region);
+ html.removeClass(header, 'dojoxGridCellSortFocus');
+ if(html.hasClass(region, 'dojoxGridSortNode')){
+ html.removeClass(region, 'dojoxGridSortNodeFocus');
+ }else if(html.hasClass(region, 'dojoxGridSortBtn')){
+ html.removeClass(region, 'dojoxGridSortBtnFocus');
+ }
+ region.blur();
+ },
+ _getCurrentRegion: function(){
+ return this._focusRegions ? this._focusRegions[this._currRegionIdx] : null;
+ },
+ _getRegionHeader: function(region){
+ while(region && !html.hasClass(region, 'dojoxGridCell')){
+ region = region.parentNode;
+ }
+ return region;
+ },
+ destroy: function(){
+ this._sortDef = this._sortData = null;
+ this._headerNodes = this._focusRegions = null;
+ this.inherited(arguments);
+ }
+});
+
+EnhancedGrid.registerPlugin(NestedSorting);
+
+return NestedSorting;
+});
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Pagination.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Pagination.js
new file mode 100644
index 0000000..244d79d
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Pagination.js
@@ -0,0 +1,974 @@
+//>>built
+require({cache:{
+'url:dojox/grid/enhanced/templates/Pagination.html':"<div dojoAttachPoint=\"paginatorBar\"\n\t><table cellpadding=\"0\" cellspacing=\"0\" class=\"dojoxGridPaginator\"\n\t\t><tr\n\t\t\t><td dojoAttachPoint=\"descriptionTd\" class=\"dojoxGridDescriptionTd\"\n\t\t\t\t><div dojoAttachPoint=\"descriptionDiv\" class=\"dojoxGridDescription\"></div\n\t\t\t></div></td\n\t\t\t><td dojoAttachPoint=\"sizeSwitchTd\"></td\n\t\t\t><td dojoAttachPoint=\"pageStepperTd\" class=\"dojoxGridPaginatorFastStep\"\n\t\t\t\t><div dojoAttachPoint=\"pageStepperDiv\" class=\"dojoxGridPaginatorStep\"></div\n\t\t\t></td\n\t\t\t><td dojoAttachPoint=\"gotoPageTd\" class=\"dojoxGridPaginatorGotoTd\"\n\t\t\t\t><div dojoAttachPoint=\"gotoPageDiv\" class=\"dojoxGridPaginatorGotoDiv\" dojoAttachEvent=\"onclick:_openGotopageDialog, onkeydown:_openGotopageDialog\"\n\t\t\t\t\t><span class=\"dojoxGridWardButtonInner\">&#8869;</span\n\t\t\t\t></div\n\t\t\t></td\n\t\t></tr\n\t></table\n></div>\n"}});
+define("dojox/grid/enhanced/plugins/Pagination", [
+ "dojo/_base/kernel",
+ "dojo/_base/declare",
+ "dojo/_base/array",
+ "dojo/_base/connect",
+ "dojo/_base/lang",
+ "dojo/_base/html",
+ "dojo/_base/event",
+ "dojo/_base/window",
+ "dojo/query",
+ "dojo/string",
+ "dojo/i18n",
+ "dojo/keys",
+ "dojo/text!../templates/Pagination.html",
+ "./Dialog",
+ "./_StoreLayer",
+ "../_Plugin",
+ "../../EnhancedGrid",
+ "dijit/form/Button",
+ "dijit/form/NumberTextBox",
+ "dijit/focus",
+ "dijit/_Widget",
+ "dijit/_TemplatedMixin",
+ "dijit/_WidgetsInTemplateMixin",
+ "dojox/html/metrics",
+ "dojo/i18n!../nls/Pagination"
+], function(kernel, declare, array, connect, lang, html, event, win, query,
+ string, i18n, keys, template, Dialog, layers, _Plugin, EnhancedGrid,
+ Button, NumberTextBox, dijitFocus, _Widget, _TemplatedMixin, _WidgetsInTemplateMixin, metrics){
+
+var _GotoPagePane = declare("dojox.grid.enhanced.plugins.pagination._GotoPagePane", [_Widget, _TemplatedMixin, _WidgetsInTemplateMixin], {
+ templateString: "<div>" +
+ "<div class='dojoxGridDialogMargin' dojoAttachPoint='_mainMsgNode'></div>" +
+ "<div class='dojoxGridDialogMargin'>" +
+ "<input dojoType='dijit.form.NumberTextBox' style='width: 50px;' dojoAttachPoint='_pageInputBox' dojoAttachEvent='onKeyUp: _onKey'></input>" +
+ "<label dojoAttachPoint='_pageLabelNode'></label>" +
+ "</div>" +
+ "<div class='dojoxGridDialogButton'>" +
+ "<button dojoType='dijit.form.Button' dojoAttachPoint='_confirmBtn' dojoAttachEvent='onClick: _onConfirm'></button>" +
+ "<button dojoType='dijit.form.Button' dojoAttachPoint='_cancelBtn' dojoAttachEvent='onClick: _onCancel'></button>" +
+ "</div>" +
+ "</div>",
+ widgetsInTemplate: true,
+ dlg: null,
+ postMixInProperties: function(){
+ this.plugin = this.dlg.plugin;
+ },
+ postCreate: function(){
+ this.inherited(arguments);
+ this._mainMsgNode.innerHTML = this.plugin._nls[12];
+ this._confirmBtn.set("label", this.plugin._nls[14]);
+ this._confirmBtn.set("disabled", true);
+ this._cancelBtn.set("label", this.plugin._nls[15]);
+ },
+ _onConfirm: function(evt){
+ if(this._pageInputBox.isValid() && this._pageInputBox.getDisplayedValue() !== ""){
+ this.plugin.currentPage(this._pageInputBox.parse(this._pageInputBox.getDisplayedValue()));
+ this.dlg._gotoPageDialog.hide();
+ this._pageInputBox.reset();
+ }
+ stopEvent(evt);
+ },
+ _onCancel: function(evt){
+ this._pageInputBox.reset();
+ this.dlg._gotoPageDialog.hide();
+ stopEvent(evt);
+ },
+ _onKey: function(evt){
+ this._confirmBtn.set("disabled", !this._pageInputBox.isValid() || this._pageInputBox.getDisplayedValue() == "");
+ if(!evt.altKey && !evt.metaKey && evt.keyCode === keys.ENTER){
+ this._onConfirm(evt);
+ }
+ }
+});
+
+var _GotoPageDialog = declare("dojox.grid.enhanced.plugins.pagination._GotoPageDialog", null, {
+ pageCount: 0,
+ dlgPane: null,
+ constructor: function(plugin){
+ this.plugin = plugin;
+ this.dlgPane = new _GotoPagePane({"dlg": this});
+ this.dlgPane.startup();
+ this._gotoPageDialog = new Dialog({
+ "refNode": plugin.grid.domNode,
+ "title": this.plugin._nls[11],
+ "content": this.dlgPane
+ });
+ this._gotoPageDialog.startup();
+ },
+ _updatePageCount: function(){
+ this.pageCount = this.plugin.getTotalPageNum();
+ this.dlgPane._pageInputBox.constraints = {fractional:false, min:1, max:this.pageCount};
+ this.dlgPane._pageLabelNode.innerHTML = string.substitute(this.plugin._nls[13], [this.pageCount]);
+ },
+ showDialog: function(){
+ this._updatePageCount();
+ this._gotoPageDialog.show();
+ },
+ destroy: function(){
+ this._gotoPageDialog.destroy();
+ }
+});
+
+var _ForcedPageStoreLayer = declare("dojox.grid.enhanced.plugins._ForcedPageStoreLayer", layers._StoreLayer, {
+ tags: ["presentation"],
+ constructor: function(plugin){
+ this._plugin = plugin;
+ },
+ _fetch: function(request){
+ var _this = this,
+ plugin = _this._plugin,
+ grid = plugin.grid,
+ scope = request.scope || win.global,
+ onBegin = request.onBegin;
+ request.start = (plugin._currentPage - 1) * plugin._currentPageSize + request.start;
+ _this.startIdx = request.start;
+ _this.endIdx = request.start + plugin._currentPageSize - 1;
+ var p = plugin._paginator;
+ if(!plugin._showAll){
+ plugin._showAll = !p.sizeSwitch && !p.pageStepper && !p.gotoButton;
+ }
+ if(onBegin && plugin._showAll){
+ request.onBegin = function(size, req){
+ plugin._maxSize = plugin._currentPageSize = size;
+ _this.startIdx = 0;
+ _this.endIdx = size - 1;
+ plugin._paginator._update();
+ req.onBegin = onBegin;
+ req.onBegin.call(scope, size, req);
+ };
+ }else if(onBegin){
+ request.onBegin = function(size, req){
+ req.start = 0;
+ req.count = plugin._currentPageSize;
+ plugin._maxSize = size;
+ _this.endIdx = _this.endIdx >= size ? (size - 1) : _this.endIdx;
+ if(_this.startIdx > size && size !== 0){
+ grid._pending_requests[req.start] = false;
+ plugin.firstPage();
+ }
+ plugin._paginator._update();
+ req.onBegin = onBegin;
+ req.onBegin.call(scope, Math.min(plugin._currentPageSize, (size - _this.startIdx)), req);
+ };
+ }
+ return lang.hitch(this._store, this._originFetch)(request);
+ }
+});
+
+var stopEvent = function(evt){
+ try{
+ event.stop(evt);
+ }catch(e){}
+};
+
+var _Focus = declare("dojox.grid.enhanced.plugins.pagination._Focus", null, {
+ _focusedNode: null,
+ _isFocused: false,
+ constructor: function(paginator){
+ this._pager = paginator;
+ var focusMgr = paginator.plugin.grid.focus;
+ paginator.plugin.connect(paginator, 'onSwitchPageSize', lang.hitch(this, '_onActive'));
+ paginator.plugin.connect(paginator, 'onPageStep', lang.hitch(this, '_onActive'));
+ paginator.plugin.connect(paginator, 'onShowGotoPageDialog', lang.hitch(this, '_onActive'));
+ paginator.plugin.connect(paginator, '_update', lang.hitch(this, '_moveFocus'));
+ },
+ _onFocus: function(evt, step){
+ var node, nodes;
+ if(!this._isFocused){
+ node = this._focusedNode || query('[tabindex]', this._pager.domNode)[0];
+ }else if(step && this._focusedNode){
+ var dir = step > 0 ? -1 : 1,
+ tabindex = parseInt(this._focusedNode.getAttribute('tabindex'), 10) + dir;
+ while(tabindex >= -3 && tabindex < 0){
+ node = query('[tabindex=' + tabindex + ']', this._pager.domNode)[0];
+ if(node){
+ break;
+ }else{
+ tabindex += dir;
+ }
+ }
+ }
+ return this._focus(node, evt);
+ },
+ _onBlur: function(evt, step){
+ if(!step || !this._focusedNode){
+ this._isFocused = false;
+ if(this._focusedNode && html.hasClass(this._focusedNode, 'dojoxGridButtonFocus')){
+ html.removeClass(this._focusedNode, 'dojoxGridButtonFocus');
+ }
+ return true;
+ }
+ var node, dir = step > 0 ? -1 : 1,
+ tabindex = parseInt(this._focusedNode.getAttribute('tabindex'), 10) + dir;
+ while(tabindex >= -3 && tabindex < 0){
+ node = query('[tabindex=' + tabindex + ']', this._pager.domNode)[0];
+ if(node){
+ break;
+ }else{
+ tabindex += dir;
+ }
+ }
+ if(!node){
+ this._isFocused = false;
+ if(html.hasClass(this._focusedNode, 'dojoxGridButtonFocus')){
+ html.removeClass(this._focusedNode, 'dojoxGridButtonFocus');
+ }
+ }
+ return node ? false : true;
+ },
+ _onMove: function(rowDelta, colDelta, evt){
+ if(this._focusedNode){
+ var tabindex = this._focusedNode.getAttribute('tabindex'),
+ delta = colDelta == 1 ? "nextSibling" : "previousSibling",
+ node = this._focusedNode[delta];
+ while(node){
+ if(node.getAttribute('tabindex') == tabindex){
+ this._focus(node);
+ break;
+ }
+ node = node[delta];
+ }
+ }
+ },
+ _focus: function(node, evt){
+ if(node){
+ this._isFocused = true;
+ if(kernel.isIE && this._focusedNode){
+ html.removeClass(this._focusedNode, 'dojoxGridButtonFocus');
+ }
+ this._focusedNode = node;
+ node.focus();
+ if(kernel.isIE){
+ html.addClass(node, 'dojoxGridButtonFocus');
+ }
+ stopEvent(evt);
+ return true;
+ }
+ return false;
+ },
+ _onActive: function(e){
+ this._focusedNode = e.target;
+ if(!this._isFocused){
+ this._pager.plugin.grid.focus.focusArea('pagination' + this._pager.position);
+ }
+ },
+ _moveFocus: function(){
+ if(this._focusedNode && !this._focusedNode.getAttribute('tabindex')){
+ var next = this._focusedNode.nextSibling;
+ while(next){
+ if(next.getAttribute('tabindex')){
+ this._focus(next);
+ return;
+ }
+ next = next.nextSibling;
+ }
+ var prev = this._focusedNode.previousSibling;
+ while(prev){
+ if(prev.getAttribute('tabindex')){
+ this._focus(prev);
+ return;
+ }
+ prev = prev.previousSibling;
+ }
+ this._focusedNode = null;
+ this._onBlur();
+ }else if(kernel.isIE && this._focusedNode){
+ html.addClass(this._focusedNode, 'dojoxGridButtonFocus');
+ }
+ }
+});
+
+var _Paginator = declare("dojox.grid.enhanced.plugins._Paginator", [_Widget, _TemplatedMixin], {
+ templateString: template,
+ constructor: function(params){
+ lang.mixin(this, params);
+ this.grid = this.plugin.grid;
+ },
+ postCreate: function(){
+ this.inherited(arguments);
+ var _this = this, g = this.grid;
+ this.plugin.connect(g, "_resize", lang.hitch(this, "_resetGridHeight"));
+ this._originalResize = g.resize;
+ g.resize = function(changeSize, resultSize){
+ _this._changeSize = changeSize;
+ _this._resultSize = resultSize;
+ _this._originalResize.apply(g, arguments);
+ };
+ this.focus = _Focus(this);
+ this._placeSelf();
+ },
+ destroy: function(){
+ this.inherited(arguments);
+ this.grid.focus.removeArea("pagination" + this.position);
+ if(this._gotoPageDialog){
+ this._gotoPageDialog.destroy();
+ }
+ this.grid.resize = this._originalResize;
+ },
+ onSwitchPageSize: function(/*Event*/evt){
+
+ },
+ onPageStep: function(/*Event*/evt){
+
+ },
+ onShowGotoPageDialog: function(/*Event*/evt){
+
+ },
+ _update: function(){
+ // summary:
+ // Function to update paging information and update
+ // pagination bar display.
+ this._updateDescription();
+ this._updatePageStepper();
+ this._updateSizeSwitch();
+ this._updateGotoButton();
+ },
+ _registerFocus: function(isTop){
+ // summary:
+ // Function to register pagination bar to focus manager.
+ var focusMgr = this.grid.focus,
+ name = "pagination" + this.position,
+ f = this.focus;
+ focusMgr.addArea({
+ name: name,
+ onFocus: lang.hitch(this.focus, "_onFocus"),
+ onBlur: lang.hitch(this.focus, "_onBlur"),
+ onMove: lang.hitch(this.focus, "_onMove")
+ });
+ focusMgr.placeArea(name, isTop ? "before" : "after", isTop ? "header" : "content");
+ },
+ _placeSelf: function(){
+ // summary:
+ // Place pagination bar to a position.
+ // There are two options, top of the grid, bottom of the grid.
+ var g = this.grid,
+ isTop = this.position == "top";
+ this.placeAt(isTop ? g.viewsHeaderNode : g.viewsNode, isTop ? "before" : "after");
+ this._registerFocus(isTop);
+ },
+ _resetGridHeight: function(changeSize, resultSize){
+ // summary:
+ // Function of resize grid height to place this pagination bar.
+ // Since the grid would be able to add other element in its domNode, we have
+ // change the grid view size to place the pagination bar.
+ // This function will resize the grid viewsNode height, scorllboxNode height
+ var g = this.grid;
+ changeSize = changeSize || this._changeSize;
+ resultSize = resultSize || this._resultSize;
+ delete this._changeSize;
+ delete this._resultSize;
+ if(g._autoHeight){
+ return;
+ }
+ var padBorder = g._getPadBorder().h;
+ if(!this.plugin.gh){
+ this.plugin.gh = html.contentBox(g.domNode).h + 2 * padBorder;
+ }
+ if(resultSize){
+ changeSize = resultSize;
+ }
+ if(changeSize){
+ this.plugin.gh = html.contentBox(g.domNode).h + 2 * padBorder;
+ }
+ var gh = this.plugin.gh,
+ hh = g._getHeaderHeight(),
+ ph = html.marginBox(this.domNode).h;
+ // ph = this.plugin._paginator.position == "bottom" ? ph * 2 : ph;
+ if(typeof g.autoHeight === "number"){
+ var cgh = gh + ph - padBorder;
+ html.style(g.domNode, "height", cgh + "px");
+ html.style(g.viewsNode, "height", (cgh - ph - hh) + "px");
+ this._styleMsgNode(hh, html.marginBox(g.viewsNode).w, cgh - ph - hh);
+ }else{
+ var h = gh - ph - hh - padBorder;
+ html.style(g.viewsNode, "height", h + "px");
+ var hasHScroller = array.some(g.views.views, function(v){
+ return v.hasHScrollbar();
+ });
+ array.forEach(g.viewsNode.childNodes, function(c){
+ html.style(c, "height", h + "px");
+ });
+ array.forEach(g.views.views, function(v){
+ if(v.scrollboxNode){
+ if(!v.hasHScrollbar() && hasHScroller){
+ html.style(v.scrollboxNode, "height", (h - metrics.getScrollbar().h) + "px");
+ }else{
+ html.style(v.scrollboxNode, "height", h + "px");
+ }
+ }
+ });
+ this._styleMsgNode(hh, html.marginBox(g.viewsNode).w, h);
+ }
+ },
+ _styleMsgNode: function(top, width, height){
+ var messagesNode = this.grid.messagesNode;
+ html.style(messagesNode, {"position": "absolute", "top": top + "px", "width": width + "px", "height": height + "px", "z-Index": "100"});
+ },
+ _updateDescription: function(){
+ // summary:
+ // Update size information.
+ var s = this.plugin.forcePageStoreLayer,
+ maxSize = this.plugin._maxSize,
+ nls = this.plugin._nls,
+ getItemTitle = function(){
+ return maxSize <= 0 || maxSize == 1 ? nls[5] : nls[4];
+ };
+ if(this.description && this.descriptionDiv){
+ this.descriptionDiv.innerHTML = maxSize > 0 ? string.substitute(nls[0], [getItemTitle(), maxSize, s.startIdx + 1, s.endIdx + 1]) : "0 " + getItemTitle();
+ }
+ },
+ _updateSizeSwitch: function(){
+ // summary:
+ // Update "items per page" information.
+ html.style(this.sizeSwitchTd, "display", this.sizeSwitch ? "" : "none");
+ if(!this.sizeSwitch){
+ return;
+ }
+ if(this.sizeSwitchTd.childNodes.length < 1){
+ this._createSizeSwitchNodes();
+ }
+ this._updateSwitchNodesStyle();
+ },
+ _createSizeSwitchNodes: function(){
+ // summary:
+ // The function to create the size switch nodes
+ var node = null,
+ nls = this.plugin._nls,
+ connect = lang.hitch(this.plugin, 'connect');
+ array.forEach(this.pageSizes, function(size){
+ // create page size switch node
+ var labelValue = isFinite(size) ? string.substitute(nls[2], [size]) : nls[1],
+ value = isFinite(size) ? size : nls[16];
+ node = html.create("span", {innerHTML: value, title: labelValue, value: size, tabindex: "-1"}, this.sizeSwitchTd, "last");
+ // for accessibility
+ node.setAttribute("aria-label", labelValue);
+ // connect event
+ connect(node, "onclick", lang.hitch(this, "_onSwitchPageSize"));
+ connect(node, "onkeydown", lang.hitch(this, "_onSwitchPageSize"));
+ connect(node, "onmouseover", function(e){
+ html.addClass(e.target, "dojoxGridPageTextHover");
+ });
+ connect(node, "onmouseout", function(e){
+ html.removeClass(e.target, "dojoxGridPageTextHover");
+ });
+ // create a separation node
+ node = html.create("span", {innerHTML: "|"}, this.sizeSwitchTd, "last");
+ html.addClass(node, "dojoxGridSeparator");
+ }, this);
+ // delete last separation node
+ html.destroy(node);
+ },
+ _updateSwitchNodesStyle: function(){
+ // summary:
+ // Update the switch nodes style
+ var size = null;
+ var styleNode = function(node, status){
+ if(status){
+ html.addClass(node, "dojoxGridActivedSwitch");
+ html.removeAttr(node, "tabindex");
+ }else{
+ html.addClass(node, "dojoxGridInactiveSwitch");
+ node.setAttribute("tabindex", "-1");
+ }
+ };
+ array.forEach(this.sizeSwitchTd.childNodes, function(node){
+ if(node.value){
+ html.removeClass(node);
+ size = node.value;
+ if(this.plugin._showAll){
+ styleNode(node, isNaN(parseInt(size, 10)));
+ }else{
+ styleNode(node, this.plugin._currentPageSize == size);
+ }
+ }
+ }, this);
+ },
+ _updatePageStepper: function(){
+ // summary:
+ // Update the page step nodes
+ html.style(this.pageStepperTd, "display", this.pageStepper ? "" : "none");
+ if(!this.pageStepper){
+ return;
+ }
+ if(this.pageStepperDiv.childNodes.length < 1){
+ this._createPageStepNodes();
+ this._createWardBtns();
+ }else{
+ this._resetPageStepNodes();
+ }
+ this._updatePageStepNodesStyle();
+ },
+ _createPageStepNodes: function(){
+ // summary:
+ // Create the page step nodes if they do not exist
+ var startPage = this._getStartPage(),
+ stepSize = this._getStepPageSize(),
+ label = "", node = null, i = startPage,
+ connect = lang.hitch(this.plugin, 'connect');
+ for(; i < startPage + this.maxPageStep + 1; i++){
+ label = string.substitute(this.plugin._nls[3], [i]);
+ node = html.create("div", {innerHTML: i, value: i, title: label}, this.pageStepperDiv, "last");
+ node.setAttribute("aria-label", label);
+ // connect event
+ connect(node, "onclick", lang.hitch(this, "_onPageStep"));
+ connect(node, "onkeydown", lang.hitch(this, "_onPageStep"));
+ connect(node, "onmouseover", function(e){
+ html.addClass(e.target, "dojoxGridPageTextHover");
+ });
+ connect(node, "onmouseout", function(e){
+ html.removeClass(e.target, "dojoxGridPageTextHover");
+ });
+ html.style(node, "display", i < startPage + stepSize ? "" : "none");
+ }
+ },
+ _createWardBtns: function(){
+ // summary:
+ // Create the previous/next/first/last button
+ var _this = this, nls = this.plugin._nls;
+ var highContrastLabel = {prevPage: "&#60;", firstPage: "&#171;", nextPage: "&#62;", lastPage: "&#187;"};
+ var createWardBtn = function(value, label, position){
+ var node = html.create("div", {value: value, title: label, tabindex: "-2"}, _this.pageStepperDiv, position);
+ _this.plugin.connect(node, "onclick", lang.hitch(_this, "_onPageStep"));
+ _this.plugin.connect(node, "onkeydown", lang.hitch(_this, "_onPageStep"));
+ node.setAttribute("aria-label", label);
+ // for high contrast
+ var highConrastNode = html.create("span", {value: value, title: label, innerHTML: highContrastLabel[value]}, node, position);
+ html.addClass(highConrastNode, "dojoxGridWardButtonInner");
+ };
+ createWardBtn("prevPage", nls[6], "first");
+ createWardBtn("firstPage", nls[7], "first");
+ createWardBtn("nextPage", nls[8], "last");
+ createWardBtn("lastPage", nls[9], "last");
+ },
+ _resetPageStepNodes: function(){
+ // summary:
+ // The page step nodes might be changed when fetch data, we need to
+ // update/reset them
+ var startPage = this._getStartPage(),
+ stepSize = this._getStepPageSize(),
+ stepNodes = this.pageStepperDiv.childNodes,
+ node = null, i = startPage, j = 2, tip;
+ for(; j < stepNodes.length - 2; j++, i++){
+ node = stepNodes[j];
+ if(i < startPage + stepSize){
+ tip = string.substitute(this.plugin._nls[3], [i]);
+ html.attr(node, {
+ "innerHTML": i,
+ "title": tip,
+ "value": i
+ });
+ html.style(node, "display", "");
+ node.setAttribute("aria-label", tip);
+ }else{
+ html.style(node, "display", "none");
+ }
+ }
+ },
+ _updatePageStepNodesStyle: function(){
+ // summary:
+ // Update the style of the page step nodes
+ var value = null,
+ curPage = this.plugin.currentPage(),
+ pageCount = this.plugin.getTotalPageNum();
+ var updateClass = function(node, isWardBtn, status){
+ var value = node.value,
+ enableClass = isWardBtn ? "dojoxGrid" + value + "Btn" : "dojoxGridInactived",
+ disableClass = isWardBtn ? "dojoxGrid" + value + "BtnDisable" : "dojoxGridActived";
+ if(status){
+ html.addClass(node, disableClass);
+ html.removeAttr(node, "tabindex");
+ }else{
+ html.addClass(node, enableClass);
+ node.setAttribute("tabindex", "-2");
+ }
+ };
+ array.forEach(this.pageStepperDiv.childNodes, function(node){
+ html.removeClass(node);
+ if(isNaN(parseInt(node.value, 10))){
+ html.addClass(node, "dojoxGridWardButton");
+ var disablePageNum = node.value == "prevPage" || node.value == "firstPage" ? 1 : pageCount;
+ updateClass(node, true, (curPage === disablePageNum));
+ }else{
+ value = parseInt(node.value, 10);
+ updateClass(node, false, (value === curPage || html.style(node, "display") === "none"));
+ }
+ }, this);
+ },
+ _showGotoButton: function(flag){
+ this.gotoButton = flag;
+ this._updateGotoButton();
+ },
+ _updateGotoButton: function(){
+ // summary:
+ // Create/destroy the goto page button
+ if(!this.gotoButton){
+ if(this._gotoPageDialog){
+ this._gotoPageDialog.destroy();
+ }
+ html.removeAttr(this.gotoPageDiv, "tabindex");
+ html.style(this.gotoPageTd, 'display', 'none');
+ return;
+ }
+ if(html.style(this.gotoPageTd, 'display') == 'none'){
+ html.style(this.gotoPageTd, 'display', '');
+ }
+ this.gotoPageDiv.setAttribute('title', this.plugin._nls[10]);
+ html.toggleClass(this.gotoPageDiv, "dojoxGridPaginatorGotoDivDisabled", this.plugin.getTotalPageNum() <= 1);
+ if(this.plugin.getTotalPageNum() <= 1){
+ html.removeAttr(this.gotoPageDiv, "tabindex");
+ }else{
+ this.gotoPageDiv.setAttribute("tabindex", "-3");
+ }
+ },
+ _openGotopageDialog: function(e){
+ // summary:
+ // Show the goto page dialog
+ if(this.plugin.getTotalPageNum() <= 1){
+ return;
+ }
+ if(e.type === "keydown" && e.keyCode !== keys.ENTER && e.keyCode !== keys.SPACE){
+ return;
+ }
+ if(!this._gotoPageDialog){
+ this._gotoPageDialog = new _GotoPageDialog(this.plugin);
+ }
+ this._gotoPageDialog.showDialog();
+ this.onShowGotoPageDialog(e);
+ },
+ _onSwitchPageSize: function(/*Event*/e){
+ // summary:
+ // The handler of switch the page size
+ if(e.type === "keydown" && e.keyCode !== keys.ENTER && e.keyCode !== keys.SPACE){
+ return;
+ }
+ this.onSwitchPageSize(e);
+ this.plugin.currentPageSize(e.target.value);
+ },
+ _onPageStep: function(/*Event*/e){
+ // summary:
+ // The handler jump page event
+ if(e.type === "keydown" && e.keyCode !== keys.ENTER && e.keyCode !== keys.SPACE){
+ return;
+ }
+ var p = this.plugin,
+ value = e.target.value;
+ this.onPageStep(e);
+ if(!isNaN(parseInt(value, 10))){
+ p.currentPage(parseInt(value, 10));
+ }else{
+ p[value]();
+ }
+ },
+ _getStartPage: function(){
+ var cp = this.plugin.currentPage(),
+ ms = this.maxPageStep,
+ hs = parseInt(ms / 2, 10),
+ tp = this.plugin.getTotalPageNum();
+ if(cp < hs || (cp - hs) < 1 || tp <= ms){
+ return 1;
+ }else{
+ return tp - cp < hs && cp - ms >= 0 ? tp - ms + 1 : cp - hs;
+ }
+ },
+ _getStepPageSize: function(){
+ var sp = this._getStartPage(),
+ tp = this.plugin.getTotalPageNum(),
+ ms = this.maxPageStep;
+ return sp + ms > tp ? tp - sp + 1 : ms;
+ }
+});
+
+var Pagination = declare("dojox.grid.enhanced.plugins.Pagination", _Plugin, {
+ // summary:
+ // The typical pagination way to deal with huge dataset
+ // an alternative for the default virtual scrolling manner.
+ name: "pagination",
+ // defaultPageSize: Integer
+ // Number of rows in a page, 25 by default.
+ defaultPageSize: 25,
+ // defaultPage: Integer
+ // Which page will be displayed initially, 1st page by default.
+ defaultPage: 1,
+ // description: boolean
+ // Whether the description information will be displayed, true by default.
+ description: true,
+ // sizeSwitch: boolean
+ // Whether the page size switch options will be displayed, true by default.
+ sizeSwitch: true,
+ // pageStepper: boolean
+ // Whether the page switch options will be displayed, true by default.
+ pageStepper: true,
+ // gotoButton: boolean
+ // Whether the goto page button will be displayed, false by default.
+ gotoButton: false,
+ // pageSizes: Array
+ // Array of page sizes for switching, e.g. [10, 25, 50, 100, Infinity] by default,
+ // Infinity or any NaN value will be treated as "all".
+ pageSizes: [10, 25, 50, 100, Infinity],
+ // maxPageStep: Integer
+ // The max number of page sizes to be displayed, 7 by default.
+ maxPageStep: 7,
+ // position: string
+ // The position of the pagination bar - "top"|"bottom", "bottom" by default.
+ position: 'bottom',
+
+ init: function(){
+ var g = this.grid;
+ g.usingPagination = true;
+ this._initOptions();
+ this._currentPage = this.defaultPage;
+ this._currentPageSize = this.grid.rowsPerPage = this.defaultPageSize;
+ // wrap store layer
+ this._store = g.store;
+ this.forcePageStoreLayer = new _ForcedPageStoreLayer(this);
+ layers.wrap(g, "_storeLayerFetch", this.forcePageStoreLayer);
+ // create pagination bar
+ this._paginator = this.option.position != "top" ?
+ new _Paginator(lang.mixin(this.option, {position: "bottom", plugin: this})) :
+ new _Paginator(lang.mixin(this.option, {position: "top", plugin: this}));
+ this._regApis();
+ },
+ destroy: function(){
+ this.inherited(arguments);
+ this._paginator.destroy();
+ var g = this.grid;
+ g.unwrap(this.forcePageStoreLayer.name());
+ g.scrollToRow = this._gridOriginalfuncs[0];
+ g._onNew = this._gridOriginalfuncs[1];
+ g.removeSelectedRows = this._gridOriginalfuncs[2];
+ this._paginator = null;
+ this._nls = null;
+ },
+ currentPage: function(page){
+ // summary:
+ // Shift to the given page, return current page number. If there
+ // is no valid page was passed in, just return current page num.
+ // page: Integer
+ // The page to go to, starting at 1.
+ // return:
+ // Current page number
+ if(page <= this.getTotalPageNum() && page > 0 && this._currentPage !== page){
+ this._currentPage = page;
+ this.grid._refresh(true);
+ this.grid.resize();
+ }
+ return this._currentPage;
+ },
+ nextPage: function(){
+ // summary:
+ // Go to the next page.
+ this.currentPage(this._currentPage + 1);
+ },
+ prevPage: function(){
+ // summary:
+ // Go to the previous page.
+ this.currentPage(this._currentPage - 1);
+ },
+ firstPage: function(){
+ // summary:
+ // Go to the first page
+ this.currentPage(1);
+ },
+ lastPage: function(){
+ // summary:
+ // Go to the last page
+ this.currentPage(this.getTotalPageNum());
+ },
+ currentPageSize: function(size){
+ // summary:
+ // Change the size of current page or return the current page size.
+ // size: Integer || null
+ // An integer identifying the number of rows per page. If the size
+ // is an Infinity, all rows will be displayed; if an invalid value pssed
+ // in, the current page size will be returned.
+ // return
+ // Current size of items per page.
+ if(!isNaN(size)){
+ var g = this.grid,
+ startIndex = this._currentPageSize * (this._currentPage - 1), endIndex;
+ this._showAll = !isFinite(size);
+ this.grid.usingPagination = !this._showAll;
+ this._currentPageSize = this._showAll ? this._maxSize : size;
+ g.rowsPerPage = this._showAll ? this._defaultRowsPerPage : size;
+ endIndex = startIndex + Math.min(this._currentPageSize, this._maxSize);
+ if(endIndex > this._maxSize){
+ this.lastPage();
+ }else{
+ var cp = Math.ceil(startIndex / this._currentPageSize) + 1;
+ if(cp !== this._currentPage){
+ this.currentPage(cp);
+ }else{
+ this.grid._refresh(true);
+ }
+ }
+ this.grid.resize();
+ }
+ return this._currentPageSize;
+ },
+ getTotalPageNum: function(){
+ // summary:
+ // Get total page number
+ return Math.ceil(this._maxSize / this._currentPageSize);
+ },
+ getTotalRowCount: function(){
+ // summary:
+ // Function for get total row count
+ return this._maxSize;
+ },
+ scrollToRow: function(inRowIndex){
+ // summary:
+ // Override the grid.scrollToRow(), could jump to the right page
+ // and scroll to the specific row
+ // inRowIndex: integer
+ // The row index
+ var page = parseInt(inRowIndex / this._currentPageSize, 10) + 1;
+ if(page > this.getTotalPageNum()){
+ return;
+ }
+ this.currentPage(page);
+ var rowIdx = inRowIndex % this._currentPageSize;
+ return this._gridOriginalfuncs[0](rowIdx);
+ },
+ removeSelectedRows: function(){
+ this._multiRemoving = true;
+ this._gridOriginalfuncs[2].apply();
+ this._multiRemoving = false;
+ this.grid.resize();
+ this.grid._refresh();
+ },
+ showGotoPageButton: function(flag){
+ // summary:
+ // For show/hide the go to page button dynamically
+ // flag: boolean
+ // Show the go to page button when flag is true, otherwise hide it
+ this._paginator.gotoButton = flag;
+ this._paginator._updateGotoButton();
+ },
+ // [DEPRECATED] ============
+ gotoPage: function(page){
+ kernel.deprecated("dojox.grid.enhanced.EnhancedGrid.gotoPage(page)", "use dojox.grid.enhanced.EnhancedGrid.currentPage(page) instead", "1.8");
+ this.currentPage(page);
+ },
+ gotoFirstPage: function(){
+ kernel.deprecated("dojox.grid.enhanced.EnhancedGrid.gotoFirstPage()", "use dojox.grid.enhanced.EnhancedGrid.firstPage() instead", "1.8");
+ this.firstPage();
+ },
+ gotoLastPage: function(){
+ kernel.deprecated("dojox.grid.enhanced.EnhancedGrid.gotoLastPage()", "use dojox.grid.enhanced.EnhancedGrid.lastPage() instead", "1.8");
+ this.lastPage();
+ },
+ changePageSize: function(size){
+ kernel.deprecated("dojox.grid.enhanced.EnhancedGrid.changePageSize(size)", "use dojox.grid.enhanced.EnhancedGrid.currentPageSize(size) instead", "1.8");
+ this.currentPageSize(size);
+ },
+ // =============== Protected ================
+ _nls: null,
+ _showAll: false,
+ _maxSize: 0,
+ // =============== Private ===============
+ _defaultRowsPerPage: 25,
+ _currentPage: 1,
+ _currentPageSize: 25,
+
+ _initOptions: function(){
+ this._defaultRowsPerPage = this.grid.rowsPerPage || 25;
+ this.defaultPage = this.option.defaultPage >= 1 ? parseInt(this.option.defaultPage, 10) : 1;
+ this.option.description = this.option.description !== undefined ? !!this.option.description : this.description;
+ this.option.sizeSwitch = this.option.sizeSwitch !== undefined ? !!this.option.sizeSwitch : this.sizeSwitch;
+ this.option.pageStepper = this.option.pageStepper !== undefined ? !!this.option.pageStepper : this.pageStepper;
+ this.option.gotoButton = this.option.gotoButton !== undefined ? !!this.option.gotoButton : this.gotoButton;
+ if(lang.isArray(this.option.pageSizes)){
+ var pageSizes = [];
+ array.forEach(this.option.pageSizes, function(size){
+ size = typeof size == 'number' ? size : parseInt(size, 10);
+ if(!isNaN(size) && size > 0){
+ pageSizes.push(size);
+ }else if(array.indexOf(pageSizes, Infinity) < 0){
+ pageSizes.push(Infinity);
+ }
+ }, this);
+ this.option.pageSizes = pageSizes.sort(function(a, b){return a - b;});
+ }else{
+ this.option.pageSizes = this.pageSizes;
+ }
+ this.defaultPageSize = this.option.defaultPageSize >= 1 ? parseInt(this.option.defaultPageSize, 10) : this.pageSizes[0];
+ this.option.maxPageStep = this.option.maxPageStep > 0 ? this.option.maxPageStep : this.maxPageStep;
+ this.option.position = lang.isString(this.option.position) ? this.option.position.toLowerCase() : this.position;
+ var nls = i18n.getLocalization("dojox.grid.enhanced", "Pagination");
+ this._nls = [
+ nls.descTemplate,
+ nls.allItemsLabelTemplate,
+ nls.pageSizeLabelTemplate,
+ nls.pageStepLabelTemplate,
+ nls.itemTitle,
+ nls.singularItemTitle,
+ nls.prevTip,
+ nls.firstTip,
+ nls.nextTip,
+ nls.lastTip,
+ nls.gotoButtonTitle,
+ nls.dialogTitle,
+ nls.dialogIndication,
+ nls.pageCountIndication,
+ nls.dialogConfirm,
+ nls.dialogCancel,
+ nls.all
+ ];
+ },
+ _regApis: function(){
+ var g = this.grid;
+ // New added APIs
+ g.currentPage = lang.hitch(this, this.currentPage);
+ g.nextPage = lang.hitch(this, this.nextPage);
+ g.prevPage = lang.hitch(this, this.prevPage);
+ g.firstPage = lang.hitch(this, this.firstPage);
+ g.lastPage = lang.hitch(this, this.lastPage);
+ g.currentPageSize = lang.hitch(this, this.currentPageSize);
+ g.showGotoPageButton = lang.hitch(this, this.showGotoPageButton);
+ g.getTotalRowCount = lang.hitch(this, this.getTotalRowCount);
+ g.getTotalPageNum = lang.hitch(this, this.getTotalPageNum);
+
+ g.gotoPage = lang.hitch(this, this.gotoPage);
+ g.gotoFirstPage = lang.hitch(this, this.gotoFirstPage);
+ g.gotoLastPage = lang.hitch(this, this.gotoLastPage);
+ g.changePageSize = lang.hitch(this, this.changePageSize);
+ // Changed APIs
+ this._gridOriginalfuncs = [
+ lang.hitch(g, g.scrollToRow),
+ lang.hitch(g, g._onNew),
+ lang.hitch(g, g.removeSelectedRows)
+ ];
+ g.scrollToRow = lang.hitch(this, this.scrollToRow);
+ g.removeSelectedRows = lang.hitch(this, this.removeSelectedRows);
+ g._onNew = lang.hitch(this, this._onNew);
+ this.connect(g, "_onDelete", lang.hitch(this, this._onDelete));
+ },
+ _onNew: function(item, parentInfo){
+ var totalPages = this.getTotalPageNum();
+ if(((this._currentPage === totalPages || totalPages === 0) && this.grid.get('rowCount') < this._currentPageSize) || this._showAll){
+ lang.hitch(this.grid, this._gridOriginalfuncs[1])(item, parentInfo);
+ this.forcePageStoreLayer.endIdx++;
+ }
+ this._maxSize++;
+ if(this._showAll){
+ this._currentPageSize++;
+ }
+ if(this._showAll && this.grid.autoHeight){
+ this.grid._refresh();
+ }else{
+ this._paginator._update();
+ }
+ },
+ _onDelete: function(){
+ if(!this._multiRemoving){
+ this.grid.resize();
+ if(this._showAll){
+ this.grid._refresh();
+ }
+ }
+ if(this.grid.get('rowCount') === 0){
+ this.prevPage();
+ }
+ }
+});
+
+EnhancedGrid.registerPlugin(Pagination/*name:'pagination'*/);
+
+return Pagination;
+
+}); \ No newline at end of file
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Printer.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Printer.js
new file mode 100644
index 0000000..09ab390
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Printer.js
@@ -0,0 +1,292 @@
+//>>built
+define("dojox/grid/enhanced/plugins/Printer", [
+ "dojo/_base/declare",
+ "dojo/_base/html",
+ "dojo/_base/Deferred",
+ "dojo/_base/lang",
+ "dojo/_base/sniff",
+ "dojo/_base/xhr",
+ "dojo/_base/array",
+ "dojo/query",
+ "dojo/DeferredList",
+ "../_Plugin",
+ "../../EnhancedGrid",
+ "./exporter/TableWriter"
+], function(declare, html, Deferred, lang, has, xhr, array, query, DeferredList, _Plugin, EnhancedGrid, TableWriter){
+
+var Printer = declare("dojox.grid.enhanced.plugins.Printer", _Plugin, {
+ // summary:
+ // Provide printGrid function to the grid.
+ // example:
+ // | dojo.require("dojox.grid.enhanced.plugins.Printer");
+ // | dijit.byId("grid1").printGrid("my grid", //A title for the grid,optional
+ // | ["cssfile1.css","cssfile2.css"],//An array of css files to decorate the printed gird,optional
+ // | {table:"border='border'"} //tagName:"attrbuteList" pairs, optional,
+ // | //control the html tags in the generated html
+ // | );
+
+ // __printArgs: {
+ // title: String
+ // A title of the printed page can be specified. Optional.
+ // If given, it's shown in an <h1> tag at the top of the page.
+ // cssFiles: Array | String
+ // CSS file paths. Optional.
+ // Every row and column is given CSS classes, including:
+ // grid_row_{row-number}, grid_odd_row, grid_even_row, grid_header,
+ // grid_col_{col-number}, grid_odd_col, grid_even_col
+ // {row_number} and {col-number} are both integers starting from 1.
+ // Row classes are for <thead> and <tbody> tags.
+ // Column classes are for <th> and <td> tags.
+ // Users can use these classes in the CSS files, but cannot define their own.
+ // writerArgs: Object (Association Array)
+ // Arguments for TableWriter.
+ // fetchArgs: object?
+ // Any arguments for store.fetch
+ // }
+
+ // name: String
+ // Plugin name
+ name: "printer",
+
+ constructor: function(grid){
+ // summary:
+ // only newed by _Plugin
+ // inGrid: EnhancedGrid
+ // The grid to plug in to.
+ this.grid = grid;
+ this._mixinGrid(grid);
+
+ //For print, we usually need the HTML instead of raw data.
+ grid.setExportFormatter(function(data, cell, rowIndex, rowItem){
+ return cell.format(rowIndex, rowItem);
+ });
+ },
+ _mixinGrid: function(){
+ var g = this.grid;
+ g.printGrid = lang.hitch(this, this.printGrid);
+ g.printSelected = lang.hitch(this, this.printSelected);
+ g.exportToHTML = lang.hitch(this, this.exportToHTML);
+ g.exportSelectedToHTML = lang.hitch(this, this.exportSelectedToHTML);
+ g.normalizePrintedGrid = lang.hitch(this, this.normalizeRowHeight);
+ },
+ printGrid: function(args){
+ // summary:
+ // Print all the data in the grid, using title as a title,
+ // decorating generated html by cssFiles,
+ // using tagName:"attrbuteList" pairs(writerArgs) to control html tags
+ // in the generated html string.
+ // tags:
+ // public
+ // args: __printArgs?
+ // Arguments for print.
+ this.exportToHTML(args, lang.hitch(this, this._print));
+ },
+ printSelected: function(args){
+ // summary:
+ // Print selected data. All other features are the same as printGrid.
+ // For meaning of arguments see function *printGrid*
+ // tags:
+ // public
+ // args: __printArgs?
+ // Arguments for print.
+ this.exportSelectedToHTML(args, lang.hitch(this, this._print));
+ },
+ exportToHTML: function(args, onExported){
+ // summary:
+ // Export to HTML string, but do NOT print.
+ // Users can use this to implement print preview.
+ // For meaning of the 1st-3rd arguments see function *printGrid*.
+ // tags:
+ // public
+ // args: __printArgs?
+ // Arguments for print.
+ // onExported: function(string)
+ // call back function
+ args = this._formalizeArgs(args);
+ var _this = this;
+ this.grid.exportGrid("table", args, function(str){
+ _this._wrapHTML(args.title, args.cssFiles, args.titleInBody + str).then(onExported);
+ });
+ },
+ exportSelectedToHTML: function(args, onExported){
+ // summary:
+ // Export selected rows to HTML string, but do NOT print.
+ // Users can use this to implement print preview.
+ // For meaning of arguments see function *printGrid*
+ // tags:
+ // public
+ // args: __printArgs?
+ // Arguments for print.
+ args = this._formalizeArgs(args);
+ var _this = this;
+ this.grid.exportSelected("table", args.writerArgs, function(str){
+ _this._wrapHTML(args.title, args.cssFiles, args.titleInBody + str).then(onExported);
+ });
+ },
+
+ _loadCSSFiles: function(cssFiles){
+ var dl = array.map(cssFiles, function(cssFile){
+ cssFile = lang.trim(cssFile);
+ if(cssFile.substring(cssFile.length - 4).toLowerCase() === '.css'){
+ return xhr.get({
+ url: cssFile
+ });
+ }else{
+ var d = new Deferred();
+ d.callback(cssFile);
+ return d;
+ }
+ });
+ return DeferredList.prototype.gatherResults(dl);
+ },
+ _print: function(/* string */htmlStr){
+ // summary:
+ // Do the print job.
+ // tags:
+ // private
+ // htmlStr: String
+ // The html content string to be printed.
+ // returns:
+ // undefined
+ var win, _this = this,
+ fillDoc = function(w){
+ var doc = w.document;
+ doc.open();
+ doc.write(htmlStr);
+ doc.close();
+ _this.normalizeRowHeight(doc);
+ };
+ if(!window.print){
+ //We don't have a print facility.
+ return;
+ }else if(has("chrome") || has("opera")){
+ //referred from dijit._editor.plugins.Print._print()
+ //In opera and chrome the iframe.contentWindow.print
+ //will also print the outside window. So we must create a
+ //stand-alone new window.
+ win = window.open("javascript: ''", "",
+ "status=0,menubar=0,location=0,toolbar=0,width=1,height=1,resizable=0,scrollbars=0");
+ fillDoc(win);
+ win.print();
+ //Opera will stop at this point, showing the popping-out window.
+ //If the user closes the window, the following codes will not execute.
+ //If the user returns focus to the main window, the print function
+ // is executed, but still a no-op.
+ win.close();
+ }else{
+ //Put private things in deeper namespace to avoid poluting grid namespace.
+ var fn = this._printFrame,
+ dn = this.grid.domNode;
+ if(!fn){
+ var frameId = dn.id + "_print_frame";
+ if(!(fn = html.byId(frameId))){
+ //create an iframe to store the grid data.
+ fn = html.create("iframe");
+ fn.id = frameId;
+ fn.frameBorder = 0;
+ html.style(fn, {
+ width: "1px",
+ height: "1px",
+ position: "absolute",
+ right: 0,
+ bottom: 0,
+ border: "none",
+ overflow: "hidden"
+ });
+ if(!has("ie")){
+ html.style(fn, "visibility", "hidden");
+ }
+ dn.appendChild(fn);
+ }
+ //Reuse this iframe
+ this._printFrame = fn;
+ }
+ win = fn.contentWindow;
+ fillDoc(win);
+ //IE requires the frame to be focused for print to work, and it's harmless for FF.
+ win.focus();
+ win.print();
+ }
+ },
+ _wrapHTML: function(/* string */title, /* Array */cssFiles, /* string */body_content){
+ // summary:
+ // Put title, cssFiles, and body_content together into an HTML string.
+ // tags:
+ // private
+ // title: String
+ // A title for the html page.
+ // cssFiles: Array
+ // css file pathes.
+ // body_content: String
+ // Content to print, not including <head></head> part and <html> tags
+ // returns:
+ // the wrapped HTML string ready for print
+ return this._loadCSSFiles(cssFiles).then(function(cssStrs){
+ var i, sb = ['<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">',
+ '<html ', html._isBodyLtr() ? '' : 'dir="rtl"', '><head><title>', title,
+ '</title><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>'];
+ for(i = 0; i < cssStrs.length; ++i){
+ sb.push('<style type="text/css">', cssStrs[i], '</style>');
+ }
+ sb.push('</head>');
+ if(body_content.search(/^\s*<body/i) < 0){
+ body_content = '<body>' + body_content + '</body>';
+ }
+ sb.push(body_content, '</html>');
+ return sb.join('');
+ });
+ },
+ normalizeRowHeight: function(doc){
+ var views = query(".grid_view", doc.body);
+ var headPerView = array.map(views, function(view){
+ return query(".grid_header", view)[0];
+ });
+ var rowsPerView = array.map(views, function(view){
+ return query(".grid_row", view);
+ });
+ var rowCount = rowsPerView[0].length;
+ var i, v, h, maxHeight = 0;
+ for(v = views.length - 1; v >= 0; --v){
+ h = html.contentBox(headPerView[v]).h;
+ if(h > maxHeight){
+ maxHeight = h;
+ }
+ }
+ for(v = views.length - 1; v >= 0; --v){
+ html.style(headPerView[v], "height", maxHeight + "px");
+ }
+ for(i = 0; i < rowCount; ++i){
+ maxHeight = 0;
+ for(v = views.length - 1; v >= 0; --v){
+ h = html.contentBox(rowsPerView[v][i]).h;
+ if(h > maxHeight){
+ maxHeight = h;
+ }
+ }
+ for(v = views.length - 1; v >= 0; --v){
+ html.style(rowsPerView[v][i], "height", maxHeight + "px");
+ }
+ }
+ var left = 0, ltr = html._isBodyLtr();
+ for(v = 0; v < views.length; ++v){
+ html.style(views[v], ltr ? "left" : "right", left + "px");
+ left += html.marginBox(views[v]).w;
+ }
+ },
+ _formalizeArgs: function(args){
+ args = (args && lang.isObject(args)) ? args : {};
+ args.title = String(args.title) || "";
+ if(!lang.isArray(args.cssFiles)){
+ args.cssFiles = [args.cssFiles];
+ }
+ args.titleInBody = args.title ? ['<h1>', args.title, '</h1>'].join('') : '';
+ return args; //Object
+ }
+});
+
+EnhancedGrid.registerPlugin(Printer/*name:'printer'*/, {
+ "dependency": ["exporter"]
+});
+
+return Printer;
+});
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Rearrange.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Rearrange.js
new file mode 100644
index 0000000..1c3bac3
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Rearrange.js
@@ -0,0 +1,506 @@
+//>>built
+define("dojox/grid/enhanced/plugins/Rearrange", [
+ "dojo/_base/kernel",
+ "dojo/_base/lang",
+ "dojo/_base/declare",
+ "dojo/_base/array",
+ "dojo/_base/connect",
+ "../../EnhancedGrid",
+ "../_Plugin",
+ "./_RowMapLayer"
+], function(dojo, lang, declare, array, connect, EnhancedGrid, _Plugin, _RowMapLayer){
+
+var Rearrange = declare("dojox.grid.enhanced.plugins.Rearrange", _Plugin, {
+ // summary:
+ // Provides a set of method to re-arrange the structure of grid.
+
+ // name: String
+ // plugin name
+ name: "rearrange",
+
+ constructor: function(grid, args){
+ this.grid = grid;
+ this.setArgs(args);
+ var rowMapLayer = new _RowMapLayer(grid);
+ dojox.grid.enhanced.plugins.wrap(grid, "_storeLayerFetch", rowMapLayer);
+ },
+ setArgs: function(args){
+ this.args = lang.mixin(this.args || {}, args || {});
+ this.args.setIdentifierForNewItem = this.args.setIdentifierForNewItem || function(v){return v;};
+ },
+ destroy: function(){
+ this.inherited(arguments);
+ this.grid.unwrap("rowmap");
+ },
+ onSetStore: function(store){
+ this.grid.layer("rowmap").clearMapping();
+ },
+ _hasIdentity: function(points){
+ var g = this.grid, s = g.store, cells = g.layout.cells;
+ if(s.getFeatures()["dojo.data.api.Identity"]){
+ if(array.some(points, function(point){
+ return s.getIdentityAttributes(g._by_idx[point.r].item) == cells[point.c].field;
+ })){
+ return true;
+ }
+ }
+ return false;
+ },
+ moveColumns: function(colsToMove, targetPos){
+ // summary:
+ // Move a set of columns to a given position.
+ // tag:
+ // public
+ // colsToMove: Integer[]
+ // Array of column indexes.
+ // targetPos: Integer
+ // The target position
+ var g = this.grid,
+ layout = g.layout,
+ cells = layout.cells,
+ colIndex, i, delta = 0,
+ before = true, tmp = {}, mapping = {};
+ colsToMove.sort(function(a, b){
+ return a - b;
+ });
+ for(i = 0; i < colsToMove.length; ++i){
+ tmp[colsToMove[i]] = i;
+ if(colsToMove[i] < targetPos){
+ ++delta;
+ }
+ }
+ var leftCount = 0, rightCount = 0;
+ var maxCol = Math.max(colsToMove[colsToMove.length - 1], targetPos);
+ if(maxCol == cells.length){
+ --maxCol;
+ }
+ var minCol = Math.min(colsToMove[0], targetPos);
+ for(i = minCol; i <= maxCol; ++i){
+ var j = tmp[i];
+ if(j >= 0){
+ mapping[i] = targetPos - delta + j;
+ }else if(i < targetPos){
+ mapping[i] = minCol + leftCount;
+ ++leftCount;
+ }else if(i >= targetPos){
+ mapping[i] = targetPos + colsToMove.length - delta + rightCount;
+ ++rightCount;
+ }
+ }
+ //console.log("mapping:", mapping, ", colsToMove:", colsToMove,", target:", targetPos);
+ delta = 0;
+ if(targetPos == cells.length){
+ --targetPos;
+ before = false;
+ }
+ g._notRefreshSelection = true;
+ for(i = 0; i < colsToMove.length; ++i){
+ colIndex = colsToMove[i];
+ if(colIndex < targetPos){
+ colIndex -= delta;
+ }
+ ++delta;
+ if(colIndex != targetPos){
+ layout.moveColumn(cells[colIndex].view.idx, cells[targetPos].view.idx, colIndex, targetPos, before);
+ cells = layout.cells;
+ }
+ if(targetPos <= colIndex){
+ ++targetPos;
+ }
+ }
+ delete g._notRefreshSelection;
+ connect.publish("dojox/grid/rearrange/move/" + g.id, ["col", mapping, colsToMove]);
+ },
+ moveRows: function(rowsToMove, targetPos){
+ // summary:
+ // Move a set of rows to a given position
+ // tag:
+ // public
+ // rowsToMove: Integer[]
+ // Array of row indexes.
+ // targetPos: Integer
+ // The target position
+ var g = this.grid,
+ mapping = {},
+ preRowsToMove = [],
+ postRowsToMove = [],
+ len = rowsToMove.length,
+ i, r, k, arr, rowMap, lastPos;
+
+ for(i = 0; i < len; ++i){
+ r = rowsToMove[i];
+ if(r >= targetPos){
+ break;
+ }
+ preRowsToMove.push(r);
+ }
+ postRowsToMove = rowsToMove.slice(i);
+
+ arr = preRowsToMove;
+ len = arr.length;
+ if(len){
+ rowMap = {};
+ array.forEach(arr, function(r){
+ rowMap[r] = true;
+ });
+ mapping[arr[0]] = targetPos - len;
+ for(k = 0, i = arr[k] + 1, lastPos = i - 1; i < targetPos; ++i){
+ if(!rowMap[i]){
+ mapping[i] = lastPos;
+ ++lastPos;
+ }else{
+ ++k;
+ mapping[i] = targetPos - len + k;
+ }
+ }
+ }
+ arr = postRowsToMove;
+ len = arr.length;
+ if(len){
+ rowMap = {};
+ array.forEach(arr, function(r){
+ rowMap[r] = true;
+ });
+ mapping[arr[len - 1]] = targetPos + len - 1;
+ for(k = len - 1, i = arr[k] - 1, lastPos = i + 1; i >= targetPos; --i){
+ if(!rowMap[i]){
+ mapping[i] = lastPos;
+ --lastPos;
+ }else{
+ --k;
+ mapping[i] = targetPos + k;
+ }
+ }
+ }
+ var tmpMapping = lang.clone(mapping);
+ g.layer("rowmap").setMapping(mapping);
+ g.forEachLayer(function(layer){
+ if(layer.name() != "rowmap"){
+ layer.invalidate();
+ return true;
+ }else{
+ return false;
+ }
+ }, false);
+ g.selection.selected = [];
+ g._noInternalMapping = true;
+ g._refresh();
+ setTimeout(function(){
+ connect.publish("dojox/grid/rearrange/move/" + g.id, ["row", tmpMapping, rowsToMove]);
+ g._noInternalMapping = false;
+ }, 0);
+ },
+ moveCells: function(cellsToMove, target){
+ var g = this.grid,
+ s = g.store;
+ if(s.getFeatures()["dojo.data.api.Write"]){
+ if(cellsToMove.min.row == target.min.row && cellsToMove.min.col == target.min.col){
+ //Same position, no need to move
+ return;
+ }
+ var cells = g.layout.cells,
+ cnt = cellsToMove.max.row - cellsToMove.min.row + 1,
+ r, c, tr, tc,
+ sources = [], targets = [];
+ for(r = cellsToMove.min.row, tr = target.min.row; r <= cellsToMove.max.row; ++r, ++tr){
+ for(c = cellsToMove.min.col, tc = target.min.col; c <= cellsToMove.max.col; ++c, ++tc){
+ while(cells[c] && cells[c].hidden){
+ ++c;
+ }
+ while(cells[tc] && cells[tc].hidden){
+ ++tc;
+ }
+ sources.push({
+ "r": r,
+ "c": c
+ });
+ targets.push({
+ "r": tr,
+ "c": tc,
+ "v": cells[c].get(r, g._by_idx[r].item)
+ });
+ }
+ }
+ if(this._hasIdentity(sources.concat(targets))){
+ console.warn("Can not write to identity!");
+ return;
+ }
+ array.forEach(sources, function(point){
+ s.setValue(g._by_idx[point.r].item, cells[point.c].field, "");
+ });
+ array.forEach(targets, function(point){
+ s.setValue(g._by_idx[point.r].item, cells[point.c].field, point.v);
+ });
+ s.save({
+ onComplete: function(){
+ connect.publish("dojox/grid/rearrange/move/" + g.id, ["cell", {
+ "from": cellsToMove,
+ "to": target
+ }]);
+ }
+ });
+ }
+ },
+ copyCells: function(cellsToMove, target){
+ var g = this.grid,
+ s = g.store;
+ if(s.getFeatures()["dojo.data.api.Write"]){
+ if(cellsToMove.min.row == target.min.row && cellsToMove.min.col == target.min.col){
+ return;
+ }
+ var cells = g.layout.cells,
+ cnt = cellsToMove.max.row - cellsToMove.min.row + 1,
+ r, c, tr, tc,
+ targets = [];
+ for(r = cellsToMove.min.row, tr = target.min.row; r <= cellsToMove.max.row; ++r, ++tr){
+ for(c = cellsToMove.min.col, tc = target.min.col; c <= cellsToMove.max.col; ++c, ++tc){
+ while(cells[c] && cells[c].hidden){
+ ++c;
+ }
+ while(cells[tc] && cells[tc].hidden){
+ ++tc;
+ }
+ targets.push({
+ "r": tr,
+ "c": tc,
+ "v": cells[c].get(r, g._by_idx[r].item)
+ });
+ }
+ }
+ if(this._hasIdentity(targets)){
+ console.warn("Can not write to identity!");
+ return;
+ }
+ array.forEach(targets, function(point){
+ s.setValue(g._by_idx[point.r].item, cells[point.c].field, point.v);
+ });
+ s.save({
+ onComplete: function(){
+ setTimeout(function(){
+ connect.publish("dojox/grid/rearrange/copy/" + g.id, ["cell", {
+ "from": cellsToMove,
+ "to": target
+ }]);
+ }, 0);
+ }
+ });
+ }
+ },
+ changeCells: function(sourceGrid, cellsToMove, target){
+ var g = this.grid,
+ s = g.store;
+ if(s.getFeatures()["dojo.data.api.Write"]){
+ var srcg = sourceGrid,
+ cells = g.layout.cells,
+ srccells = srcg.layout.cells,
+ cnt = cellsToMove.max.row - cellsToMove.min.row + 1,
+ r, c, tr, tc, targets = [];
+ for(r = cellsToMove.min.row, tr = target.min.row; r <= cellsToMove.max.row; ++r, ++tr){
+ for(c = cellsToMove.min.col, tc = target.min.col; c <= cellsToMove.max.col; ++c, ++tc){
+ while(srccells[c] && srccells[c].hidden){
+ ++c;
+ }
+ while(cells[tc] && cells[tc].hidden){
+ ++tc;
+ }
+ targets.push({
+ "r": tr,
+ "c": tc,
+ "v": srccells[c].get(r, srcg._by_idx[r].item)
+ });
+ }
+ }
+ if(this._hasIdentity(targets)){
+ console.warn("Can not write to identity!");
+ return;
+ }
+ array.forEach(targets, function(point){
+ s.setValue(g._by_idx[point.r].item, cells[point.c].field, point.v);
+ });
+ s.save({
+ onComplete: function(){
+ connect.publish("dojox/grid/rearrange/change/" + g.id, ["cell", target]);
+ }
+ });
+ }
+ },
+ clearCells: function(cellsToClear){
+ var g = this.grid,
+ s = g.store;
+ if(s.getFeatures()["dojo.data.api.Write"]){
+ var cells = g.layout.cells,
+ cnt = cellsToClear.max.row - cellsToClear.min.row + 1,
+ r, c, targets = [];
+ for(r = cellsToClear.min.row; r <= cellsToClear.max.row; ++r){
+ for(c = cellsToClear.min.col; c <= cellsToClear.max.col; ++c){
+ while(cells[c] && cells[c].hidden){
+ ++c;
+ }
+ targets.push({
+ "r": r,
+ "c": c
+ });
+ }
+ }
+ if(this._hasIdentity(targets)){
+ console.warn("Can not write to identity!");
+ return;
+ }
+ array.forEach(targets, function(point){
+ s.setValue(g._by_idx[point.r].item, cells[point.c].field, "");
+ });
+ s.save({
+ onComplete: function(){
+ connect.publish("dojox/grid/rearrange/change/" + g.id, ["cell", cellsToClear]);
+ }
+ });
+ }
+ },
+ insertRows: function(sourceGrid, rowsToMove, targetPos){
+ try{
+ var g = this.grid,
+ s = g.store,
+ rowCnt = g.rowCount,
+ mapping = {},
+ obj = {idx: 0},
+ newRows = [], i,
+ emptyTarget = targetPos < 0;
+ _this = this;
+ var len = rowsToMove.length;
+ if(emptyTarget){
+ targetPos = 0;
+ }else{
+ for(i = targetPos; i < g.rowCount; ++i){
+ mapping[i] = i + len;
+ }
+ }
+ if(s.getFeatures()['dojo.data.api.Write']){
+ if(sourceGrid){
+ var srcg = sourceGrid,
+ srcs = srcg.store,
+ thisItem, attrs;
+ if(!emptyTarget){
+ for(i = 0; !thisItem; ++i){
+ thisItem = g._by_idx[i];
+ }
+ attrs = s.getAttributes(thisItem.item);
+ }else{
+ //If the target grid is empty, there is no way to retrieve attributes.
+ //So try to get attrs from grid.layout.cells[], but this might not be right
+ //since some fields may be missed(e.g ID fields), please use "setIdentifierForNewItem()"
+ //to add those missed fields
+ attrs = array.map(g.layout.cells, function(cell){
+ return cell.field;
+ });
+ }
+ var rowsToFetch = [];
+ array.forEach(rowsToMove, function(rowIndex, i){
+ var item = {};
+ var srcItem = srcg._by_idx[rowIndex];
+ if(srcItem){
+ array.forEach(attrs, function(attr){
+ item[attr] = srcs.getValue(srcItem.item, attr);
+ });
+ item = _this.args.setIdentifierForNewItem(item, s, rowCnt + obj.idx) || item;
+ try{
+ s.newItem(item);
+ newRows.push(targetPos + i);
+ mapping[rowCnt + obj.idx] = targetPos + i;
+ ++obj.idx;
+ }catch(e){
+ console.log("insertRows newItem:",e,item);
+ }
+ }else{
+ rowsToFetch.push(rowIndex);
+ }
+ });
+ }else if(rowsToMove.length && lang.isObject(rowsToMove[0])){
+ array.forEach(rowsToMove, function(rowData, i){
+ var item = _this.args.setIdentifierForNewItem(rowData, s, rowCnt + obj.idx) || rowData;
+ try{
+ s.newItem(item);
+ newRows.push(targetPos + i);
+ mapping[rowCnt + obj.idx] = targetPos + i;
+ ++obj.idx;
+ }catch(e){
+ console.log("insertRows newItem:",e,item);
+ }
+ });
+ }else{
+ return;
+ }
+ g.layer("rowmap").setMapping(mapping);
+ s.save({
+ onComplete: function(){
+ g._refresh();
+ setTimeout(function(){
+ connect.publish("dojox/grid/rearrange/insert/" + g.id, ["row", newRows]);
+ }, 0);
+ }
+ });
+ }
+ }catch(e){
+ console.log("insertRows:",e);
+ }
+ },
+ removeRows: function(rowsToRemove){
+ var g = this.grid;
+ var s = g.store;
+ try{
+ array.forEach(array.map(rowsToRemove, function(rowIndex){
+ return g._by_idx[rowIndex];
+ }), function(row){
+ if(row){
+ s.deleteItem(row.item);
+ }
+ });
+ s.save({
+ onComplete: function(){
+ connect.publish("dojox/grid/rearrange/remove/" + g.id, ["row", rowsToRemove]);
+ }
+ });
+ }catch(e){
+ console.log("removeRows:",e);
+ }
+ },
+ _getPageInfo: function(){
+ // summary:
+ // Find pages that contain visible rows
+ // return: Object
+ // {topPage: xx, bottomPage: xx, invalidPages: [xx,xx,...]}
+ var scroller = this.grid.scroller,
+ topPage = scroller.page,
+ bottomPage = scroller.page,
+ firstVisibleRow = scroller.firstVisibleRow,
+ lastVisibleRow = scroller.lastVisibleRow,
+ rowsPerPage = scroller.rowsPerPage,
+ renderedPages = scroller.pageNodes[0],
+ topRow, bottomRow, matched,
+ invalidPages = [];
+
+ array.forEach(renderedPages, function(page, pageIndex){
+ if(!page){ return; }
+ matched = false;
+ topRow = pageIndex * rowsPerPage;
+ bottomRow = (pageIndex + 1) * rowsPerPage - 1;
+ if(firstVisibleRow >= topRow && firstVisibleRow <= bottomRow){
+ topPage = pageIndex;
+ matched = true;
+ }
+ if(lastVisibleRow >= topRow && lastVisibleRow <= bottomRow){
+ bottomPage = pageIndex;
+ matched = true;
+ }
+ if(!matched && (topRow > lastVisibleRow || bottomRow < firstVisibleRow)){
+ invalidPages.push(pageIndex);
+ }
+ });
+ return {topPage: topPage, bottomPage: bottomPage, invalidPages: invalidPages};
+ }
+});
+
+EnhancedGrid.registerPlugin(Rearrange/*name:'rearrange'*/);
+
+return Rearrange;
+
+}); \ No newline at end of file
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Search.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Search.js
new file mode 100644
index 0000000..2c0284c
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Search.js
@@ -0,0 +1,123 @@
+//>>built
+define("dojox/grid/enhanced/plugins/Search", [
+ "dojo/_base/kernel",
+ "dojo/_base/lang",
+ "dojo/_base/declare",
+ "dojo/_base/array",
+ "dojo/data/util/filter",
+ "../../EnhancedGrid",
+ "../_Plugin"
+], function(dojo, lang, declare, array, dFilter, EnhancedGrid, _Plugin){
+
+var Search = declare("dojox.grid.enhanced.plugins.Search", _Plugin, {
+ // summary:
+ // Search the grid using wildcard string or Regular Expression.
+
+ // name: String
+ // plugin name
+ name: "search",
+
+ constructor: function(grid, args){
+ this.grid = grid;
+ args = (args && lang.isObject(args)) ? args : {};
+ this._cacheSize = args.cacheSize || -1;
+ grid.searchRow = lang.hitch(this, "searchRow");
+ },
+ searchRow: function(/* Object|RegExp|String */searchArgs, /* function(Integer, item) */onSearched){
+ if(!lang.isFunction(onSearched)){ return; }
+ if(lang.isString(searchArgs)){
+ searchArgs = dFilter.patternToRegExp(searchArgs);
+ }
+ var isGlobal = false;
+ if(searchArgs instanceof RegExp){
+ isGlobal = true;
+ }else if(lang.isObject(searchArgs)){
+ var isEmpty = true;
+ for(var field in searchArgs){
+ if(lang.isString(searchArgs[field])){
+ searchArgs[field] = dFilter.patternToRegExp(searchArgs[field]);
+ }
+ isEmpty = false;
+ }
+ if(isEmpty){ return; }
+ }else{
+ return;
+ }
+ this._search(searchArgs, 0, onSearched, isGlobal);
+ },
+ _search: function(/* Object|RegExp */searchArgs, /* Integer */start, /* function(Integer, item) */onSearched, /* Boolean */isGlobal){
+ var _this = this,
+ cnt = this._cacheSize,
+ args = {
+ start: start,
+ query: this.grid.query,
+ sort: this.grid.getSortProps(),
+ queryOptions: this.grid.queryOptions,
+ onBegin: function(size){
+ _this._storeSize = size;
+ },
+ onComplete: function(items){
+ if(!array.some(items, function(item, i){
+ if(_this._checkRow(item, searchArgs, isGlobal)){
+ onSearched(start + i, item);
+ return true;
+ }
+ return false;
+ })){
+ if(cnt > 0 && start + cnt < _this._storeSize){
+ _this._search(searchArgs, start + cnt, onSearched, isGlobal);
+ }else{
+ onSearched(-1, null);
+ }
+ }
+ }
+ };
+ if(cnt > 0){
+ args.count = cnt;
+ }
+ this.grid._storeLayerFetch(args);
+ },
+ _checkRow: function(/* store item */item, /* Object|RegExp */searchArgs, /* Boolean */isGlobal){
+ var g = this.grid, s = g.store, i, field,
+ cells = array.filter(g.layout.cells, function(cell){
+ return !cell.hidden;
+ });
+ if(isGlobal){
+ return array.some(cells, function(cell){
+ try{
+ if(cell.field){
+ return String(s.getValue(item, cell.field)).search(searchArgs) >= 0;
+ }
+ }catch(e){
+ console.log("Search._checkRow() error: ", e);
+ }
+ return false;
+ });
+ }else{
+ for(field in searchArgs){
+ if(searchArgs[field] instanceof RegExp){
+ for(i = cells.length - 1; i >= 0; --i){
+ if(cells[i].field == field){
+ try{
+ if(String(s.getValue(item, field)).search(searchArgs[field]) < 0){
+ return false;
+ }
+ break;
+ }catch(e){
+ return false;
+ }
+ }
+ }
+ if(i < 0){ return false; }
+ }
+ }
+ return true;
+ }
+ }
+});
+
+EnhancedGrid.registerPlugin(Search/*name:'search'*/);
+
+return Search;
+
+}); \ No newline at end of file
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Selector.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Selector.js
new file mode 100644
index 0000000..c9e2574
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/Selector.js
@@ -0,0 +1,1477 @@
+//>>built
+define("dojox/grid/enhanced/plugins/Selector", [
+ "dojo/_base/kernel",
+ "dojo/_base/lang",
+ "dojo/_base/declare",
+ "dojo/_base/array",
+ "dojo/_base/event",
+ "dojo/keys",
+ "dojo/query",
+ "dojo/_base/html",
+ "dojo/_base/window",
+ "dijit/focus",
+ "../../_RowSelector",
+ "../_Plugin",
+ "../../EnhancedGrid",
+ "../../cells/_base",
+ "./AutoScroll"
+], function(dojo, lang, declare, array, event, keys, query, html, win, dijitFocus, _RowSelector, _Plugin, EnhancedGrid){
+
+/*=====
+dojo.declare("__SelectItem", null,{
+ // summary:
+ // An abstract representation of an item.
+});
+dojo.declare("__SelectCellItem", __SelectItem,{
+ // summary:
+ // An abstract representation of a cell.
+
+ // row: Integer
+ // Row index of this cell
+ row: 0,
+
+ // col: Integer
+ // Column index of this cell
+ col: 0
+});
+dojo.declare("__SelectRowItem", __SelectItem,{
+ // summary:
+ // An abstract representation of a row.
+
+ // row: Integer
+ // Row index of this row
+ row: 0,
+
+ // except: Integer[]
+ // An array of column indexes of all the unselected cells in this row.
+ except: []
+});
+dojo.declare("__SelectColItem", __SelectItem,{
+ // summary:
+ // An abstract representation of a column.
+
+ // col: Integer
+ // Column index of this column
+ col: 0,
+
+ // except: Integer[]
+ // An array of row indexes of all the unselected cells in this column.
+ except: []
+});
+=====*/
+
+var DISABLED = 0, SINGLE = 1, MULTI = 2,
+ _theOther = { col: "row", row: "col" },
+ _inRange = function(type, value, start, end, halfClose){
+ if(type !== "cell"){
+ value = value[type];
+ start = start[type];
+ end = end[type];
+ if(typeof value !== "number" || typeof start !== "number" || typeof end !== "number"){
+ return false;
+ }
+ return halfClose ? ((value >= start && value < end) || (value > end && value <= start))
+ : ((value >= start && value <= end) || (value >= end && value <= start));
+ }else{
+ return _inRange("col", value, start, end, halfClose) && _inRange("row", value, start, end, halfClose);
+ }
+ },
+ _isEqual = function(type, v1, v2){
+ try{
+ if(v1 && v2){
+ switch(type){
+ case "col": case "row":
+ return v1[type] == v2[type] && typeof v1[type] == "number" &&
+ !(_theOther[type] in v1) && !(_theOther[type] in v2);
+ case "cell":
+ return v1.col == v2.col && v1.row == v2.row && typeof v1.col == "number" && typeof v1.row == "number";
+ }
+ }
+ }catch(e){}
+ return false;
+ },
+ _stopEvent = function(evt){
+ try{
+ if(evt && evt.preventDefault){
+ event.stop(evt);
+ }
+ }catch(e){}
+ },
+ _createItem = function(type, rowIndex, colIndex){
+ switch(type){
+ case "col":
+ return {
+ "col": typeof colIndex == "undefined" ? rowIndex : colIndex,
+ "except": []
+ };
+ case "row":
+ return {
+ "row": rowIndex,
+ "except": []
+ };
+ case "cell":
+ return {
+ "row": rowIndex,
+ "col": colIndex
+ };
+ }
+ return null;
+ };
+var Selector = declare("dojox.grid.enhanced.plugins.Selector", _Plugin, {
+ // summary:
+ // Provides standard extended selection for grid.
+ // Supports mouse/keyboard selection, multi-selection, and de-selection.
+ // Acceptable plugin parameters:
+ // The whole plugin parameter object is a config object passed to the setupConfig function.
+ //
+ // Acceptable cell parameters defined in layout:
+ // 1. notselectable: boolean
+ // Whether this column is (and all the cells in it are) selectable.
+
+ // name: String
+ // plugin name
+ name: "selector",
+
+ // noClear: Boolean
+ // Not to clear rows selected by IndirectSelection.
+/*
+ // _config: null,
+ // _enabled: true,
+ // _selecting: {
+ // row: false,
+ // col: false,
+ // cell: false
+ // },
+ // _selected: {
+ // row: [],
+ // col: [],
+ // cell: []
+ // },
+ // _startPoint: {},
+ // _currentPoint: {},
+ // _lastAnchorPoint: {},
+ // _lastEndPoint: {},
+ // _lastSelectedAnchorPoint: {},
+ // _lastSelectedEndPoint: {},
+ // _keyboardSelect: {
+ // row: 0,
+ // col: 0,
+ // cell: 0
+ // },
+ // _curType: null,
+ // _lastType: null,
+ // _usingKeyboard: false,
+ // _toSelect: true,
+*/
+
+ constructor: function(grid, args){
+ this.grid = grid;
+ this._config = {
+ row: MULTI,
+ col: MULTI,
+ cell: MULTI
+ };
+ this.noClear = args && args.noClear;
+ this.setupConfig(args);
+ if(grid.selectionMode === "single"){
+ this._config.row = SINGLE;
+ }
+ this._enabled = true;
+ this._selecting = {};
+ this._selected = {
+ "col": [],
+ "row": [],
+ "cell": []
+ };
+ this._startPoint = {};
+ this._currentPoint = {};
+ this._lastAnchorPoint = {};
+ this._lastEndPoint = {};
+ this._lastSelectedAnchorPoint = {};
+ this._lastSelectedEndPoint = {};
+ this._keyboardSelect = {};
+ this._lastType = null;
+ this._selectedRowModified = {};
+ this._hacks();
+ this._initEvents();
+ this._initAreas();
+ this._mixinGrid();
+ },
+ destroy: function(){
+ this.inherited(arguments);
+ },
+ //------------public--------------------
+ setupConfig: function(config){
+ // summary:
+ // Set selection mode for row/col/cell.
+ // config: Object
+ // An object with the following structure (all properties are optional):
+ // {
+ // //Default is "multi", all other values are same as "multi".
+ // row: false|"disabled"|"single",
+ // col: false|"disabled"|"single",
+ // cell: false|"disabled"|"single"
+ // }
+ if(!config || !lang.isObject(config)){
+ return;
+ }
+ var types = ["row", "col", "cell"];
+ for(var type in config){
+ if(array.indexOf(types, type) >= 0){
+ if(!config[type] || config[type] == "disabled"){
+ this._config[type] = DISABLED;
+ }else if(config[type] == "single"){
+ this._config[type] = SINGLE;
+ }else{
+ this._config[type] = MULTI;
+ }
+ }
+ }
+
+ //Have to set mode to default grid selection.
+ var mode = ["none","single","extended"][this._config.row];
+ this.grid.selection.setMode(mode);
+ },
+ isSelected: function(type, rowIndex, colIndex){
+ // summary:
+ // Check whether a location (a cell, a column or a row) is selected.
+ // tag:
+ // public
+ // type: String
+ // "row" or "col" or "cell"
+ // rowIndex: Integer
+ // If type is "row" or "cell", this is the row index.
+ // If type if "col", this is the column index.
+ // colIndex: Integer?
+ // Only valid when type is "cell"
+ // return: Boolean
+ // true if selected, false if not. If cell is covered by a selected column, it's selected.
+ return this._isSelected(type, _createItem(type, rowIndex, colIndex));
+ },
+ toggleSelect: function(type, rowIndex, colIndex){
+ this._startSelect(type, _createItem(type, rowIndex, colIndex), this._config[type] === MULTI, false, false, !this.isSelected(type, rowIndex, colIndex));
+ this._endSelect(type);
+ },
+ select: function(type, rowIndex, colIndex){
+ // summary:
+ // Select a location (a cell, a column or a row).
+ // tag:
+ // public
+ // type: String
+ // "row" or "col" or "cell"
+ // rowIndex: Integer
+ // If type is "row" or "cell", this is the row index.
+ // If type if "col", this is the column index.
+ // colIndex: Integer?
+ // Only valid when type is "cell"
+ if(!this.isSelected(type, rowIndex, colIndex)){
+ this.toggleSelect(type, rowIndex, colIndex);
+ }
+ },
+ deselect: function(type, rowIndex, colIndex){
+ if(this.isSelected(type, rowIndex, colIndex)){
+ this.toggleSelect(type, rowIndex, colIndex);
+ }
+ },
+ selectRange: function(type, start, end, toSelect){
+ // summary:
+ // Select a continuous range (a block of cells, a set of continuous columns or rows)
+ // tag:
+ // public
+ // type: String
+ // "row" or "col" or "cell"
+ // start: Integer | Object
+ // If type is "row" or "col", this is the index of the starting row or column.
+ // If type if "cell", this is the left-top cell of the range.
+ // end: Integer | Object
+ // If type is "row" or "col", this is the index of the ending row or column.
+ // If type if "cell", this is the right-bottom cell of the range.
+ this.grid._selectingRange = true;
+ var startPoint = type == "cell" ? _createItem(type, start.row, start.col) : _createItem(type, start),
+ endPoint = type == "cell" ? _createItem(type, end.row, end.col) : _createItem(type, end);
+ this._startSelect(type, startPoint, false, false, false, toSelect);
+ this._highlight(type, endPoint, toSelect === undefined ? true : toSelect);
+ this._endSelect(type);
+ this.grid._selectingRange = false;
+ },
+ clear: function(type){
+ // summary:
+ // Clear all selections.
+ // tag:
+ // public
+ // type: String?
+ // "row" or "col" or "cell". If omitted, clear all.
+ this._clearSelection(type || "all");
+ },
+ isSelecting: function(type){
+ // summary:
+ // Check whether the user is currently selecting something.
+ // tag:
+ // public
+ // type: String
+ // "row" or "col" or "cell"
+ // return: Boolean
+ // true if is selection, false otherwise.
+ if(typeof type == "undefined"){
+ return this._selecting.col || this._selecting.row || this._selecting.cell;
+ }
+ return this._selecting[type];
+ },
+ selectEnabled: function(toEnable){
+ // summary:
+ // Turn on/off this selection functionality if *toEnable* is provided.
+ // Check whether this selection functionality is enabled if nothing is passed in.
+ // tag:
+ // public
+ // toEnable: Boolean?
+ // To enable or not. Optional.
+ // return: Boolean | undefined
+ // Enabled or not.
+ if(typeof toEnable != "undefined" && !this.isSelecting()){
+ this._enabled = !!toEnable;
+ }
+ return this._enabled;
+ },
+ getSelected: function(type, includeExceptions){
+ // summary:
+ // Get an array of selected locations.
+ // tag:
+ // public
+ // type: String
+ // "row" or "col" or "cell"
+ // includeExceptions: Boolean
+ // Only meaningful for rows/columns. If true, all selected rows/cols, even they are partly selected, are all returned.
+ // return: __SelectItem[]
+ switch(type){
+ case "cell":
+ return array.map(this._selected[type], function(item){ return item; });
+ case "col": case "row":
+ return array.map(includeExceptions ? this._selected[type]
+ : array.filter(this._selected[type], function(item){
+ return item.except.length === 0;
+ }), function(item){
+ return includeExceptions ? item : item[type];
+ });
+ }
+ return [];
+ },
+ getSelectedCount: function(type, includeExceptions){
+ // summary:
+ // Get the number of selected items.
+ // tag:
+ // public
+ // type: String
+ // "row" or "col" or "cell"
+ // includeExceptions: Boolean
+ // Only meaningful for rows/columns. If true, all selected rows/cols, even they are partly selected, are all returned.
+ // return: Integer
+ // The number of selected items.
+ switch(type){
+ case "cell":
+ return this._selected[type].length;
+ case "col": case "row":
+ return (includeExceptions ? this._selected[type]
+ : array.filter(this._selected[type], function(item){
+ return item.except.length === 0;
+ })).length;
+ }
+ return 0;
+ },
+ getSelectedType: function(){
+ // summary:
+ // Get the type of selected items.
+ // tag:
+ // public
+ // return: String
+ // "row" or "col" or "cell", or any mix of these (separator is | ).
+ var s = this._selected;
+ return ["", "cell", "row", "row|cell",
+ "col", "col|cell", "col|row", "col|row|cell"
+ ][(!!s.cell.length) | (!!s.row.length << 1) | (!!s.col.length << 2)];
+ },
+ getLastSelectedRange: function(type){
+ // summary:
+ // Get last selected range of the given type.
+ // tag:
+ // public
+ // return: Object
+ // {start: __SelectItem, end: __SelectItem}
+ // return null if nothing is selected.
+ return this._lastAnchorPoint[type] ? {
+ "start": this._lastAnchorPoint[type],
+ "end": this._lastEndPoint[type]
+ } : null;
+ },
+
+ //--------------------------private----------------------------
+ _hacks: function(){
+ // summary:
+ // Complete the event system of grid, hack some grid functions to prevent default behavior.
+ var g = this.grid;
+ var doContentMouseUp = function(e){
+ if(e.cellNode){
+ g.onMouseUp(e);
+ }
+ g.onMouseUpRow(e);
+ };
+ var mouseUp = lang.hitch(g, "onMouseUp");
+ var mouseDown = lang.hitch(g, "onMouseDown");
+ var doRowSelectorFocus = function(e){
+ e.cellNode.style.border = "solid 1px";
+ };
+ array.forEach(g.views.views, function(view){
+ view.content.domouseup = doContentMouseUp;
+ view.header.domouseup = mouseUp;
+ if(view.declaredClass == "dojox.grid._RowSelector"){
+ view.domousedown = mouseDown;
+ view.domouseup = mouseUp;
+ view.dofocus = doRowSelectorFocus;
+ }
+ });
+ //Disable default selection.
+ g.selection.clickSelect = function(){};
+
+ this._oldDeselectAll = g.selection.deselectAll;
+ var _this = this;
+ g.selection.selectRange = function(from, to){
+ _this.selectRange("row", from, to, true);
+ if(g.selection.preserver){
+ g.selection.preserver._updateMapping(true, true, false, from, to);
+ }
+ g.selection.onChanged();
+ };
+ g.selection.deselectRange = function(from, to){
+ _this.selectRange("row", from, to, false);
+ if(g.selection.preserver){
+ g.selection.preserver._updateMapping(true, false, false, from, to);
+ }
+ g.selection.onChanged();
+ };
+ g.selection.deselectAll = function(){
+ g._selectingRange = true;
+ _this._oldDeselectAll.apply(g.selection, arguments);
+ _this._clearSelection("all");
+ g._selectingRange = false;
+ if(g.selection.preserver){
+ g.selection.preserver._updateMapping(true, false, true);
+ }
+ g.selection.onChanged();
+ };
+
+ var rowSelector = g.views.views[0];
+ //The default function re-write the whole className, so can not insert any other classes.
+ if(rowSelector instanceof _RowSelector){
+ rowSelector.doStyleRowNode = function(inRowIndex, inRowNode){
+ html.removeClass(inRowNode, "dojoxGridRow");
+ html.addClass(inRowNode, "dojoxGridRowbar");
+ html.addClass(inRowNode, "dojoxGridNonNormalizedCell");
+ html.toggleClass(inRowNode, "dojoxGridRowbarOver", g.rows.isOver(inRowIndex));
+ html.toggleClass(inRowNode, "dojoxGridRowbarSelected", !!g.selection.isSelected(inRowIndex));
+ };
+ }
+ this.connect(g, "updateRow", function(rowIndex){
+ array.forEach(g.layout.cells, function(cell){
+ if(this.isSelected("cell", rowIndex, cell.index)){
+ this._highlightNode(cell.getNode(rowIndex), true);
+ }
+ }, this);
+ });
+ },
+ _mixinGrid: function(){
+ // summary:
+ // Expose events to grid.
+ var g = this.grid;
+ g.setupSelectorConfig = lang.hitch(this, this.setupConfig);
+ g.onStartSelect = function(){};
+ g.onEndSelect = function(){};
+ g.onStartDeselect = function(){};
+ g.onEndDeselect = function(){};
+ g.onSelectCleared = function(){};
+ },
+ _initEvents: function(){
+ // summary:
+ // Connect events, create event handlers.
+ var g = this.grid,
+ _this = this,
+ dp = lang.partial,
+ starter = function(type, e){
+ if(type === "row"){
+ _this._isUsingRowSelector = true;
+ }
+ //only left mouse button can select.
+ if(_this.selectEnabled() && _this._config[type] && e.button != 2){
+ if(_this._keyboardSelect.col || _this._keyboardSelect.row || _this._keyboardSelect.cell){
+ _this._endSelect("all");
+ _this._keyboardSelect.col = _this._keyboardSelect.row = _this._keyboardSelect.cell = 0;
+ }
+ if(_this._usingKeyboard){
+ _this._usingKeyboard = false;
+ }
+ var target = _createItem(type, e.rowIndex, e.cell && e.cell.index);
+ _this._startSelect(type, target, e.ctrlKey, e.shiftKey);
+ }
+ },
+ ender = lang.hitch(this, "_endSelect");
+ this.connect(g, "onHeaderCellMouseDown", dp(starter, "col"));
+ this.connect(g, "onHeaderCellMouseUp", dp(ender, "col"));
+
+ this.connect(g, "onRowSelectorMouseDown", dp(starter, "row"));
+ this.connect(g, "onRowSelectorMouseUp", dp(ender, "row"));
+
+ this.connect(g, "onCellMouseDown", function(e){
+ if(e.cell && e.cell.isRowSelector){ return; }
+ if(g.singleClickEdit){
+ _this._singleClickEdit = true;
+ g.singleClickEdit = false;
+ }
+ starter(_this._config["cell"] == DISABLED ? "row" : "cell", e);
+ });
+ this.connect(g, "onCellMouseUp", function(e){
+ if(_this._singleClickEdit){
+ delete _this._singleClickEdit;
+ g.singleClickEdit = true;
+ }
+ ender("all", e);
+ });
+
+ this.connect(g, "onCellMouseOver", function(e){
+ if(_this._curType != "row" && _this._selecting[_this._curType] && _this._config[_this._curType] == MULTI){
+ _this._highlight("col", _createItem("col", e.cell.index), _this._toSelect);
+ if(!_this._keyboardSelect.cell){
+ _this._highlight("cell", _createItem("cell", e.rowIndex, e.cell.index), _this._toSelect);
+ }
+ }
+ });
+ this.connect(g, "onHeaderCellMouseOver", function(e){
+ if(_this._selecting.col && _this._config.col == MULTI){
+ _this._highlight("col", _createItem("col", e.cell.index), _this._toSelect);
+ }
+ });
+ this.connect(g, "onRowMouseOver", function(e){
+ if(_this._selecting.row && _this._config.row == MULTI){
+ _this._highlight("row", _createItem("row", e.rowIndex), _this._toSelect);
+ }
+ });
+
+ //When row order has changed in a unpredictable way (sorted or filtered), map the new rowindex.
+ this.connect(g, "onSelectedById", "_onSelectedById");
+
+ //When the grid refreshes, all those selected should still appear selected.
+ this.connect(g, "_onFetchComplete", function(){
+ //console.debug("refresh after buildPage:", g._notRefreshSelection);
+ if(!g._notRefreshSelection){
+ this._refreshSelected(true);
+ }
+ });
+
+ //Small scroll might not refresh the grid.
+ this.connect(g.scroller, "buildPage", function(){
+ //console.debug("refresh after buildPage:", g._notRefreshSelection);
+ if(!g._notRefreshSelection){
+ this._refreshSelected(true);
+ }
+ });
+
+ //Whenever the mouse is up, end selecting.
+ this.connect(win.doc, "onmouseup", dp(ender, "all"));
+
+ //If autoscroll is enabled, connect to it.
+ this.connect(g, "onEndAutoScroll", function(isVertical, isForward, view, target){
+ var selectCell = _this._selecting.cell,
+ type, current, dir = isForward ? 1 : -1;
+ if(isVertical && (selectCell || _this._selecting.row)){
+ type = selectCell ? "cell" : "row";
+ current = _this._currentPoint[type];
+ _this._highlight(type, _createItem(type, current.row + dir, current.col), _this._toSelect);
+ }else if(!isVertical && (selectCell || _this._selecting.col)){
+ type = selectCell ? "cell" : "col";
+ current = _this._currentPoint[type];
+ _this._highlight(type, _createItem(type, current.row, target), _this._toSelect);
+ }
+ });
+ //If the grid is changed, selection should be consistent.
+ this.subscribe("dojox/grid/rearrange/move/" + g.id, "_onInternalRearrange");
+ this.subscribe("dojox/grid/rearrange/copy/" + g.id, "_onInternalRearrange");
+ this.subscribe("dojox/grid/rearrange/change/" + g.id, "_onExternalChange");
+ this.subscribe("dojox/grid/rearrange/insert/" + g.id, "_onExternalChange");
+ this.subscribe("dojox/grid/rearrange/remove/" + g.id, "clear");
+
+ //have to also select when the grid's default select is used.
+ this.connect(g, "onSelected", function(rowIndex){
+ if(this._selectedRowModified && this._isUsingRowSelector){
+ delete this._selectedRowModified;
+ }else if(!this.grid._selectingRange){
+ this.select("row", rowIndex);
+ }
+ });
+ this.connect(g, "onDeselected", function(rowIndex){
+ if(this._selectedRowModified && this._isUsingRowSelector){
+ delete this._selectedRowModified;
+ }else if(!this.grid._selectingRange){
+ this.deselect("row", rowIndex);
+ }
+ });
+ },
+ _onSelectedById: function(id, newIndex, isSelected){
+ if(this.grid._noInternalMapping){
+ return;
+ }
+ var pointSet = [this._lastAnchorPoint.row, this._lastEndPoint.row,
+ this._lastSelectedAnchorPoint.row, this._lastSelectedEndPoint.row];
+ pointSet = pointSet.concat(this._selected.row);
+ var found = false;
+ array.forEach(pointSet, function(item){
+ if(item){
+ if(item.id === id){
+ found = true;
+ item.row = newIndex;
+ }else if(item.row === newIndex && item.id){
+ item.row = -1;
+ }
+ }
+ });
+ if(!found && isSelected){
+ array.some(this._selected.row, function(item){
+ if(item && !item.id && !item.except.length){
+ item.id = id;
+ item.row = newIndex;
+ return true;
+ }
+ return false;
+ });
+ }
+ found = false;
+ pointSet = [this._lastAnchorPoint.cell, this._lastEndPoint.cell,
+ this._lastSelectedAnchorPoint.cell, this._lastSelectedEndPoint.cell];
+ pointSet = pointSet.concat(this._selected.cell);
+ array.forEach(pointSet, function(item){
+ if(item){
+ if(item.id === id){
+ found = true;
+ item.row = newIndex;
+ }else if(item.row === newIndex && item.id){
+ item.row = -1;
+ }
+ }
+ });
+ },
+ onSetStore: function(){
+ this._clearSelection("all");
+ },
+ _onInternalRearrange: function(type, mapping){
+ try{
+ //The column can not refresh it self!
+ this._refresh("col", false);
+
+ array.forEach(this._selected.row, function(item){
+ array.forEach(this.grid.layout.cells, function(cell){
+ this._highlightNode(cell.getNode(item.row), false);
+ }, this);
+ }, this);
+ //The rowbar must be cleaned manually
+ query(".dojoxGridRowSelectorSelected").forEach(function(node){
+ html.removeClass(node, "dojoxGridRowSelectorSelected");
+ html.removeClass(node, "dojoxGridRowSelectorSelectedUp");
+ html.removeClass(node, "dojoxGridRowSelectorSelectedDown");
+ });
+
+ var cleanUp = function(item){
+ if(item){
+ delete item.converted;
+ }
+ },
+ pointSet = [this._lastAnchorPoint[type], this._lastEndPoint[type],
+ this._lastSelectedAnchorPoint[type], this._lastSelectedEndPoint[type]];
+
+ if(type === "cell"){
+ this.selectRange("cell", mapping.to.min, mapping.to.max);
+ var cells = this.grid.layout.cells;
+ array.forEach(pointSet, function(item){
+ if(item.converted){ return; }
+ for(var r = mapping.from.min.row, tr = mapping.to.min.row; r <= mapping.from.max.row; ++r, ++tr){
+ for(var c = mapping.from.min.col, tc = mapping.to.min.col; c <= mapping.from.max.col; ++c, ++tc){
+ while(cells[c].hidden){ ++c; }
+ while(cells[tc].hidden){ ++tc; }
+ if(item.row == r && item.col == c){
+ //console.log('mapping found: (', item.row, ",",item.col,") to (", tr, ",", tc,")");
+ item.row = tr;
+ item.col = tc;
+ item.converted = true;
+ return;
+ }
+ }
+ }
+ });
+ }else{
+ pointSet = this._selected.cell.concat(this._selected[type]).concat(pointSet).concat(
+ [this._lastAnchorPoint.cell, this._lastEndPoint.cell,
+ this._lastSelectedAnchorPoint.cell, this._lastSelectedEndPoint.cell]);
+ array.forEach(pointSet, function(item){
+ if(item && !item.converted){
+ var from = item[type];
+ if(from in mapping){
+ item[type] = mapping[from];
+ }
+ item.converted = true;
+ }
+ });
+ array.forEach(this._selected[_theOther[type]], function(item){
+ for(var i = 0, len = item.except.length; i < len; ++i){
+ var from = item.except[i];
+ if(from in mapping){
+ item.except[i] = mapping[from];
+ }
+ }
+ });
+ }
+
+ array.forEach(pointSet, cleanUp);
+
+ this._refreshSelected(true);
+ this._focusPoint(type, this._lastEndPoint);
+ }catch(e){
+ console.warn("Selector._onInternalRearrange() error",e);
+ }
+ },
+ _onExternalChange: function(type, target){
+ var start = type == "cell" ? target.min : target[0],
+ end = type == "cell" ? target.max : target[target.length - 1];
+ this.selectRange(type, start, end);
+ },
+ _refresh: function(type, toHighlight){
+ if(!this._keyboardSelect[type]){
+ array.forEach(this._selected[type], function(item){
+ this._highlightSingle(type, toHighlight, item, undefined, true);
+ }, this);
+ }
+ },
+ _refreshSelected: function(){
+ this._refresh("col", true);
+ this._refresh("row", true);
+ this._refresh("cell", true);
+ },
+ _initAreas: function(){
+ var g = this.grid, f = g.focus, _this = this,
+ keyboardSelectReady = 1, duringKeyboardSelect = 2,
+ onmove = function(type, createNewEnd, rowStep, colStep, evt){
+ //Keyboard swipe selection is SHIFT + Direction Keys.
+ var ks = _this._keyboardSelect;
+ //Tricky, rely on valid status not being 0.
+ if(evt.shiftKey && ks[type]){
+ if(ks[type] === keyboardSelectReady){
+ if(type === "cell"){
+ var item = _this._lastEndPoint[type];
+ if(f.cell != g.layout.cells[item.col + colStep] || f.rowIndex != item.row + rowStep){
+ ks[type] = 0;
+ return;
+ }
+ }
+ //If selecting is not started, start it
+ _this._startSelect(type, _this._lastAnchorPoint[type], true, false, true);
+ _this._highlight(type, _this._lastEndPoint[type], _this._toSelect);
+ ks[type] = duringKeyboardSelect;
+ }
+ //Highlight to the new end point.
+ var newEnd = createNewEnd(type, rowStep, colStep, evt);
+ if(_this._isValid(type, newEnd, g)){
+ _this._highlight(type, newEnd, _this._toSelect);
+ }
+ _stopEvent(evt);
+ }
+ },
+ onkeydown = function(type, getTarget, evt, isBubble){
+ if(isBubble && _this.selectEnabled() && _this._config[type] != DISABLED){
+ switch(evt.keyCode){
+ case keys.SPACE:
+ //Keyboard single point selection is SPACE.
+ _this._startSelect(type, getTarget(), evt.ctrlKey, evt.shiftKey);
+ _this._endSelect(type);
+ break;
+ case keys.SHIFT:
+ //Keyboard swipe selection starts with SHIFT.
+ if(_this._config[type] == MULTI && _this._isValid(type, _this._lastAnchorPoint[type], g)){
+ //End last selection if any.
+ _this._endSelect(type);
+ _this._keyboardSelect[type] = keyboardSelectReady;
+ _this._usingKeyboard = true;
+ }
+ }
+ }
+ },
+ onkeyup = function(type, evt, isBubble){
+ if(isBubble && evt.keyCode == keys.SHIFT && _this._keyboardSelect[type]){
+ _this._endSelect(type);
+ _this._keyboardSelect[type] = 0;
+ }
+ };
+ //TODO: this area "rowHeader" should be put outside, same level as header/content.
+ if(g.views.views[0] instanceof _RowSelector){
+ this._lastFocusedRowBarIdx = 0;
+ f.addArea({
+ name:"rowHeader",
+ onFocus: function(evt, step){
+ var view = g.views.views[0];
+ if(view instanceof _RowSelector){
+ var rowBarNode = view.getCellNode(_this._lastFocusedRowBarIdx, 0);
+ if(rowBarNode){
+ html.toggleClass(rowBarNode, f.focusClass, false);
+ }
+ //evt might not be real event, it may be a mock object instead.
+ if(evt && "rowIndex" in evt){
+ if(evt.rowIndex >= 0){
+ _this._lastFocusedRowBarIdx = evt.rowIndex;
+ }else if(!_this._lastFocusedRowBarIdx){
+ _this._lastFocusedRowBarIdx = 0;
+ }
+ }
+ rowBarNode = view.getCellNode(_this._lastFocusedRowBarIdx, 0);
+ if(rowBarNode){
+ dijitFocus.focus(rowBarNode);
+ html.toggleClass(rowBarNode, f.focusClass, true);
+ }
+ f.rowIndex = _this._lastFocusedRowBarIdx;
+ _stopEvent(evt);
+ return true;
+ }
+ return false;
+ },
+ onBlur: function(evt, step){
+ var view = g.views.views[0];
+ if(view instanceof _RowSelector){
+ var rowBarNode = view.getCellNode(_this._lastFocusedRowBarIdx, 0);
+ if(rowBarNode){
+ html.toggleClass(rowBarNode, f.focusClass, false);
+ }
+ _stopEvent(evt);
+ }
+ return true;
+ },
+ onMove: function(rowStep, colStep, evt){
+ var view = g.views.views[0];
+ if(rowStep && view instanceof _RowSelector){
+ var next = _this._lastFocusedRowBarIdx + rowStep;
+ if(next >= 0 && next < g.rowCount){
+ //TODO: these logic require a better Scroller.
+ _stopEvent(evt);
+ var rowBarNode = view.getCellNode(_this._lastFocusedRowBarIdx, 0);
+ html.toggleClass(rowBarNode, f.focusClass, false);
+ //If the row is not fetched, fetch it.
+ var sc = g.scroller;
+ var lastPageRow = sc.getLastPageRow(sc.page);
+ var rc = g.rowCount - 1, row = Math.min(rc, next);
+ if(next > lastPageRow){
+ g.setScrollTop(g.scrollTop + sc.findScrollTop(row) - sc.findScrollTop(_this._lastFocusedRowBarIdx));
+ }
+ //Now we have fetched the row.
+ rowBarNode = view.getCellNode(next, 0);
+ dijitFocus.focus(rowBarNode);
+ html.toggleClass(rowBarNode, f.focusClass, true);
+ _this._lastFocusedRowBarIdx = next;
+ //If the row is out of view, scroll to it.
+ f.cell = rowBarNode;
+ f.cell.view = view;
+ f.cell.getNode = function(index){
+ return f.cell;
+ };
+ f.rowIndex = _this._lastFocusedRowBarIdx;
+ f.scrollIntoView();
+ f.cell = null;
+ }
+ }
+ }
+ });
+ f.placeArea("rowHeader","before","content");
+ }
+ //Support keyboard selection.
+ f.addArea({
+ name:"cellselect",
+ onMove: lang.partial(onmove, "cell", function(type, rowStep, colStep, evt){
+ var current = _this._currentPoint[type];
+ return _createItem("cell", current.row + rowStep, current.col + colStep);
+ }),
+ onKeyDown: lang.partial(onkeydown, "cell", function(){
+ return _createItem("cell", f.rowIndex, f.cell.index);
+ }),
+ onKeyUp: lang.partial(onkeyup, "cell")
+ });
+ f.placeArea("cellselect","below","content");
+ f.addArea({
+ name:"colselect",
+ onMove: lang.partial(onmove, "col", function(type, rowStep, colStep, evt){
+ var current = _this._currentPoint[type];
+ return _createItem("col", current.col + colStep);
+ }),
+ onKeyDown: lang.partial(onkeydown, "col", function(){
+ return _createItem("col", f.getHeaderIndex());
+ }),
+ onKeyUp: lang.partial(onkeyup, "col")
+ });
+ f.placeArea("colselect","below","header");
+ f.addArea({
+ name:"rowselect",
+ onMove: lang.partial(onmove, "row", function(type, rowStep, colStep, evt){
+ return _createItem("row", f.rowIndex);
+ }),
+ onKeyDown: lang.partial(onkeydown, "row", function(){
+ return _createItem("row", f.rowIndex);
+ }),
+ onKeyUp: lang.partial(onkeyup, "row")
+ });
+ f.placeArea("rowselect","below","rowHeader");
+ },
+ _clearSelection: function(type, reservedItem){
+ // summary:
+ // Clear selection for given type and fire events, but retain the highlight for *reservedItem*,
+ // thus avoid "flashing".
+ // tag:
+ // private
+ // type: String
+ // "row", "col", or "cell
+ // reservedItem: __SelectItem
+ // The item to retain highlight.
+ if(type == "all"){
+ this._clearSelection("cell", reservedItem);
+ this._clearSelection("col", reservedItem);
+ this._clearSelection("row", reservedItem);
+ return;
+ }
+ this._isUsingRowSelector = true;
+ array.forEach(this._selected[type], function(item){
+ if(!_isEqual(type, reservedItem, item)){
+ this._highlightSingle(type, false, item);
+ }
+ }, this);
+ this._blurPoint(type, this._currentPoint);
+ this._selecting[type] = false;
+ this._startPoint[type] = this._currentPoint[type] = null;
+ this._selected[type] = [];
+
+ //Have to also deselect default grid selection.
+ if(type == "row" && !this.grid._selectingRange){
+ this._oldDeselectAll.call(this.grid.selection);
+ this.grid.selection._selectedById = {};
+ }
+
+ //Fire events.
+ this.grid.onEndDeselect(type, null, null, this._selected);
+ this.grid.onSelectCleared(type);
+ },
+ _startSelect: function(type, start, extending, isRange, mandatarySelect, toSelect){
+ // summary:
+ // Start selection, setup start point and current point, fire events.
+ // tag:
+ // private
+ // type: String
+ // "row", "col", or "cell"
+ // extending: Boolean
+ // Whether this is a multi selection
+ // isRange: Boolean
+ // Whether this is a range selection (i.e. select from the last end point to this point)
+ // start: __SelectItem
+ // The start point
+ // mandatarySelect: Boolean
+ // If true, toSelect will be same as the original selection status.
+ if(!this._isValid(type, start)){
+ return;
+ }
+ var lastIsSelected = this._isSelected(type, this._lastEndPoint[type]),
+ isSelected = this._isSelected(type, start);
+
+ if(this.noClear && !extending){
+ this._toSelect = toSelect === undefined ? true : toSelect;
+ }else{
+ //If we are modifying the selection using keyboard, retain the old status.
+ this._toSelect = mandatarySelect ? isSelected : !isSelected;
+ }
+
+ //If CTRL is not pressed or it's SINGLE mode, this is a brand new selection.
+ if(!extending || (!isSelected && this._config[type] == SINGLE)){
+ this._clearSelection("col", start);
+ this._clearSelection("cell", start);
+ if(!this.noClear || (type === 'row' && this._config[type] == SINGLE)){
+ this._clearSelection('row', start);
+ }
+ this._toSelect = toSelect === undefined ? true : toSelect;
+ }
+
+ this._selecting[type] = true;
+ this._currentPoint[type] = null;
+
+ //We're holding SHIFT while clicking, it's a Click-Range selection.
+ if(isRange && this._lastType == type && lastIsSelected == this._toSelect && this._config[type] == MULTI){
+ if(type === "row"){
+ this._isUsingRowSelector = true;
+ }
+ this._startPoint[type] = this._lastEndPoint[type];
+ this._highlight(type, this._startPoint[type]);
+ this._isUsingRowSelector = false;
+ }else{
+ this._startPoint[type] = start;
+ }
+ //Now start selection
+ this._curType = type;
+ this._fireEvent("start", type);
+ this._isStartFocus = true;
+ this._isUsingRowSelector = true;
+ this._highlight(type, start, this._toSelect);
+ this._isStartFocus = false;
+ },
+ _endSelect: function(type){
+ // summary:
+ // End selection. Keep records, fire events and cleanup status.
+ // tag:
+ // private
+ // type: String
+ // "row", "col", or "cell"
+ if(type === "row"){
+ delete this._isUsingRowSelector;
+ }
+ if(type == "all"){
+ this._endSelect("col");
+ this._endSelect("row");
+ this._endSelect("cell");
+ }else if(this._selecting[type]){
+ this._addToSelected(type);
+ this._lastAnchorPoint[type] = this._startPoint[type];
+ this._lastEndPoint[type] = this._currentPoint[type];
+ if(this._toSelect){
+ this._lastSelectedAnchorPoint[type] = this._lastAnchorPoint[type];
+ this._lastSelectedEndPoint[type] = this._lastEndPoint[type];
+ }
+ this._startPoint[type] = this._currentPoint[type] = null;
+ this._selecting[type] = false;
+ this._lastType = type;
+ this._fireEvent("end", type);
+ }
+ },
+ _fireEvent: function(evtName, type){
+ switch(evtName){
+ case "start":
+ this.grid[this._toSelect ? "onStartSelect" : "onStartDeselect"](type, this._startPoint[type], this._selected);
+ break;
+ case "end":
+ this.grid[this._toSelect ? "onEndSelect" : "onEndDeselect"](type, this._lastAnchorPoint[type], this._lastEndPoint[type], this._selected);
+ break;
+ }
+ },
+ _calcToHighlight: function(type, target, toHighlight, toSelect){
+ // summary:
+ // Calculate what status should *target* have.
+ // If *toSelect* is not provided, this is a no op.
+ // This function is time-critical!!
+ if(toSelect !== undefined){
+ var sltd;
+ if(this._usingKeyboard && !toHighlight){
+ var last = this._isInLastRange(this._lastType, target);
+ if(last){
+ sltd = this._isSelected(type, target);
+ //This 2 cases makes the keyboard swipe selection valid!
+ if(toSelect && sltd){
+ return false;
+ }
+ if(!toSelect && !sltd && this._isInLastRange(this._lastType, target, true)){
+ return true;
+ }
+ }
+ }
+ return toHighlight ? toSelect : (sltd || this._isSelected(type, target));
+ }
+ return toHighlight;
+ },
+ _highlightNode: function(node, toHighlight){
+ // summary:
+ // Do the actual highlight work.
+ if(node){
+ var selectCSSClass = "dojoxGridRowSelected";
+ var selectCellClass = "dojoxGridCellSelected";
+ html.toggleClass(node, selectCSSClass, toHighlight);
+ html.toggleClass(node, selectCellClass, toHighlight);
+ }
+ },
+ _highlightHeader: function(colIdx, toHighlight){
+ var cells = this.grid.layout.cells;
+ var node = cells[colIdx].getHeaderNode();
+ var selectedClass = "dojoxGridHeaderSelected";
+ html.toggleClass(node, selectedClass, toHighlight);
+ },
+ _highlightRowSelector: function(rowIdx, toHighlight){
+ //var t1 = (new Date()).getTime();
+ var rowSelector = this.grid.views.views[0];
+ if(rowSelector instanceof _RowSelector){
+ var node = rowSelector.getRowNode(rowIdx);
+ if(node){
+ var selectedClass = "dojoxGridRowSelectorSelected";
+ html.toggleClass(node, selectedClass, toHighlight);
+ }
+ }
+ //console.log((new Date()).getTime() - t1);
+ },
+ _highlightSingle: function(type, toHighlight, target, toSelect, isRefresh){
+ // summary:
+ // Highlight a single item.
+ // This function is time critical!!
+ var _this = this, toHL, g = _this.grid, cells = g.layout.cells;
+ switch(type){
+ case "cell":
+ toHL = this._calcToHighlight(type, target, toHighlight, toSelect);
+ var c = cells[target.col];
+ if(!c.hidden && !c.notselectable){
+ this._highlightNode(target.node || c.getNode(target.row), toHL);
+ }
+ break;
+ case "col":
+ toHL = this._calcToHighlight(type, target, toHighlight, toSelect);
+ this._highlightHeader(target.col, toHL);
+ query("td[idx='" + target.col + "']", g.domNode).forEach(function(cellNode){
+ var rowNode = cells[target.col].view.content.findRowTarget(cellNode);
+ if(rowNode){
+ var rowIndex = rowNode[dojox.grid.util.rowIndexTag];
+ _this._highlightSingle("cell", toHL, {
+ "row": rowIndex,
+ "col": target.col,
+ "node": cellNode
+ });
+ }
+ });
+ break;
+ case "row":
+ toHL = this._calcToHighlight(type, target, toHighlight, toSelect);
+ this._highlightRowSelector(target.row, toHL);
+ if(this._config.cell){
+ array.forEach(cells, function(cell){
+ _this._highlightSingle("cell", toHL, {
+ "row": target.row,
+ "col": cell.index,
+ "node": cell.getNode(target.row)
+ });
+ });
+ }
+ //To avoid dead lock
+ this._selectedRowModified = true;
+ if(!isRefresh){
+ g.selection.setSelected(target.row, toHL);
+ }
+ }
+ },
+ _highlight: function(type, target, toSelect){
+ // summary:
+ // Highlight from start point to target.
+ // toSelect: Boolean
+ // Whether we are selecting or deselecting.
+ // This function is time critical!!
+ if(this._selecting[type] && target !== null){
+ var start = this._startPoint[type],
+ current = this._currentPoint[type],
+ _this = this,
+ highlight = function(from, to, toHL){
+ _this._forEach(type, from, to, function(item){
+ _this._highlightSingle(type, toHL, item, toSelect);
+ }, true);
+ };
+ switch(type){
+ case "col": case "row":
+ if(current !== null){
+ if(_inRange(type, target, start, current, true)){
+ //target is between start and current, some selected should be deselected.
+ highlight(current, target, false);
+ }else{
+ if(_inRange(type, start, target, current, true)){
+ //selection has jumped to different direction, all should be deselected.
+ highlight(current, start, false);
+ current = start;
+ }
+ highlight(target, current, true);
+ }
+ }else{
+ //First time select.
+ this._highlightSingle(type, true, target, toSelect);
+ }
+ break;
+ case "cell":
+ if(current !== null){
+ if(_inRange("row", target, start, current, true) ||
+ _inRange("col", target, start, current, true) ||
+ _inRange("row", start, target, current, true) ||
+ _inRange("col", start, target, current, true)){
+ highlight(start, current, false);
+ }
+ }
+ highlight(start, target, true);
+ }
+ this._currentPoint[type] = target;
+ this._focusPoint(type, this._currentPoint);
+ }
+ },
+ _focusPoint: function(type, point){
+ // summary:
+ // Focus the current point, so when you move mouse, the focus indicator follows you.
+ if(!this._isStartFocus){
+ var current = point[type],
+ f = this.grid.focus;
+ if(type == "col"){
+ f._colHeadFocusIdx = current.col;
+ f.focusArea("header");
+ }else if(type == "row"){
+ f.focusArea("rowHeader", {
+ "rowIndex": current.row
+ });
+ }else if(type == "cell"){
+ f.setFocusIndex(current.row, current.col);
+ }
+ }
+ },
+ _blurPoint: function(type, point){
+ // summary:
+ // Blur the current point.
+ var f = this.grid.focus;
+ if(type == "col"){
+ f._blurHeader();
+ }else if(type == "cell"){
+ f._blurContent();
+ }
+ },
+ _addToSelected: function(type){
+ // summary:
+ // Record the selected items.
+ var toSelect = this._toSelect, _this = this,
+ toAdd = [], toRemove = [],
+ start = this._startPoint[type],
+ end = this._currentPoint[type];
+ if(this._usingKeyboard){
+ //If using keyboard, selection will be ended after every move. But we have to remember the original selection status,
+ //so as to return to correct status when we shrink the selection region.
+ this._forEach(type, this._lastAnchorPoint[type], this._lastEndPoint[type], function(item){
+ //If the original selected item is not in current range, change its status.
+ if(!_inRange(type, item, start, end)){
+ (toSelect ? toRemove : toAdd).push(item);
+ }
+ });
+ }
+ this._forEach(type, start, end, function(item){
+ var isSelected = _this._isSelected(type, item);
+ if(toSelect && !isSelected){
+ //Add new selected items
+ toAdd.push(item);
+ }else if(!toSelect){
+ //Remove deselected items.
+ toRemove.push(item);
+ }
+ });
+ this._add(type, toAdd);
+ this._remove(type, toRemove);
+
+ // have to keep record in original grid selection
+ array.forEach(this._selected.row, function(item){
+ if(item.except.length > 0){
+ //to avoid dead lock
+ this._selectedRowModified = true;
+ this.grid.selection.setSelected(item.row, false);
+ }
+ }, this);
+ },
+ _forEach: function(type, start, end, func, halfClose){
+ // summary:
+ // Go through items from *start* point to *end* point.
+ // This function is time critical!!
+ if(!this._isValid(type, start, true) || !this._isValid(type, end, true)){
+ return;
+ }
+ switch(type){
+ case "col": case "row":
+ start = start[type];
+ end = end[type];
+ var dir = end > start ? 1 : -1;
+ if(!halfClose){
+ end += dir;
+ }
+ for(; start != end; start += dir){
+ func(_createItem(type, start));
+ }
+ break;
+ case "cell":
+ var colDir = end.col > start.col ? 1 : -1,
+ rowDir = end.row > start.row ? 1 : -1;
+ for(var i = start.row, p = end.row + rowDir; i != p; i += rowDir){
+ for(var j = start.col, q = end.col + colDir; j != q; j += colDir){
+ func(_createItem(type, i, j));
+ }
+ }
+ }
+ },
+ _makeupForExceptions: function(type, newCellItems){
+ // summary:
+ // When new cells is selected, maybe they will fill in the "holes" in selected rows and columns.
+ var makedUps = [];
+ array.forEach(this._selected[type], function(v1){
+ array.forEach(newCellItems, function(v2){
+ if(v1[type] == v2[type]){
+ var pos = array.indexOf(v1.except, v2[_theOther[type]]);
+ if(pos >= 0){
+ v1.except.splice(pos, 1);
+ }
+ makedUps.push(v2);
+ }
+ });
+ });
+ return makedUps;
+ },
+ _makeupForCells: function(type, newItems){
+ // summary:
+ // When some rows/cols are selected, maybe they can cover some of the selected cells,
+ // and fill some of the "holes" in the selected cols/rows.
+ var toRemove = [];
+ array.forEach(this._selected.cell, function(v1){
+ array.some(newItems, function(v2){
+ if(v1[type] == v2[type]){
+ toRemove.push(v1);
+ return true;
+ }
+ return false;
+ });
+ });
+ this._remove("cell", toRemove);
+ array.forEach(this._selected[_theOther[type]], function(v1){
+ array.forEach(newItems, function(v2){
+ var pos = array.indexOf(v1.except, v2[type]);
+ if(pos >= 0){
+ v1.except.splice(pos, 1);
+ }
+ });
+ });
+ },
+ _addException: function(type, items){
+ // summary:
+ // If some rows/cols are deselected, maybe they have created "holes" in selected cols/rows.
+ array.forEach(this._selected[type], function(v1){
+ array.forEach(items, function(v2){
+ v1.except.push(v2[_theOther[type]]);
+ });
+ });
+ },
+ _addCellException: function(type, items){
+ // summary:
+ // If some cells are deselected, maybe they have created "holes" in selected rows/cols.
+ array.forEach(this._selected[type], function(v1){
+ array.forEach(items, function(v2){
+ if(v1[type] == v2[type]){
+ v1.except.push(v2[_theOther[type]]);
+ }
+ });
+ });
+ },
+ _add: function(type, items){
+ // summary:
+ // Add to the selection record.
+ var cells = this.grid.layout.cells;
+ if(type == "cell"){
+ var colMakedup = this._makeupForExceptions("col", items);
+ var rowMakedup = this._makeupForExceptions("row", items);
+ //Step over hidden columns.
+ items = array.filter(items, function(item){
+ return array.indexOf(colMakedup, item) < 0 && array.indexOf(rowMakedup, item) < 0 &&
+ !cells[item.col].hidden && !cells[item.col].notselectable;
+ });
+ }else{
+ if(type == "col"){
+ //Step over hidden columns.
+ items = array.filter(items, function(item){
+ return !cells[item.col].hidden && !cells[item.col].notselectable;
+ });
+ }
+ this._makeupForCells(type, items);
+ this._selected[type] = array.filter(this._selected[type], function(v){
+ return array.every(items, function(item){
+ return v[type] !== item[type];
+ });
+ });
+ }
+ if(type != "col" && this.grid._hasIdentity){
+ array.forEach(items, function(item){
+ var record = this.grid._by_idx[item.row];
+ if(record){
+ item.id = record.idty;
+ }
+ }, this);
+ }
+ this._selected[type] = this._selected[type].concat(items);
+ },
+ _remove: function(type, items){
+ // summary:
+ // Remove from the selection record.
+ var comp = lang.partial(_isEqual, type);
+ this._selected[type] = array.filter(this._selected[type], function(v1){
+ return !array.some(items, function(v2){
+ return comp(v1, v2);
+ });
+ });
+ if(type == "cell"){
+ this._addCellException("col", items);
+ this._addCellException("row", items);
+ }else if(this._config.cell){
+ this._addException(_theOther[type], items);
+ }
+ },
+ _isCellNotInExcept: function(type, item){
+ // summary:
+ // Return true only when a cell is covered by selected row/col, and its not a "hole".
+ var attr = item[type], corres = item[_theOther[type]];
+ return array.some(this._selected[type], function(v){
+ return v[type] == attr && array.indexOf(v.except, corres) < 0;
+ });
+ },
+ _isSelected: function(type, item){
+ // summary:
+ // Return true when the item is selected. (or logically selected, i.e, covered by a row/col).
+ if(!item){ return false; }
+ var res = array.some(this._selected[type], function(v){
+ var ret = _isEqual(type, item, v);
+ if(ret && type !== "cell"){
+ return v.except.length === 0;
+ }
+ return ret;
+ });
+ if(!res && type === "cell"){
+ res = (this._isCellNotInExcept("col", item) || this._isCellNotInExcept("row", item));
+ if(type === "cell"){
+ res = res && !this.grid.layout.cells[item.col].notselectable;
+ }
+ }
+ return res;
+ },
+ _isInLastRange: function(type, item, isSelected){
+ // summary:
+ // Return true only when the item is in the last seletion/deseletion range.
+ var start = this[isSelected ? "_lastSelectedAnchorPoint" : "_lastAnchorPoint"][type],
+ end = this[isSelected ? "_lastSelectedEndPoint" : "_lastEndPoint"][type];
+ if(!item || !start || !end){ return false; }
+ return _inRange(type, item, start, end);
+ },
+ _isValid: function(type, item, allowNotSelectable){
+ // summary:
+ // Check whether the item is a valid __SelectItem for the given type.
+ if(!item){ return false; }
+ try{
+ var g = this.grid, index = item[type];
+ switch(type){
+ case "col":
+ return index >= 0 && index < g.layout.cells.length && lang.isArray(item.except) &&
+ (allowNotSelectable || !g.layout.cells[index].notselectable);
+ case "row":
+ return index >= 0 && index < g.rowCount && lang.isArray(item.except);
+ case "cell":
+ return item.col >= 0 && item.col < g.layout.cells.length &&
+ item.row >= 0 && item.row < g.rowCount &&
+ (allowNotSelectable || !g.layout.cells[item.col].notselectable);
+ }
+ }catch(e){}
+ return false;
+ }
+});
+
+EnhancedGrid.registerPlugin(Selector/*name:'selector'*/, {
+ "dependency": ["autoScroll"]
+});
+
+return Selector;
+
+}); \ No newline at end of file
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/_RowMapLayer.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/_RowMapLayer.js
new file mode 100644
index 0000000..bf19ce3
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/_RowMapLayer.js
@@ -0,0 +1,207 @@
+//>>built
+define("dojox/grid/enhanced/plugins/_RowMapLayer", [
+ "dojo/_base/declare",
+ "dojo/_base/array",
+ "dojo/_base/lang",
+ "./_StoreLayer"
+], function(declare, array, lang, layers){
+
+var _devideToArrays = function(a){
+ a.sort(function(v1, v2){
+ return v1 - v2;
+ });
+ var arr = [[a[0]]];
+ for(var i = 1, j = 0; i < a.length; ++i){
+ if(a[i] == a[i-1] + 1){
+ arr[j].push(a[i]);
+ }else{
+ arr[++j] = [a[i]];
+ }
+ }
+ return arr;
+},
+hitchIfCan = function(scope, func){
+ return func ? lang.hitch(scope || lang.global, func) : function(){};
+};
+
+return declare("dojox.grid.enhanced.plugins._RowMapLayer", layers._StoreLayer, {
+ tags: ["reorder"],
+ constructor: function(grid){
+ this._map = {};
+ this._revMap = {};
+ this.grid = grid;
+ this._oldOnDelete = grid._onDelete;
+ var _this = this;
+ grid._onDelete = function(item){
+ _this._onDelete(item);
+ _this._oldOnDelete.call(grid, item);
+ };
+ this._oldSort = grid.sort;
+ grid.sort = function(){
+ _this.clearMapping();
+ _this._oldSort.apply(grid, arguments);
+ };
+ },
+ uninitialize: function(){
+ this.grid._onDelete = this._oldOnDelete;
+ this.grid.sort = this._oldSort;
+ },
+ setMapping: function(mapping){
+ // summary:
+ // Remember the row mapping.
+ // mapping: Object
+ // keys are original rowIndexes, values are new rowIndexes.
+ this._store.forEachLayer(function(layer){
+ if(layer.name() === "rowmap"){
+ return false;
+ }else if(layer.onRowMappingChange){
+ layer.onRowMappingChange(mapping);
+ }
+ return true;
+ }, false);
+ var from, to, origin, revmap = {};
+ for(from in mapping){
+ from = parseInt(from, 10);
+ to = mapping[from];
+ if(typeof to == "number"){
+ if(from in this._revMap){
+ origin = this._revMap[from];
+ delete this._revMap[from];
+ }else{
+ origin = from;
+ }
+ if(origin == to){
+ delete this._map[origin];
+ revmap[to] = "eq";
+ }else{
+ this._map[origin] = to;
+ revmap[to] = origin;
+ }
+ }
+ }
+ for(to in revmap){
+ if(revmap[to] === "eq"){
+ delete this._revMap[parseInt(to, 10)];
+ }else{
+ this._revMap[parseInt(to, 10)] = revmap[to];
+ }
+ }
+ },
+ clearMapping: function(){
+ this._map = {};
+ this._revMap = {};
+ },
+ _onDelete: function(item){
+ var idx = this.grid._getItemIndex(item, true);
+ if(idx in this._revMap){
+ var rowIdxArr = [], r, i, origin = this._revMap[idx];
+ delete this._map[origin];
+ delete this._revMap[idx];
+ for(r in this._revMap){
+ r = parseInt(r, 10);
+ if(this._revMap[r] > origin){
+ --this._revMap[r];
+ }
+ }
+ for(r in this._revMap){
+ r = parseInt(r, 10);
+ if(r > idx){
+ rowIdxArr.push(r);
+ }
+ }
+ rowIdxArr.sort(function(a, b){
+ return b - a;
+ });
+ for(i = rowIdxArr.length - 1; i >= 0; --i){
+ r = rowIdxArr[i];
+ this._revMap[r - 1] = this._revMap[r];
+ delete this._revMap[r];
+ }
+ this._map = {};
+ for(r in this._revMap){
+ this._map[this._revMap[r]] = r;
+ }
+ }
+ },
+ _fetch: function(userRequest){
+ var mapCount = 0, r;
+ var start = userRequest.start || 0;
+ for(r in this._revMap){
+ r = parseInt(r, 10);
+ if(r >= start){
+ ++mapCount;
+ }
+ }
+ if(mapCount > 0){
+ //Row mapping is in use.
+ var rows = [], i, map = {},
+ count = userRequest.count > 0 ? userRequest.count : -1;
+ if(count > 0){
+ for(i = 0; i < count; ++i){
+ r = start + i;
+ r = r in this._revMap ? this._revMap[r] : r;
+ map[r] = i;
+ rows.push(r);
+ }
+ }else{
+ //We don't have a count, must create our own.
+ for(i = 0;; ++i){
+ r = start + i;
+ if(r in this._revMap){
+ --mapCount;
+ r = this._revMap[r];
+ }
+ map[r] = i;
+ rows.push(r);
+ if(mapCount <= 0){
+ break;
+ }
+ }
+ }
+ this._subFetch(userRequest, this._getRowArrays(rows), 0, [], map, userRequest.onComplete, start, count);
+ return userRequest;
+ }else{
+ //No row mapping at all.
+ return lang.hitch(this._store, this._originFetch)(userRequest);
+ }
+ },
+ _getRowArrays: function(rows){
+ return _devideToArrays(rows);
+ },
+ _subFetch: function(userRequest, rowArrays, index, result, map, oldOnComplete, start, count){
+ var arr = rowArrays[index], _this = this;
+ var urstart = userRequest.start = arr[0];
+ userRequest.count = arr[arr.length - 1] - arr[0] + 1;
+ userRequest.onComplete = function(items){
+ array.forEach(items, function(item, i){
+ var r = urstart + i;
+ if(r in map){
+ result[map[r]] = item;
+ }
+ });
+ if(++index == rowArrays.length){
+ //mapped rows are all fetched.
+ if(count > 0){
+ userRequest.start = start;
+ userRequest.count = count;
+ userRequest.onComplete = oldOnComplete;
+ hitchIfCan(userRequest.scope, oldOnComplete)(result, userRequest);
+ }else{
+ userRequest.start = userRequest.start + items.length;
+ delete userRequest.count;
+ userRequest.onComplete = function(items){
+ result = result.concat(items);
+ userRequest.start = start;
+ userRequest.onComplete = oldOnComplete;
+ hitchIfCan(userRequest.scope, oldOnComplete)(result, userRequest);
+ };
+ _this.originFetch(userRequest);
+ }
+ }else{
+ _this._subFetch(userRequest, rowArrays, index, result, map, oldOnComplete, start, count);
+ }
+ };
+ _this.originFetch(userRequest);
+ }
+});
+});
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/_SelectionPreserver.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/_SelectionPreserver.js
new file mode 100644
index 0000000..dff96c1
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/_SelectionPreserver.js
@@ -0,0 +1,109 @@
+//>>built
+define("dojox/grid/enhanced/plugins/_SelectionPreserver", [
+ "dojo/_base/declare",
+ "dojo/_base/lang",
+ "dojo/_base/connect",
+ '../../_SelectionPreserver'
+], function(declare, lang, connect, _SelectionPreserver){
+
+return declare("dojox.grid.enhanced.plugins._SelectionPreserver", _SelectionPreserver, {
+ // summary:
+ // Preserve selections across various user actions.
+ //
+ // description:
+ // Extends dojox.grid._SelectionPreserver adding a bit more support to make selection persistence working well
+ // with various EnhancedGrid features, e.g. filtering, nested sorting, pagination, select all etc.
+ //
+ // Precondition - Identifier(id) is required for store, as id is used for differentiating row items.
+ // Known issue - The preserved selections might be inaccurate if some unloaded rows are previously selected by range(e.g.SHIFT + click)
+ //
+ // example:
+ // | //To turn on this - set 'keepSelection' attribute to true
+ // | <div dojoType="dojox.grid.EnhancedGrid" keepSelection = true .../>
+
+ constructor: function(selection){
+ var grid = this.grid;
+ grid.onSelectedById = this.onSelectedById;
+ this._oldClearData = grid._clearData;
+ var self = this;
+ grid._clearData = function(){
+ self._updateMapping(!grid._noInternalMapping);
+ self._trustSelection = [];
+ self._oldClearData.apply(grid, arguments);
+ };
+ this._connects.push(
+ connect.connect(selection, 'selectRange', lang.hitch(this, '_updateMapping', true, true, false)),
+ connect.connect(selection, 'deselectRange', lang.hitch(this, '_updateMapping', true, false, false)),
+ connect.connect(selection, 'deselectAll', lang.hitch(this, '_updateMapping', true, false, true))
+ );
+ },
+ destroy: function(){
+ this.inherited(arguments);
+ this.grid._clearData = this._oldClearData;
+ },
+ reset: function(){
+ this.inherited(arguments);
+ this._idMap = [];
+ this._trustSelection = [];
+ this._defaultSelected = false;
+ },
+ _reSelectById: function(item, index){
+ // summary:
+ // Overwritten
+ var s = this.selection, g = this.grid;
+ if(item && g._hasIdentity){
+ var id = g.store.getIdentity(item);
+ if(this._selectedById[id] === undefined){
+ if(!this._trustSelection[index]){
+ s.selected[index] = this._defaultSelected;
+ }
+ }else{
+ s.selected[index] = this._selectedById[id];
+ }
+ this._idMap.push(id);
+ g.onSelectedById(id, index, s.selected[index]);
+ }
+ },
+ _selectById: function(toSelect, inItemOrIndex){
+ // summary:
+ // Overwritten
+ if(!this.inherited(arguments)){
+ this._trustSelection[inItemOrIndex] = true;
+ }
+ },
+ onSelectedById: function(id, rowIndex, value){},
+
+ _updateMapping: function(trustSelection, isSelect, isForAll, from, to){
+ // summary:
+ // This function try to keep the selection info updated when range selection is performed.
+ // 1. Calculate how many unloaded rows are there;
+ // 2. update _selectedById data if grid.selection._selected can be trusted, so loaded but unselected rows can
+ // be properly recorded.
+ var s = this.selection, g = this.grid, flag = 0, unloaded = 0, i, id;
+ for(i = g.rowCount - 1; i >= 0; --i){
+ if(!g._by_idx[i]){
+ ++unloaded;
+ flag += s.selected[i] ? 1 : -1;
+ }else{
+ id = g._by_idx[i].idty;
+ if(id && (trustSelection || this._selectedById[id] === undefined)){
+ this._selectedById[id] = !!s.selected[i];
+ }
+ }
+ }
+ if(unloaded){
+ this._defaultSelected = flag > 0;
+ }
+ if(!isForAll && from !== undefined && to !== undefined){
+ isForAll = !g.usingPagination && Math.abs(to - from + 1) === g.rowCount;
+ }
+ // When deselectAll, make sure every thing is deselected, even if it was selected but not loaded now.
+ // This occurs only when pagination's "All" is used.
+ if(isForAll && (!g.usingPagination || g.selectionMode === 'single')){
+ for(i = this._idMap.length - 1; i >= 0; --i){
+ this._selectedById[this._idMap[i]] = isSelect;
+ }
+ }
+ }
+});
+});
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/_StoreLayer.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/_StoreLayer.js
new file mode 100644
index 0000000..bf73a6d
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/_StoreLayer.js
@@ -0,0 +1,395 @@
+//>>built
+define("dojox/grid/enhanced/plugins/_StoreLayer", [
+ "dojo/_base/declare",
+ "dojo/_base/array",
+ "dojo/_base/lang",
+ "dojo/_base/xhr"
+], function(declare, array, lang, xhr){
+// summary:
+// The dojo.data.api.Read API is powerful, but it's difficult to give the store some special commands before
+// fetch, so that the store content can be temporarily modified or transformed, and acts as another store. The
+// parameter *query* or *queryOptions* in keywordArgs for *fetch* is not enough because:
+// 1. users do not have the opportunity to response to the store actions when these options or queries are applied,
+// especially when the real store is at server side.
+// 2. the store implementation must be changed to support any new options in 'query' or 'queryOptions', so it'll be
+// difficult if this implementation is not able to or very hard to be changed, or some new options are required to
+// be valid for all stores.
+// This *StoreLayer* framework is dedicated to provide a uniform way for configuring an existing store, so that
+// it can be easily extended to have special behaviors or act like a totally different store.
+// The major approach is to wrap the *fetch* function of store, layer by layer. Every layer treats the incoming
+// store.fetch as a 'black box', thus maintaining the independence between layers.
+// *fetch* is the most important data retriever in the Read API, almost all other functions are used for a single
+// item, and require that this item is already retrieved (by and only by *fetch*). So once we've controlled this
+// *fetch* function, we've controlled almost the whole store. This fact simplifies our implementation of StoreLayer.
+// example:
+// //ns is for namespace, i.e.:dojox.grid.enhanced.plugins
+// ns.wrap(ns.wrap(ns.wrap(store, new ns.FilterLayer()), new ns.UniqueLayer()), new ns.TransformLayer());
+//
+// //every layer has a name, it should be given in the document of this layer.
+// //if you don't know it's name, you can get it by: ns.SomeLayer.prototype.name();
+// store.layer("filter").filterDef(...);
+// store.layer("unique").setUniqueColumns(...);
+// store.layer("transform").setScheme(...);
+//
+// //now use the store as usual...
+//
+// store.unwrap("transform"); //remove the transform layer but retain the other two.
+//
+// //now use the store as usual...
+//
+// store.unwrap(); //remove all the layers, get the original store back.
+
+ var ns = lang.getObject("grid.enhanced.plugins", true, dojox);
+
+ var getPrevTags = function(tags){
+ var tagList = ["reorder", "sizeChange", "normal", "presentation"];
+ var idx = tagList.length;
+ for(var i = tags.length - 1; i >= 0; --i){
+ var p = array.indexOf(tagList, tags[i]);
+ if(p >= 0 && p <= idx){
+ idx = p;
+ }
+ }
+ if(idx < tagList.length - 1){
+ return tagList.slice(0, idx + 1);
+ }else{
+ return tagList;
+ }
+ },
+
+ unwrap = function(/* string? */layerName){
+ // summary:
+ // Unwrap the layers of the store
+ // tags:
+ // public
+ // returns:
+ // The unwrapped store, for nested use only.
+ var i, layers = this._layers, len = layers.length;
+ if(layerName){
+ for(i = len-1; i >= 0; --i){
+ if(layers[i].name() == layerName){
+ layers[i]._unwrap(layers[i + 1]);
+ break;
+ }
+ }
+ layers.splice(i, 1);
+ }else{
+ for(i = len - 1; i >= 0; --i){
+ layers[i]._unwrap();
+ }
+ }
+ if(!layers.length){
+ delete this._layers;
+ delete this.layer;
+ delete this.unwrap;
+ delete this.forEachLayer;
+ }
+ //console.log("layers:",this._layers);
+ return this; //Read-store
+ },
+
+ getLayer = function(layerName){
+ // summary:
+ // Get a layer of the store, so we can configure that layer.
+ // tags:
+ // public (scope is store)
+ // layerName: string
+ // the name of the layer
+ // returns:
+ // the store layer object
+ var i, layers = this._layers;
+ if(typeof layerName == "undefined"){
+ return layers.length; //Integer
+ }
+ if(typeof layerName == "number"){
+ return layers[layerName]; //_StoreLayer
+ }
+ for(i = layers.length - 1; i >= 0; --i){
+ if(layers[i].name() == layerName){
+ return layers[i]; //_StoreLayer
+ }
+ }
+ return null; //_StoreLayer
+ },
+
+ forEachLayer = function(callback, isInnerToOuter){
+ // summary:
+ // Visit the layers one by one. From the outer most to inner most by default.
+ // callback: Function
+ // The function to callback.
+ // If return false, break the loop.
+ // isInnerToOuter: Boolean
+ // Whether visit from the inner most layer to the outer most layer.
+ var len = this._layers.length, start, end, dir;
+ if(isInnerToOuter){
+ start = 0;
+ end = len;
+ dir = 1;
+ }else{
+ start = len - 1;
+ end = -1;
+ dir = -1;
+ }
+ for(var i = start; i != end; i += dir){
+ if(callback(this._layers[i], i) === false){
+ return i;
+ }
+ }
+ return end;
+ };
+ ns.wrap = function(store, funcName, layer, layerFuncName){
+ // summary:
+ // Wrap the store with the given layer.
+ // tags:
+ // public
+ // store: Read-store
+ // The store to be wrapped.
+ // layer: _StoreLayer
+ // The layer to be used
+ // returns
+ // The wrapped store, for nested use only.
+ if(!store._layers){
+ store._layers = [];
+ store.layer = lang.hitch(store, getLayer);
+ store.unwrap = lang.hitch(store, unwrap);
+ store.forEachLayer = lang.hitch(store, forEachLayer);
+ }
+ var prevTags = getPrevTags(layer.tags);
+ if(!array.some(store._layers, function(lyr, i){
+ if(array.some(lyr.tags, function(tag){
+ return array.indexOf(prevTags, tag) >= 0;
+ })){
+ return false;
+ }else{
+ store._layers.splice(i, 0, layer);
+ layer._wrap(store, funcName, layerFuncName, lyr);
+ return true;
+ }
+ })){
+ store._layers.push(layer);
+ layer._wrap(store, funcName, layerFuncName);
+ }
+ //console.log("wrapped layers:", dojo.map(store._layers, function(lyr){return lyr.name();}));
+ return store; //Read-store
+ };
+
+ var _StoreLayer = declare("dojox.grid.enhanced.plugins._StoreLayer", null, {
+ // summary:
+ // The most abstract class of store layers, provides basic utilities and some interfaces.
+ // tags:
+ // abstract
+/*=====
+ // _store: [protected] Read-store
+ // The wrapped store.
+ _store: null,
+
+ // _originFetch: [protected] function
+ // The original fetch function of the store.
+ _originFetch: null,
+
+ // __enabled: [private] Boolean
+ // To control whether this layer is valid.
+ __enabled: true,
+=====*/
+ tags: ["normal"],
+
+ layerFuncName: "_fetch",
+
+ constructor: function(){
+ this._store = null;
+ this._originFetch = null;
+ this.__enabled = true;
+ },
+ initialize: function(store){
+ // summary:
+ //
+ },
+ uninitialize: function(store){
+ // summary:
+ //
+ },
+ invalidate: function(){
+
+ },
+ _wrap: function(store, funcName, layerFuncName, nextLayer){
+ // summary:
+ // Do the actual wrapping (or 'hacking' if you like) to the store.
+ // tags:
+ // internal
+ // store: Read-store
+ // The store to be wrapped.
+ this._store = store;
+ this._funcName = funcName;
+ var fetchFunc = lang.hitch(this, function(){
+ return (this.enabled() ? this[layerFuncName || this.layerFuncName] : this.originFetch).apply(this, arguments);
+ });
+ if(nextLayer){
+ this._originFetch = nextLayer._originFetch;
+ nextLayer._originFetch = fetchFunc;
+ }else{
+ this._originFetch = store[funcName] || function(){};
+ store[funcName] = fetchFunc;
+ }
+ this.initialize(store);
+ },
+ _unwrap: function(nextLayer){
+ // summary:
+ // Do the actual unwrapping to the store.
+ // tags:
+ // internal
+ // store: Read-store
+ // The store to be unwrapped.
+ this.uninitialize(this._store);
+ if(nextLayer){
+ nextLayer._originFetch = this._originFetch;
+ }else{
+ this._store[this._funcName] = this._originFetch;
+ }
+ this._originFetch = null;
+ this._store = null;
+ },
+ enabled: function(/* bool? */toEnable){
+ // summary:
+ // The get/set function of the enabled status of this layer
+ // tags:
+ // public
+ // toEnable: Boolean?
+ // If given, is a setter, otherwise, it's getter.
+ if(typeof toEnable != "undefined"){
+ this.__enabled = !!toEnable;
+ }
+ return this.__enabled; //Boolean
+ },
+ name: function(){
+ // summary:
+ // Get the name of this store layer.
+ // The default name retrieved from class name, which should have a pattern of "{name}Layer".
+ // If this pattern does not exist, the whole class name will be this layer's name.
+ // It's better to override this method if your class name is too complicated.
+ // tags:
+ // public extension
+ // returns:
+ // The name of this layer.
+ if(!this.__name){
+ var m = this.declaredClass.match(/(?:\.(?:_*)([^\.]+)Layer$)|(?:\.([^\.]+)$)/i);
+ this.__name = m ? (m[1] || m[2]).toLowerCase() : this.declaredClass;
+ }
+ return this.__name;
+ },
+ originFetch: function(){
+ return (lang.hitch(this._store, this._originFetch)).apply(this, arguments);
+ }
+ });
+ var _ServerSideLayer = declare("dojox.grid.enhanced.plugins._ServerSideLayer", _StoreLayer, {
+ // summary:
+ // The most abstract class for all server side store layers.
+ // tags:
+ // abstract
+/*=====
+ // _url: [protected] string
+ // The url of the server
+ _url: "",
+ // __cmds [private] object
+ // The command object to be sent to server.
+ __cmds: {},
+=====*/
+ constructor: function(args){
+ args = args || {};
+ this._url = args.url || "";
+ this._isStateful = !!args.isStateful;
+ this._onUserCommandLoad = args.onCommandLoad || function(){};
+ this.__cmds = {cmdlayer:this.name(), enable:true};
+
+ //Only for stateful server, sending commands before fetch makes sense.
+ this.useCommands(this._isStateful);
+ },
+ enabled: function(/* bool? */toEnable){
+ // summary:
+ // Overrided from _StoreLayer.enabled
+ var res = this.inherited(arguments);
+ this.__cmds.enable = this.__enabled;
+ return res;
+ },
+ useCommands: function(/* bool? */toUse){
+ // summary:
+ // If you only want to modify the user request, instead of sending a separate command
+ // to server before fetch, just call:
+ // this.useCommand(false);
+ // tags:
+ // public
+ // toUse: Boolean?
+ // If provided, it's a setter, otherwise, it's a getter
+ if(typeof toUse != "undefined"){
+ this.__cmds.cmdlayer = (toUse && this._isStateful) ? this.name() : null;
+ }
+ return !!(this.__cmds.cmdlayer); //Boolean
+ },
+ _fetch: function(/* keywordArgs */userRequest){
+ // summary:
+ // Implementation of _StoreLayer._fetch
+ if(this.__cmds.cmdlayer){
+ //We're gonna send command to server before fetch.
+ xhr.post({
+ url: this._url || this._store.url,
+ content: this.__cmds,
+ load: lang.hitch(this, function(responce){
+ this.onCommandLoad(responce, userRequest);
+ this.originFetch(userRequest);
+ }),
+ error: lang.hitch(this, this.onCommandError)
+ });
+ }else{
+ //The user only wants to modify the request object.
+ this.onCommandLoad("", userRequest);
+ this.originFetch(userRequest);
+ }
+ return userRequest; //dojo.data.api.Request
+ },
+ command: function(/* string */cmdName,/* (string|number|bool|...)? */cmdContent){
+ // summary:
+ // get/set a command (a name-value pair)
+ // tags:
+ // public
+ // cmdName: string
+ // The name of the command
+ // cmdContent: anything
+ // The content of the command
+ // returns:
+ // The content of the command if cmdContent is undefined
+ var cmds = this.__cmds;
+ if(cmdContent === null){
+ delete cmds[cmdName];
+ }else if(typeof cmdContent !== "undefined"){
+ cmds[cmdName] = cmdContent;
+ }
+ return cmds[cmdName]; //anything
+ },
+ onCommandLoad: function(/* string */response, /* keywordArgs */userRequest){
+ // summary:
+ // When the server gives back *response* for the commands, you can do something here.
+ // tags:
+ // callback extension
+ // response: string
+ // server response
+ // userRequest: [in|out] dojo.data.api.Request
+ // The request object for *fetch*. You can modify this object according to the *response*
+ // so as to change the behavior of *fetch*
+ this._onUserCommandLoad(this.__cmds, userRequest, response);
+ },
+ onCommandError: function(error){
+ // summary:
+ // handle errors when sending commands.
+ // tags:
+ // callback extension
+ // error: Error
+ console.log(error);
+ throw error;
+ }
+ });
+
+ return {
+ _StoreLayer: _StoreLayer,
+ _ServerSideLayer: _ServerSideLayer,
+ wrap: ns.wrap
+ };
+});
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/exporter/CSVWriter.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/exporter/CSVWriter.js
new file mode 100644
index 0000000..44006e2
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/exporter/CSVWriter.js
@@ -0,0 +1,88 @@
+//>>built
+define("dojox/grid/enhanced/plugins/exporter/CSVWriter", [
+ "dojo/_base/declare",
+ "dojo/_base/array",
+ "./_ExportWriter",
+ "../Exporter"
+], function(declare, array, _ExportWriter, Exporter){
+
+Exporter.registerWriter("csv", "dojox.grid.enhanced.plugins.exporter.CSVWriter");
+
+return declare("dojox.grid.enhanced.plugins.exporter.CSVWriter", _ExportWriter, {
+ // summary:
+ // Export grid to CSV format.
+ _separator: ',',
+
+ _newline: "\r\n",
+
+ constructor: function(/* object? */writerArgs){
+ // summary:
+ // CSV default separator is ','.
+ // But we can also use our own.
+ // writerArgs: object?
+ // {separator:'...'}
+ if(writerArgs){
+ this._separator = writerArgs.separator ? writerArgs.separator : this._separator;
+ this._newline = writerArgs.newline ? writerArgs.newline : this._newline;
+ }
+ this._headers = [];
+ this._dataRows = [];
+ },
+
+ _formatCSVCell: function(/* string */cellValue){
+ // summary:
+ // Format cell value to follow CSV standard.
+ // See: http://en.wikipedia.org/wiki/Comma-separated_values
+ // tags:
+ // private
+ // cellValue: string
+ // The value in a cell.
+ // returns:
+ // The formatted content of a cell
+ if(cellValue === null || cellValue === undefined){
+ return '';
+ }
+ var result = String(cellValue).replace(/"/g, '""');
+ if(result.indexOf(this._separator) >= 0 || result.search(/[" \t\r\n]/) >= 0){
+ result = '"' + result + '"';
+ }
+ return result; //String
+ },
+
+ beforeContentRow: function(/* object */arg_obj){
+ // summary:
+ // Overrided from _ExportWriter
+ var row = [],
+ func = this._formatCSVCell;
+ array.forEach(arg_obj.grid.layout.cells, function(cell){
+ //We are not interested in indirect selectors and row indexes.
+ if(!cell.hidden && array.indexOf(arg_obj.spCols,cell.index) < 0){
+ //We only need data here, not html
+ row.push(func(this._getExportDataForCell(arg_obj.rowIndex, arg_obj.row, cell, arg_obj.grid)));
+ }
+ }, this);
+ this._dataRows.push(row);
+ //We do not need to go into the row.
+ return false; //Boolean
+ },
+
+ handleCell: function(/* object */arg_obj){
+ // summary:
+ // Overrided from _ExportWriter
+ var cell = arg_obj.cell;
+ if(arg_obj.isHeader && !cell.hidden && array.indexOf(arg_obj.spCols,cell.index) < 0){
+ this._headers.push(cell.name || cell.field);
+ }
+ },
+
+ toString: function(){
+ // summary:
+ // Overrided from _ExportWriter
+ var result = this._headers.join(this._separator);
+ for(var i = this._dataRows.length - 1; i >= 0; --i){
+ this._dataRows[i] = this._dataRows[i].join(this._separator);
+ }
+ return result + this._newline + this._dataRows.join(this._newline); //String
+ }
+});
+});
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/exporter/TableWriter.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/exporter/TableWriter.js
new file mode 100644
index 0000000..0ea2c74
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/exporter/TableWriter.js
@@ -0,0 +1,160 @@
+//>>built
+define("dojox/grid/enhanced/plugins/exporter/TableWriter", [
+ "dojo/_base/declare",
+ "dojo/_base/array",
+ "dojo/dom-geometry",
+ "./_ExportWriter",
+ "../Exporter"
+], function(declare, array, domGeometry, _ExportWriter, Exporter){
+
+Exporter.registerWriter("table", "dojox.grid.enhanced.plugins.exporter.TableWriter");
+
+return declare("dojox.grid.enhanced.plugins.exporter.TableWriter", _ExportWriter, {
+ // summary:
+ // Export grid to HTML table format. Primarily used by Printer plugin.
+ constructor: function(/* object? */writerArgs){
+ // summary:
+ // The generated table only defines the col/rowspan, height and width of
+ // all the cells in the style attribute, no other attributes
+ // (like border, cellspacing, etc.) are used.
+ // Users can define these attributes in the writerArgs object, like:
+ // {table:"border='border'",thead:"cellspacing='3'"}
+ this._viewTables = [];
+ this._tableAttrs = writerArgs || {};
+ },
+
+ _getTableAttrs: function(/* string */tagName){
+ // summary:
+ // Get html attribute string for the given kind of tag.
+ // tags:
+ // private
+ // tagName: string
+ // An html tag name
+ // returns:
+ // The well formatted attributes for the given html table.tag
+ var attrs = this._tableAttrs[tagName] || '';
+ //To ensure the attribute list starts with a space
+ if(attrs && attrs[0] != ' '){
+ attrs = ' ' + attrs;
+ }
+ return attrs; //String
+ },
+
+ _getRowClass: function(/* object */arg_obj){
+ // summary:
+ // Get CSS class string for a row
+ // tags:
+ // private
+ return arg_obj.isHeader ? " grid_header" : [//String
+ " grid_row grid_row_",
+ arg_obj.rowIdx + 1,
+ arg_obj.rowIdx % 2 ? " grid_even_row" : " grid_odd_row"
+ ].join('');
+ },
+
+ _getColumnClass: function(/* object */arg_obj){
+ // summary:
+ // Get CSS class string for a column
+ // tags:
+ // private
+ var col_idx = arg_obj.cell.index + arg_obj.colOffset + 1;
+ return [" grid_column grid_column_", col_idx,//String
+ col_idx % 2 ? " grid_odd_column" : " grid_even_column"].join('');
+ },
+
+ beforeView: function(/* object */arg_obj){
+ // summary:
+ // Overrided from _ExportWriter
+ var viewIdx = arg_obj.viewIdx,
+ table = this._viewTables[viewIdx],
+ height, width = domGeometry.getMarginBox(arg_obj.view.contentNode).w;
+ if(!table){
+ var left = 0;
+ for(var i = 0; i < viewIdx; ++i){
+ left += this._viewTables[i]._width;
+ }
+ table = this._viewTables[viewIdx] = ['<div class="grid_view" style="position: absolute; top: 0; ',
+ domGeometry.isBodyLtr() ? 'left' : 'right', ':', left,
+ 'px;">'];
+ }
+ table._width = width;
+ if(arg_obj.isHeader){
+ height = domGeometry.getContentBox(arg_obj.view.headerContentNode).h;
+ }else{
+ var rowNode = arg_obj.grid.getRowNode(arg_obj.rowIdx);
+ if(rowNode){
+ height = domGeometry.getContentBox(rowNode).h;
+ }else{
+ //This row has not been loaded from store, so we should estimate it's height.
+ height = arg_obj.grid.scroller.averageRowHeight;
+ }
+ }
+ table.push('<table class="', this._getRowClass(arg_obj),
+ '" style="table-layout:fixed; height:', height, 'px; width:', width, 'px;" ',
+ 'border="0" cellspacing="0" cellpadding="0" ',
+ this._getTableAttrs("table"),
+ '><tbody ', this._getTableAttrs('tbody'), '>');
+ return true; //Boolean
+ },
+
+ afterView: function(/* object */arg_obj){
+ // summary:
+ // Overrided from _ExportWriter
+ this._viewTables[arg_obj.viewIdx].push('</tbody></table>');
+ },
+
+ beforeSubrow: function(/* object */arg_obj){
+ // summary:
+ // Overrided from _ExportWriter
+ this._viewTables[arg_obj.viewIdx].push('<tr', this._getTableAttrs('tr'), '>');
+ return true; //Boolean
+ },
+
+ afterSubrow: function(/* object */arg_obj){
+ // summary:
+ // Overrided from _ExportWriter
+ this._viewTables[arg_obj.viewIdx].push('</tr>');
+ },
+
+ handleCell: function(/* object */arg_obj){
+ // summary:
+ // Overrided from _ExportWriter
+ var cell = arg_obj.cell;
+ if(cell.hidden || array.indexOf(arg_obj.spCols, cell.index) >= 0){
+ //We are not interested in indirect selectors and row indexes.
+ return;
+ }
+ var cellTagName = arg_obj.isHeader ? 'th' : 'td',
+ attrs = [cell.colSpan ? ' colspan="' + cell.colSpan + '"' : '',
+ cell.rowSpan ? ' rowspan="' + cell.rowSpan + '"' : '',
+ ' style="width: ', domGeometry.getContentBox(cell.getHeaderNode()).w, 'px;"',
+ this._getTableAttrs(cellTagName),
+ ' class="', this._getColumnClass(arg_obj), '"'].join(''),
+ table = this._viewTables[arg_obj.viewIdx];
+ table.push('<', cellTagName, attrs, '>');
+ if(arg_obj.isHeader){
+ table.push(cell.name || cell.field);
+ } else{
+ table.push(this._getExportDataForCell(arg_obj.rowIdx, arg_obj.row, cell, arg_obj.grid));
+ }
+ table.push('</', cellTagName, '>');
+ },
+
+ afterContent: function(){
+ // summary:
+ // Overrided from _ExportWriter
+ array.forEach(this._viewTables, function(table){
+ table.push('</div>');
+ });
+ },
+
+ toString: function(){
+ // summary:
+ // Overrided from _ExportWriter
+ var viewsHTML = array.map(this._viewTables, function(table){ //String
+ return table.join('');
+ }).join('');
+ return ['<div style="position: relative;">', viewsHTML, '</div>'].join('');
+ }
+});
+});
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/exporter/_ExportWriter.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/exporter/_ExportWriter.js
new file mode 100644
index 0000000..14bd39f
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/exporter/_ExportWriter.js
@@ -0,0 +1,269 @@
+//>>built
+define("dojox/grid/enhanced/plugins/exporter/_ExportWriter", [
+ "dojo/_base/declare"
+], function(declare){
+//require Exporter here, so the implementations only need to require this file,
+//and the users only need to require the implementation file.
+
+return declare("dojox.grid.enhanced.plugins.exporter._ExportWriter", null, {
+ // summary:
+ // This is an abstract class for all kinds of writers used in the Exporter plugin.
+ // It utilizes the strategy pattern to break the export work into several stages,
+ // and provide interfaces for all of them.
+ // Implementations might choose some of the functions in this class to override,
+ // thus providing their own functionalities.
+ // The Exporter will go through the grid line by line. So in every line, all the Views
+ // will be reached, and the header line is only handled once.
+ // An *argObj* object is passed to most functions of this class.
+ // It carries context arguments that make sense when they are called.
+
+/*=====
+ argObj: {
+ // grid: EnhancedGrid
+ // The grid object we are now handling.
+ grid: null,
+
+ // isHeader: bool
+ // Indicating which context we're handling, header or content.
+ isHeader: true,
+
+ // view: _View
+ // Reference to the current _View object.
+ view: null,
+
+ // viewIdx: int
+ // The index of the current _View object in the views array.
+ // If the grid does not have any rowselector view, it conforms to the index
+ // in the _ViewManager.views.
+ viewIdx: -1,
+
+ // subrow: _View.structure.cells[i]
+ // Reference to the current subrow.
+ // A subrow describe the innter structure of a row in a view, it's an array of cells
+ subrow: null,
+
+ // subrowIdx: int
+ // The index of the current subrow in the subrow array: _View.structure.cells.
+ subrowIdx: -1,
+
+ // cell: dojox.grid.__CellDef
+ // Reference to the current cell.
+ cell: null,
+
+ //cellIdx: int
+ // The index of the current cell in the current subrow.
+ // It's different from cell.index, which is the index in the whole line.
+ cellIdx: -1,
+
+ //row: item
+ // The current row of data (logically), a.k.a.: current item.
+ row: null,
+
+ //rowIdx: int
+ // The index of the current row (item).
+ rowIdx: -1,
+
+ // spCols: Array<int>
+ // An array of special column indexes(flat,not regarding structure).
+ // Special columns are typically attached to grid as a kind of UI facility
+ // by the grid widget, instead of some real data.
+ // For example, indirect selectors and row indexers.
+ // Users can choose to export it or not.
+ spCols: [],
+
+ // colOffset: int
+ // If the grid has a _RowSelector view or something else, this view will NOT be
+ // passed to the user in argObj. So the column index (cell.index) will appear shifted
+ // (start from 1 instead of 0). This colOffset is provided to remove this shift.
+ // usage:
+ // var correctColIndex = argObj.cell.index + argObj.colOffset;
+ colOffset: 0
+ },
+=====*/
+
+ constructor: function(/* object? */writerArgs){
+ // summary:
+ // Writer initializations goes here.
+ // writerArgs: object?
+ // Any implementation of this class might accept a writerArgs object (optional),
+ // which contains some writer-specific arguments given by the user.
+ },
+ _getExportDataForCell: function(rowIndex, rowItem, cell, grid){
+ var data = (cell.get || grid.get).call(cell, rowIndex, rowItem);
+ if(this.formatter){
+ return this.formatter(data, cell, rowIndex, rowItem);
+ }else{
+ return data;
+ }
+ },
+ beforeHeader: function(/* EnhancedGrid */grid){
+ // summary:
+ // We are going to start the travel in the grid.
+ // Is there anything we should do now?
+ // tags:
+ // protected extension
+ // return:
+ // true: go on hanling the header row and then call afterHeader.
+ // false: skip the header row, won't call afterHeader.
+ return true; //Boolean
+ },
+ afterHeader: function(){
+ // summary:
+ // The header line has been handled.
+ // tags:
+ // protected extension
+ // returns:
+ // undefined
+ },
+ beforeContent: function(/* Array */items){
+ // summary:
+ // We are ready to go through all the contents(items).
+ // tags:
+ // protected extension
+ // items:
+ // All the items fetched from the store
+ // return:
+ // true: go on handling the contents and then call afterContent.
+ // false: skip all the contents, won't call afterContent.
+ return true; //Boolean
+ },
+ afterContent: function(){
+ // summary:
+ // We have finished the entire grid travel.
+ // Do some clean up work if you need to.
+ // tags:
+ // protected extension
+ // returns:
+ // undefined
+ },
+ beforeContentRow: function(/* object */argObj){
+ // summary:
+ // Before handling a line of data (not header).
+ // tags:
+ // protected extension
+ // argObj:
+ // An object with at least the following context properties available:
+ // {
+ // grid,isHeader,
+ // row,rowIdx,
+ // spCols
+ // }
+ // return:
+ // true: go on handling the current data row and then call afterContentRow.
+ // false: skip the current data row, won't call afterContentRow.
+ return true; //Boolean
+ },
+ afterContentRow: function(/* object */argObj){
+ // summary:
+ // After handling a line of data (not header).
+ // tags:
+ // protected extension
+ // argObj:
+ // An object with at least the following context properties available:
+ // {
+ // grid,isHeader,
+ // row,rowIdx,
+ // spCols
+ // }
+ // returns:
+ // undefined
+ },
+ beforeView: function(/* object */argObj){
+ // summary:
+ // Before handling a view.
+ // tags:
+ // protected extension
+ // argObj:
+ // An object with at least the following context properties available:
+ // {
+ // grid,isHeader,
+ // view,viewIdx,
+ // spCols(if isHeader==false)
+ // }
+ // return:
+ // true: go on handling the current view and then call afterView.
+ // false: skip the current view, won't call afterView.
+ return true; //Boolean
+ },
+ afterView: function(/* object */argObj){
+ // summary:
+ // After handling a view.
+ // tags:
+ // protected extension
+ // argObj:
+ // An object with at least the following context properties available:
+ // {
+ // grid,isHeader,
+ // view,viewIdx,
+ // spCols(if isHeader==false)
+ // }
+ // tags:
+ // protected extension
+ // returns:
+ // undefined
+ },
+ beforeSubrow: function(/* object */argObj){
+ // summary:
+ // Before handling a subrow in a line (defined in the grid structure).
+ // tags:
+ // protected extension
+ // argObj:
+ // An object with at least the following context properties available:
+ // {
+ // grid,isHeader,
+ // row,rowIdx,
+ // view,viewIdx,
+ // subrow,subrowIdx,
+ // spCols(if isHeader==false)
+ // }
+ // return:
+ // true: go on handling the current subrow and then call afterSubrow.
+ // false: skip the current subrow, won't call afterSubrow.
+ return true; //Boolean
+ },
+ afterSubrow: function(/* object */argObj){
+ // summary:
+ // Before handling a subrow in a line (defined in the grid structure).
+ // tags:
+ // protected extension
+ // argObj:
+ // An object with at least the following context properties available:
+ // {
+ // grid,isHeader,
+ // row,rowIdx,
+ // view,viewIdx,
+ // subrow,subrowIdx,
+ // spCols(if isHeader==false)
+ // }
+ // returns:
+ // undefined
+ },
+ handleCell: function(/* object */argObj){
+ // summary:
+ // Handle a header cell or data cell.
+ // tags:
+ // protected extension
+ // argObj:
+ // An object with at least the following context properties available:
+ // {
+ // grid,isHeader,
+ // row,rowIdx,
+ // view,viewIdx,
+ // subrow,subrowIdx,
+ // cell,cellIdx,
+ // spCols(if isHeader==false)
+ // }
+ // returns:
+ // undefined
+ },
+ toString: function(){
+ // summary:
+ // Export to a string.
+ // tags:
+ // protected extension
+ // returns:
+ // The exported result string.
+ return ''; //String
+ }
+});
+});
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/ClearFilterConfirm.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/ClearFilterConfirm.js
new file mode 100644
index 0000000..2a63dcb
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/ClearFilterConfirm.js
@@ -0,0 +1,46 @@
+//>>built
+define("dojox/grid/enhanced/plugins/filter/ClearFilterConfirm", [
+ "dojo/_base/declare",
+ "dojo/cache",
+ "dijit/_Widget",
+ "dijit/_TemplatedMixin",
+ "dijit/_WidgetsInTemplateMixin"
+], function(declare, cache, _Widget, _TemplatedMixin, _WidgetsInTemplateMixin){
+
+return declare("dojox.grid.enhanced.plugins.filter.ClearFilterConfirm",
+ [_Widget, _TemplatedMixin, _WidgetsInTemplateMixin], {
+ // summary:
+ // The UI for user to confirm the operation of clearing filter.
+ templateString: cache("dojox.grid", "enhanced/templates/ClearFilterConfirmPane.html"),
+
+ widgetsInTemplate: true,
+
+ plugin: null,
+
+ postMixInProperties: function(){
+ var nls = this.plugin.nls;
+ this._clearBtnLabel = nls["clearButton"];
+ this._cancelBtnLabel = nls["cancelButton"];
+ this._clearFilterMsg = nls["clearFilterMsg"];
+ },
+
+ postCreate: function(){
+ this.inherited(arguments);
+ this.cancelBtn.domNode.setAttribute("aria-label", this.plugin.nls["waiCancelButton"]);
+ this.clearBtn.domNode.setAttribute("aria-label", this.plugin.nls["waiClearButton"]);
+ },
+
+ uninitialize: function(){
+ this.plugin = null;
+ },
+
+ _onCancel: function(){
+ this.plugin.clearFilterDialog.hide();
+ },
+
+ _onClear: function(){
+ this.plugin.clearFilterDialog.hide();
+ this.plugin.filterDefDialog.clearFilter(this.plugin.filterDefDialog._clearWithoutRefresh);
+ }
+});
+});
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/FilterBar.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/FilterBar.js
new file mode 100644
index 0000000..422c56a
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/FilterBar.js
@@ -0,0 +1,386 @@
+//>>built
+define("dojox/grid/enhanced/plugins/filter/FilterBar", [
+ "dojo/_base/declare",
+ "dojo/_base/array",
+ "dojo/_base/connect",
+ "dojo/_base/lang",
+ "dojo/_base/sniff",
+ "dojo/_base/event",
+ "dojo/_base/html",
+ "dojo/_base/window",
+ "dojo/cache",
+ "dojo/query",
+ "dijit/_Widget",
+ "dijit/_TemplatedMixin",
+ "dijit/_WidgetsInTemplateMixin",
+ "dojo/fx",
+ "dojo/_base/fx",
+ "dojo/string",
+ "dijit/focus"
+], function(declare, array, connect, lang, has, event, html, win, cache, query, _Widget, _TemplatedMixin, _WidgetsInTemplateMixin, fx, baseFx, string, dijitFocus){
+
+var _focusClass = "dojoxGridFBarHover",
+ _filteredClass = "dojoxGridFBarFiltered",
+ _stopEvent = function(evt){
+ try{
+ if(evt && evt.preventDefault){
+ event.stop(evt);
+ }
+ }catch(e){}
+ };
+
+return declare("dojox.grid.enhanced.plugins.filter.FilterBar", [_Widget, _TemplatedMixin, _WidgetsInTemplateMixin],{
+ // summary:
+ // The filter bar UI.
+ templateString: cache("dojox.grid","enhanced/templates/FilterBar.html"),
+
+ widgetsInTemplate: true,
+
+ _timeout_statusTooltip: 300,
+
+ _handle_statusTooltip: null,
+
+ _curColIdx: -1,
+
+ plugin: null,
+
+ postMixInProperties: function(){
+ var plugin = this.plugin;
+ var nls = plugin.nls;
+ this._filterBarDefBtnLabel = nls["filterBarDefButton"];
+ this._filterBarClearBtnLabel = nls["filterBarClearButton"];
+ this._closeFilterBarBtnLabel = nls["closeFilterBarBtn"];
+ var itemsName = plugin.args.itemsName || nls["defaultItemsName"];
+ this._noFilterMsg = string.substitute(nls["filterBarMsgNoFilterTemplate"], ["", itemsName]);
+
+ var t = this.plugin.args.statusTipTimeout;
+ if(typeof t == 'number'){
+ this._timeout_statusTooltip = t;
+ }
+
+ var g = plugin.grid;
+ g.showFilterBar = lang.hitch(this, "showFilterBar");
+ g.toggleFilterBar = lang.hitch(this, "toggleFilterBar");
+ g.isFilterBarShown = lang.hitch(this, "isFilterBarShown");
+ },
+ postCreate: function(){
+ this.inherited(arguments);
+ if(!this.plugin.args.closeFilterbarButton){
+ html.style(this.closeFilterBarButton.domNode, "display", "none");
+ }
+ var _this = this,
+ g = this.plugin.grid,
+ old_func = this.oldGetHeaderHeight = lang.hitch(g,g._getHeaderHeight);
+
+ this.placeAt(g.viewsHeaderNode, "after");
+ this.connect(this.plugin.filterDefDialog, "showDialog", "_onShowFilterDefDialog");
+ this.connect(this.plugin.filterDefDialog, "closeDialog", "_onCloseFilterDefDialog");
+ this.connect(g.layer("filter"), "onFiltered", this._onFiltered);
+
+ this.defineFilterButton.domNode.title = this.plugin.nls["filterBarDefButton"];
+ if(html.hasClass(win.body(), "dijit_a11y")){
+ this.defineFilterButton.set("label", this.plugin.nls["a11yFilterBarDefButton"]);
+ }
+ this.connect(this.defineFilterButton.domNode, "click", _stopEvent);
+ this.connect(this.clearFilterButton.domNode, "click", _stopEvent);
+ this.connect(this.closeFilterBarButton.domNode, "click", _stopEvent);
+
+ this.toggleClearFilterBtn(true);
+ this._initAriaInfo();
+
+ //Hack the header height to include filter bar height;
+ g._getHeaderHeight = function(){
+ return old_func() + html.marginBox(_this.domNode).h;
+ };
+ //Define an area to make focusManager handle all the navigation stuff
+ g.focus.addArea({
+ name: "filterbar",
+ onFocus: lang.hitch(this, this._onFocusFilterBar, false),
+ onBlur: lang.hitch(this, this._onBlurFilterBar)
+ });
+ g.focus.placeArea("filterbar","after","header");
+ },
+ uninitialize: function(){
+ var g = this.plugin.grid;
+ g._getHeaderHeight = this.oldGetHeaderHeight;
+ g.focus.removeArea("filterbar");
+ this.plugin = null;
+ },
+ isFilterBarShown: function(){
+ return html.style(this.domNode, "display") != "none";
+ },
+ showFilterBar: function(toShow, useAnim, animArgs){
+ var g = this.plugin.grid;
+ if(useAnim){
+ if(Boolean(toShow) == this.isFilterBarShown()){ return; }
+ animArgs = animArgs || {};
+ var anims = [], defaultDuration = 500;
+ anims.push(fx[toShow ? "wipeIn" : "wipeOut"](lang.mixin({
+ "node": this.domNode,
+ "duration": defaultDuration
+ }, animArgs)));
+ var curHeight = g.views.views[0].domNode.offsetHeight;
+ var prop = {
+ "duration": defaultDuration,
+ "properties": {
+ "height": {
+ "end": lang.hitch(this, function(){
+ var barHeight = this.domNode.scrollHeight;
+ if(has("ff")){
+ barHeight -= 2;
+ }
+ return toShow ? (curHeight - barHeight) : (curHeight + barHeight);
+ })
+ }
+ }
+ };
+ array.forEach(g.views.views, function(view){
+ anims.push(baseFx.animateProperty(lang.mixin({
+ "node": view.domNode
+ }, prop, animArgs)), baseFx.animateProperty(lang.mixin({
+ "node": view.scrollboxNode
+ }, prop, animArgs)));
+ });
+ anims.push(baseFx.animateProperty(lang.mixin({
+ "node": g.viewsNode
+ }, prop, animArgs)));
+ fx.combine(anims).play();
+ }else{
+ html.style(this.domNode, "display", toShow ? "" : "none");
+ g.update();
+ }
+ },
+ toggleFilterBar: function(useAnim, animArgs){
+ this.showFilterBar(!this.isFilterBarShown(), useAnim, animArgs);
+ },
+ getColumnIdx: function(/* int */coordX){
+ var headers = query("[role='columnheader']", this.plugin.grid.viewsHeaderNode);
+ var idx = -1;
+ for(var i = headers.length - 1; i >= 0; --i){
+ var coord = html.position(headers[i]);
+ if(coordX >= coord.x && coordX < coord.x + coord.w){
+ idx = i;
+ break;
+ }
+ }
+ if(idx >= 0 && this.plugin.grid.layout.cells[idx].filterable !== false){
+ return idx; //Integer
+ }else{
+ return -1; //Integer
+ }
+ },
+ toggleClearFilterBtn: function(toHide){
+ html.style(this.clearFilterButton.domNode, "display", toHide ? "none" : "");
+ },
+ _closeFilterBar: function(e){
+ _stopEvent(e);
+ var rulesCnt = this.plugin.filterDefDialog.getCriteria();
+ if(rulesCnt){
+ var handle = connect.connect(this.plugin.filterDefDialog, "clearFilter", this, function(){
+ this.showFilterBar(false, true);
+ connect.disconnect(handle);
+ });
+ this._clearFilterDefDialog(e);
+ }else{
+ this.showFilterBar(false, true);
+ }
+ },
+
+ _showFilterDefDialog: function(e){
+ _stopEvent(e);
+ this.plugin.filterDefDialog.showDialog(this._curColIdx);
+ this.plugin.grid.focus.focusArea("filterbar");
+ },
+ _clearFilterDefDialog: function(e){
+ _stopEvent(e);
+ this.plugin.filterDefDialog.onClearFilter();
+ this.plugin.grid.focus.focusArea("filterbar");
+ },
+ _onEnterButton: function(e){
+ //If mouse is hovering the btn, which means the user is about to click,
+ //we should not show status tip on the btn!
+ this._onBlurFilterBar();
+ _stopEvent(e);
+ },
+ _onMoveButton: function(e){
+ this._onBlurFilterBar();
+ },
+ _onLeaveButton: function(e){
+ this._leavingBtn = true;
+ },
+ _onShowFilterDefDialog: function(/* Integer */colIdx){
+ if(typeof colIdx == "number"){
+ this._curColIdx = colIdx;
+ }
+ this._defPaneIsShown = true;
+ },
+ _onCloseFilterDefDialog: function(){
+ this._defPaneIsShown = false;
+ //Do not remember what column are we on, so clicking the btn will show 'any column'
+ this._curColIdx = -1;
+ dijitFocus.focus(this.defineFilterButton.domNode);
+ },
+ _onClickFilterBar: function(/* event */e){
+ _stopEvent(e);
+ this._clearStatusTipTimeout();
+ this.plugin.grid.focus.focusArea("filterbar");
+ this.plugin.filterDefDialog.showDialog(this.getColumnIdx(e.clientX));
+ },
+ _onMouseEnter: function(/* event */e){
+ this._onFocusFilterBar(true, null);
+ this._updateTipPosition(e);
+ this._setStatusTipTimeout();
+ },
+ _onMouseMove: function(/* event */e){
+ if(this._leavingBtn){
+ this._onFocusFilterBar(true, null);
+ this._leavingBtn = false;
+ }
+ if(this._isFocused){
+ this._setStatusTipTimeout();
+ this._highlightHeader(this.getColumnIdx(e.clientX));
+ if(this._handle_statusTooltip){
+ this._updateTipPosition(e);
+ }
+ }
+ },
+ _onMouseLeave: function(e){
+ this._onBlurFilterBar();
+ },
+ _updateTipPosition: function(evt){
+ this._tippos = {
+ x: evt.pageX,
+ y: evt.pageY
+ };
+ },
+ _onFocusFilterBar: function(highlightOnly, evt, step){
+ if(!this.isFilterBarShown()){
+ return false;
+ }
+ this._isFocused = true;
+ html.addClass(this.domNode,_focusClass);
+ if(!highlightOnly){
+ var hasFilter = html.style(this.clearFilterButton.domNode, "display") !== "none";
+ var hasCloseButton = html.style(this.closeFilterBarButton.domNode, "display") !== "none";
+ if(typeof this._focusPos == "undefined"){
+ if(step > 0){
+ this._focusPos = 0;
+ }else{
+ if(hasCloseButton){
+ this._focusPos = 1;
+ }else{
+ this._focusPos = 0;
+ }
+ if(hasFilter){
+ ++this._focusPos;
+ }
+ }
+ }
+ if(this._focusPos === 0){
+ dijitFocus.focus(this.defineFilterButton.focusNode);
+ }else if(this._focusPos === 1 && hasFilter){
+ dijitFocus.focus(this.clearFilterButton.focusNode);
+ }else{
+ dijitFocus.focus(this.closeFilterBarButton.focusNode);
+ }
+ }
+ _stopEvent(evt);
+ return true;
+ },
+ _onBlurFilterBar: function(evt, step){
+ if(this._isFocused){
+ this._isFocused = false;
+ html.removeClass(this.domNode,_focusClass);
+ this._clearStatusTipTimeout();
+ this._clearHeaderHighlight();
+ }
+ var toBlur = true;
+ if(step){
+ var buttonCount = 3;
+ if(html.style(this.closeFilterBarButton.domNode, "display") === "none"){
+ --buttonCount;
+ }
+ if(html.style(this.clearFilterButton.domNode, "display") === "none"){
+ --buttonCount;
+ }
+ if(buttonCount == 1){
+ delete this._focusPos;
+ }else{
+ var current = this._focusPos;
+ for(var next = current + step; next < 0; next += buttonCount){}
+ next %= buttonCount;
+ if((step > 0 && next < current) || (step < 0 && next > current)){
+ delete this._focusPos;
+ }else{
+ this._focusPos = next;
+ toBlur = false;
+ }
+ }
+ }
+ return toBlur;
+ },
+ _onFiltered: function(/* int */filteredSize,/* int */originSize){
+ var p = this.plugin,
+ itemsName = p.args.itemsName || p.nls["defaultItemsName"],
+ msg = "", g = p.grid,
+ filterLayer = g.layer("filter");
+ if(filterLayer.filterDef()){
+ msg = string.substitute(p.nls["filterBarMsgHasFilterTemplate"], [filteredSize, originSize, itemsName]);
+ html.addClass(this.domNode, _filteredClass);
+ }else{
+ msg = string.substitute(p.nls["filterBarMsgNoFilterTemplate"], [originSize, itemsName]);
+ html.removeClass(this.domNode, _filteredClass);
+ }
+ this.statusBarNode.innerHTML = msg;
+ this._focusPos = 0;
+ },
+ _initAriaInfo: function(){
+ this.defineFilterButton.domNode.setAttribute("aria-label", this.plugin.nls["waiFilterBarDefButton"]);
+ this.clearFilterButton.domNode.setAttribute("aria-label", this.plugin.nls["waiFilterBarClearButton"]);
+ },
+ _isInColumn: function(/* int */mousePos_x, /* domNode */headerNode, /* int */colIndex){
+ var coord = html.position(headerNode);
+ return mousePos_x >= coord.x && mousePos_x < coord.x + coord.w;
+ },
+ _setStatusTipTimeout: function(){
+ this._clearStatusTipTimeout();
+ if(!this._defPaneIsShown){
+ this._handle_statusTooltip = setTimeout(lang.hitch(this,this._showStatusTooltip),this._timeout_statusTooltip);
+ }
+ },
+ _clearStatusTipTimeout: function(){
+ clearTimeout(this._handle_statusTooltip);
+ this._handle_statusTooltip = null;
+ },
+ _showStatusTooltip: function(){
+ this._handle_statusTooltip = null;
+ this.plugin.filterStatusTip.showDialog(this._tippos.x, this._tippos.y, this.getColumnIdx(this._tippos.x));
+ },
+ _highlightHeader: function(/* int */colIdx){
+ if(colIdx != this._previousHeaderIdx){
+ var g = this.plugin.grid,
+ cell = g.getCell(this._previousHeaderIdx);
+ if(cell){
+ html.removeClass(cell.getHeaderNode(), "dojoxGridCellOver");
+ }
+ cell = g.getCell(colIdx);
+ if(cell){
+ html.addClass(cell.getHeaderNode(), "dojoxGridCellOver");
+ }
+ this._previousHeaderIdx = colIdx;
+ }
+ },
+ _clearHeaderHighlight: function(){
+ if(typeof this._previousHeaderIdx != "undefined"){
+ var g = this.plugin.grid,
+ cell = g.getCell(this._previousHeaderIdx);
+ if(cell){
+ g.onHeaderCellMouseOut({
+ cellNode: cell.getHeaderNode()
+ });
+ }
+ delete this._previousHeaderIdx;
+ }
+ }
+});
+});
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/FilterBuilder.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/FilterBuilder.js
new file mode 100644
index 0000000..63297c0
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/FilterBuilder.js
@@ -0,0 +1,81 @@
+//>>built
+define("dojox/grid/enhanced/plugins/filter/FilterBuilder", [
+ "dojo/_base/declare",
+ "dojo/_base/array",
+ "dojo/_base/lang",
+ "./_FilterExpr"
+], function(declare, array, lang, exprs){
+
+var bdr = function(opCls){
+ return lang.partial(function(cls,operands){
+ return new exprs[cls](operands);
+ },opCls);
+ },
+ bdr_not = function(opCls){
+ return lang.partial(function(cls,operands){
+ return new exprs.LogicNOT(new exprs[cls](operands));
+ },opCls);
+ };
+return declare("dojox.grid.enhanced.plugins.filter.FilterBuilder", null, {
+ // summary:
+ // Create filter expression from a JSON object.
+ buildExpression: function(def){
+ if("op" in def){
+ return this.supportedOps[def.op.toLowerCase()](array.map(def.data, this.buildExpression, this));
+ }else{
+ var args = lang.mixin(this.defaultArgs[def.datatype], def.args || {});
+ return new this.supportedTypes[def.datatype](def.data, def.isColumn, args);
+ }
+ },
+ supportedOps: {
+ // summary:
+ // The builders of all supported operations
+ "equalto": bdr("EqualTo"),
+ "lessthan": bdr("LessThan"),
+ "lessthanorequalto": bdr("LessThanOrEqualTo"),
+ "largerthan": bdr("LargerThan"),
+ "largerthanorequalto": bdr("LargerThanOrEqualTo"),
+ "contains": bdr("Contains"),
+ "startswith": bdr("StartsWith"),
+ "endswith": bdr("EndsWith"),
+ "notequalto": bdr_not("EqualTo"),
+ "notcontains": bdr_not("Contains"),
+ "notstartswith": bdr_not("StartsWith"),
+ "notendswith": bdr_not("EndsWith"),
+ "isempty": bdr("IsEmpty"),
+ "range": function(operands){
+ return new exprs.LogicALL(
+ new exprs.LargerThanOrEqualTo(operands.slice(0,2)),
+ new exprs.LessThanOrEqualTo(operands[0], operands[2])
+ );
+ },
+ "logicany": bdr("LogicANY"),
+ "logicall": bdr("LogicALL")
+ },
+ supportedTypes: {
+ "number": exprs.NumberExpr,
+ "string": exprs.StringExpr,
+ "boolean": exprs.BooleanExpr,
+ "date": exprs.DateExpr,
+ "time": exprs.TimeExpr
+ },
+ defaultArgs: {
+ "boolean": {
+ "falseValue": "false",
+ "convert": function(dataValue, args){
+ var falseValue = args.falseValue;
+ var trueValue = args.trueValue;
+ if(lang.isString(dataValue)){
+ if(trueValue && dataValue.toLowerCase() == trueValue){
+ return true;
+ }
+ if(falseValue && dataValue.toLowerCase() == falseValue){
+ return false;
+ }
+ }
+ return !!dataValue;
+ }
+ }
+ }
+});
+});
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/FilterDefDialog.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/FilterDefDialog.js
new file mode 100644
index 0000000..7e49153
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/FilterDefDialog.js
@@ -0,0 +1,1252 @@
+//>>built
+define("dojox/grid/enhanced/plugins/filter/FilterDefDialog", [
+ "dojo/_base/declare",
+ "dojo/_base/array",
+ "dojo/_base/connect",
+ "dojo/_base/lang",
+ "dojo/_base/event",
+ "dojo/_base/html",
+ "dojo/_base/sniff",
+ "dojo/cache",
+ "dojo/keys",
+ "dojo/string",
+ "dojo/window",
+ "dojo/date/locale",
+ "./FilterBuilder",
+ "../Dialog",
+ "dijit/form/ComboBox",
+ "dijit/form/TextBox",
+ "dijit/form/NumberTextBox",
+ "dijit/form/DateTextBox",
+ "dijit/form/TimeTextBox",
+ "dijit/form/Button",
+ "dijit/layout/AccordionContainer",
+ "dijit/layout/ContentPane",
+ "dijit/_Widget",
+ "dijit/_TemplatedMixin",
+ "dijit/_WidgetsInTemplateMixin",
+ "dijit/focus",
+ "dojox/html/metrics",
+ "dijit/a11y",
+ "dijit/Tooltip",
+ "dijit/form/Select",
+ "dijit/form/RadioButton",
+ "dojox/html/ellipsis",
+ "../../../cells/dijit"
+], function(declare, array, connect, lang, event, html, has, cache, keys, string, win, dateLocale,
+ FilterBuilder, Dialog, ComboBox, TextBox, NumberTextBox, DateTextBox, TimeTextBox, Button,
+ AccordionContainer, ContentPane, _Widget, _TemplatedMixin, _WidgetsInTemplateMixin, dijitFocus, metrics, dijitA11y){
+
+var _tabIdxes = {
+ // summary:
+ // Define tabindexes for elements in the filter definition dialog
+ relSelect: 60,
+ accordionTitle: 70,
+ removeCBoxBtn: -1,
+ colSelect: 90,
+ condSelect: 95,
+ valueBox: 10,
+ addCBoxBtn: 20,
+ filterBtn: 30,
+ clearBtn: 40,
+ cancelBtn: 50
+ };
+var FilterAccordionContainer = declare("dojox.grid.enhanced.plugins.filter.AccordionContainer", AccordionContainer, {
+ nls: null,
+ addChild: function(/*dijit._Widget*/ child, /*Integer?*/ insertIndex){
+ var pane = arguments[0] = child._pane = new ContentPane({
+ content: child
+ });
+ this.inherited(arguments);
+ this._modifyChild(pane);
+ },
+ removeChild: function(child){
+ var pane = child, isRemoveByUser = false;
+ if(child._pane){
+ isRemoveByUser = true;
+ pane = arguments[0] = child._pane;
+ }
+ this.inherited(arguments);
+ if(isRemoveByUser){
+ this._hackHeight(false, this._titleHeight);
+ var children = this.getChildren();
+ if(children.length === 1){
+ html.style(children[0]._removeCBoxBtn.domNode, "display", "none");
+ }
+ }
+ pane.destroyRecursive();
+ },
+ selectChild: function(child){
+ if(child._pane){
+ arguments[0] = child._pane;
+ }
+ this.inherited(arguments);
+ },
+ resize: function(){
+ this.inherited(arguments);
+ array.forEach(this.getChildren(), this._setupTitleDom);
+ },
+ startup: function(){
+ if(this._started){
+ return;
+ }
+ this.inherited(arguments);
+ if(parseInt(has("ie"), 10) == 7){
+ //IE7 will fire a lot of "onresize" event during initialization.
+ array.some(this._connects, function(cnnt){
+ if(cnnt[0][1] == "onresize"){
+ this.disconnect(cnnt);
+ return true;
+ }
+ }, this);
+ }
+ array.forEach(this.getChildren(), function(child){
+ this._modifyChild(child, true);
+ }, this);
+ },
+ _onKeyPress: function(/*Event*/ e, /*dijit._Widget*/ fromTitle){
+ // summary:
+ // Overrides base class method, make left/right button do other things.
+ if(this.disabled || e.altKey || !(fromTitle || e.ctrlKey)){
+ return;
+ }
+ var k = keys, c = e.charOrCode, ltr = html._isBodyLtr(), toNext = null;
+ if((fromTitle && c == k.UP_ARROW) || (e.ctrlKey && c == k.PAGE_UP)){
+ toNext = false;
+ }else if((fromTitle && c == k.DOWN_ARROW) || (e.ctrlKey && (c == k.PAGE_DOWN || c == k.TAB))){
+ toNext = true;
+ }else if(c == (ltr ? k.LEFT_ARROW : k.RIGHT_ARROW)){
+ toNext = this._focusOnRemoveBtn ? null : false;
+ this._focusOnRemoveBtn = !this._focusOnRemoveBtn;
+ }else if(c == (ltr ? k.RIGHT_ARROW : k.LEFT_ARROW)){
+ toNext = this._focusOnRemoveBtn ? true : null;
+ this._focusOnRemoveBtn = !this._focusOnRemoveBtn;
+ }else{
+ return;
+ }
+ if(toNext !== null){
+ this._adjacent(toNext)._buttonWidget._onTitleClick();
+ }
+ event.stop(e);
+ win.scrollIntoView(this.selectedChildWidget._buttonWidget.domNode.parentNode);
+ if(has("ie")){
+ //IE will not show focus indicator if tabIndex is -1
+ this.selectedChildWidget._removeCBoxBtn.focusNode.setAttribute("tabIndex", this._focusOnRemoveBtn ? _tabIdxes.accordionTitle : -1);
+ }
+ dijitFocus.focus(this.selectedChildWidget[this._focusOnRemoveBtn ? "_removeCBoxBtn" : "_buttonWidget"].focusNode);
+ },
+ _modifyChild: function(child, isFirst){
+ if(!child || !this._started){
+ return;
+ }
+ html.style(child.domNode, "overflow", "hidden");
+ child._buttonWidget.connect(child._buttonWidget, "_setSelectedAttr", function(){
+ this.focusNode.setAttribute("tabIndex", this.selected ? _tabIdxes.accordionTitle : "-1");
+ });
+ var _this = this;
+ child._buttonWidget.connect(child._buttonWidget.domNode, "onclick", function(){
+ _this._focusOnRemoveBtn = false;
+ });
+ (child._removeCBoxBtn = new Button({
+ label: this.nls.removeRuleButton,
+ showLabel: false,
+ iconClass: "dojoxGridFCBoxRemoveCBoxBtnIcon",
+ tabIndex: _tabIdxes.removeCBoxBtn,
+ onClick: lang.hitch(child.content, "onRemove"),
+ onKeyPress: function(e){
+ _this._onKeyPress(e, child._buttonWidget.contentWidget);
+ }
+ })).placeAt(child._buttonWidget.domNode);
+ var i, children = this.getChildren();
+ if(children.length === 1){
+ child._buttonWidget.set("selected", true);
+ html.style(child._removeCBoxBtn.domNode, "display", "none");
+ }else{
+ for(i = 0; i < children.length; ++i){
+ if(children[i]._removeCBoxBtn){
+ html.style(children[i]._removeCBoxBtn.domNode, "display", "");
+ }
+ }
+ }
+ this._setupTitleDom(child);
+ if(!this._titleHeight){
+ for(i = 0; i < children.length; ++i){
+ if(children[i] != this.selectedChildWidget){
+ this._titleHeight = html.marginBox(children[i]._buttonWidget.domNode.parentNode).h;
+ break;
+ }
+ }
+ }
+ if(!isFirst){
+ this._hackHeight(true, this._titleHeight);
+ }
+ },
+ _hackHeight: function(/* bool */toGrow,/* int */heightDif){
+ var children = this.getChildren(),
+ dn = this.domNode, h = html.style(dn, "height");
+ if(!toGrow){
+ dn.style.height = (h - heightDif) + 'px';
+ }else if(children.length > 1){
+ dn.style.height = (h + heightDif) + 'px';
+ }else{
+ //Only one rule, no need to do anything.
+ return;
+ }
+ this.resize();
+ },
+ _setupTitleDom: function(child){
+ var w = html.contentBox(child._buttonWidget.titleNode).w;
+ if(has("ie") < 8){ w -= 8; }
+ html.style(child._buttonWidget.titleTextNode, "width", w + "px");
+ }
+});
+var FilterDefPane = declare("dojox.grid.enhanced.plugins.filter.FilterDefPane",[_Widget, _TemplatedMixin, _WidgetsInTemplateMixin],{
+ templateString: cache("dojox.grid","enhanced/templates/FilterDefPane.html"),
+ widgetsInTemplate: true,
+ dlg: null,
+ postMixInProperties: function(){
+ this.plugin = this.dlg.plugin;
+ var nls = this.plugin.nls;
+ this._addRuleBtnLabel = nls.addRuleButton;
+ this._cancelBtnLabel = nls.cancelButton;
+ this._clearBtnLabel = nls.clearButton;
+ this._filterBtnLabel = nls.filterButton;
+ this._relAll = nls.relationAll;
+ this._relAny = nls.relationAny;
+ this._relMsgFront = nls.relationMsgFront;
+ this._relMsgTail = nls.relationMsgTail;
+ },
+ postCreate: function(){
+ this.inherited(arguments);
+ this.connect(this.domNode, "onkeypress", "_onKey");
+ (this.cboxContainer = new FilterAccordionContainer({
+ nls: this.plugin.nls
+ })).placeAt(this.criteriaPane);
+
+ this._relSelect.set("tabIndex", _tabIdxes.relSelect);
+ this._addCBoxBtn.set("tabIndex", _tabIdxes.addCBoxBtn);
+ this._cancelBtn.set("tabIndex", _tabIdxes.cancelBtn);
+ this._clearFilterBtn.set("tabIndex", _tabIdxes.clearBtn);
+ this._filterBtn.set("tabIndex", _tabIdxes.filterBtn);
+
+ var nls = this.plugin.nls;
+ this._relSelect.domNode.setAttribute("aria-label", nls.waiRelAll);
+ this._addCBoxBtn.domNode.setAttribute("aria-label", nls.waiAddRuleButton);
+ this._cancelBtn.domNode.setAttribute("aria-label", nls.waiCancelButton);
+ this._clearFilterBtn.domNode.setAttribute("aria-label", nls.waiClearButton);
+ this._filterBtn.domNode.setAttribute("aria-label", nls.waiFilterButton);
+
+ this._relSelect.set("value", this.dlg._relOpCls === "logicall" ? "0" : "1");
+ },
+ uninitialize: function(){
+ this.cboxContainer.destroyRecursive();
+ this.plugin = null;
+ this.dlg = null;
+ },
+ _onRelSelectChange: function(val){
+ this.dlg._relOpCls = val == "0" ? "logicall" : "logicany";
+ this._relSelect.domNode.setAttribute("aria-label", this.plugin.nls[val == "0" ? "waiRelAll" : "waiRelAny"]);
+ },
+ _onAddCBox: function(){
+ this.dlg.addCriteriaBoxes(1);
+ },
+ _onCancel: function(){
+ this.dlg.onCancel();
+ },
+ _onClearFilter: function(){
+ this.dlg.onClearFilter();
+ },
+ _onFilter: function(){
+ this.dlg.onFilter();
+ },
+ _onKey: function(e){
+ if(e.keyCode == keys.ENTER){
+ this.dlg.onFilter();
+ }
+ }
+});
+var CriteriaBox = declare("dojox.grid.enhanced.plugins.filter.CriteriaBox",[_Widget, _TemplatedMixin, _WidgetsInTemplateMixin],{
+ templateString: cache("dojox.grid","enhanced/templates/CriteriaBox.html"),
+ widgetsInTemplate: true,
+ dlg: null,
+ postMixInProperties: function(){
+ this.plugin = this.dlg.plugin;
+ this._curValueBox = null;
+
+ var nls = this.plugin.nls;
+ this._colSelectLabel = nls.columnSelectLabel;
+ this._condSelectLabel = nls.conditionSelectLabel;
+ this._valueBoxLabel = nls.valueBoxLabel;
+ this._anyColumnOption = nls.anyColumnOption;
+ },
+ postCreate: function(){
+ var dlg = this.dlg, g = this.plugin.grid;
+ //Select Column
+ this._colSelect.set("tabIndex", _tabIdxes.colSelect);
+ this._colOptions = this._getColumnOptions();
+ this._colSelect.addOption([
+ {label: this.plugin.nls.anyColumnOption, value: "anycolumn", selected: dlg.curColIdx < 0},
+ {value: ""}
+ ].concat(this._colOptions));
+ //Select Condition
+ this._condSelect.set("tabIndex", _tabIdxes.condSelect);
+ this._condSelect.addOption(this._getUsableConditions(dlg.getColumnType(dlg.curColIdx)));
+ this._showSelectOrLabel(this._condSelect, this._condSelectAlt);
+
+ this.connect(g.layout, "moveColumn", "onMoveColumn");
+ },
+ _getColumnOptions: function(){
+ var colIdx = this.dlg.curColIdx >= 0 ? String(this.dlg.curColIdx) : "anycolumn";
+ return array.map(array.filter(this.plugin.grid.layout.cells, function(cell){
+ return !(cell.filterable === false || cell.hidden);
+ }), function(cell){
+ return {
+ label: cell.name || cell.field,
+ value: String(cell.index),
+ selected: colIdx == String(cell.index)
+ };
+ });
+ },
+ onMoveColumn: function(){
+ var tmp = this._onChangeColumn;
+ this._onChangeColumn = function(){};
+ var option = this._colSelect.get("selectedOptions");
+ this._colSelect.removeOption(this._colOptions);
+ this._colOptions = this._getColumnOptions();
+ this._colSelect.addOption(this._colOptions);
+ var i = 0;
+ for(; i < this._colOptions.length; ++i){
+ if(this._colOptions[i].label == option.label){
+ break;
+ }
+ }
+ if(i < this._colOptions.length){
+ this._colSelect.set("value", this._colOptions[i].value);
+ }
+ var _this = this;
+ setTimeout(function(){
+ _this._onChangeColumn = tmp;
+ }, 0);
+ },
+ onRemove: function(){
+ this.dlg.removeCriteriaBoxes(this);
+ },
+ uninitialize: function(){
+ if(this._curValueBox){
+ this._curValueBox.destroyRecursive();
+ this._curValueBox = null;
+ }
+ this.plugin = null;
+ this.dlg = null;
+ },
+ _showSelectOrLabel: function(sel, alt){
+ var options = sel.getOptions();
+ if(options.length == 1){
+ alt.innerHTML = options[0].label;
+ html.style(sel.domNode, "display", "none");
+ html.style(alt, "display", "");
+ }else{
+ html.style(sel.domNode, "display", "");
+ html.style(alt, "display", "none");
+ }
+ },
+ _onChangeColumn: function(val){
+ this._checkValidCriteria();
+ var type = this.dlg.getColumnType(val);
+ this._setConditionsByType(type);
+ this._setValueBoxByType(type);
+ this._updateValueBox();
+ },
+ _onChangeCondition: function(val){
+ this._checkValidCriteria();
+ var f = (val == "range");
+ if(f ^ this._isRange){
+ this._isRange = f;
+ this._setValueBoxByType(this.dlg.getColumnType(this._colSelect.get("value")));
+ }
+ this._updateValueBox();
+ },
+ _updateValueBox: function(cond){
+ this._curValueBox.set("disabled", this._condSelect.get("value") == "isempty");
+ },
+ _checkValidCriteria: function(){
+ // summary:
+ // Check whether the given criteria box is completed. If it is, mark it.
+ setTimeout(lang.hitch(this, function(){
+ this.updateRuleTitle();
+ this.dlg._updatePane();
+ }),0);
+ },
+ _createValueBox: function(/* widget constructor */cls,/* object */arg){
+ // summary:
+ // Create a value input box with given class and arguments
+ var func = lang.hitch(arg.cbox, "_checkValidCriteria");
+ return new cls(lang.mixin(arg,{
+ tabIndex: _tabIdxes.valueBox,
+ onKeyPress: func,
+ onChange: func,
+ "class": "dojoxGridFCBoxValueBox"
+ }));
+ },
+ _createRangeBox: function(/* widget constructor */cls,/* object */arg){
+ // summary:
+ // Create a DIV containing 2 input widgets, which represents a range, with the given class and arguments
+ var func = lang.hitch(arg.cbox, "_checkValidCriteria");
+ lang.mixin(arg,{
+ tabIndex: _tabIdxes.valueBox,
+ onKeyPress: func,
+ onChange: func
+ });
+ var div = html.create("div", {"class": "dojoxGridFCBoxValueBox"}),
+ start = new cls(arg),
+ txt = html.create("span", {"class": "dojoxGridFCBoxRangeValueTxt", "innerHTML": this.plugin.nls.rangeTo}),
+ end = new cls(arg);
+ html.addClass(start.domNode, "dojoxGridFCBoxStartValue");
+ html.addClass(end.domNode, "dojoxGridFCBoxEndValue");
+ div.appendChild(start.domNode);
+ div.appendChild(txt);
+ div.appendChild(end.domNode);
+ div.domNode = div;
+ //Mock functions for set and get (in place of the old attr function)
+ div.set = function(dummy, args){
+ if(lang.isObject(args)){
+ start.set("value", args.start);
+ end.set("value", args.end);
+ }
+ };
+ div.get = function(){
+ var s = start.get("value"),
+ e = end.get("value");
+ return s && e ? {start: s, end: e} : "";
+ };
+ return div;
+ },
+ changeCurrentColumn: function(/* bool */selectCurCol){
+ var colIdx = this.dlg.curColIdx;
+ //Re-populate the columns in case some of them are set to hidden.
+ this._colSelect.removeOption(this._colOptions);
+ this._colOptions = this._getColumnOptions();
+ this._colSelect.addOption(this._colOptions);
+ this._colSelect.set('value', colIdx >= 0 ? String(colIdx) : "anycolumn");
+ this.updateRuleTitle(true);
+ },
+ curColumn: function(){
+ return this._colSelect.getOptions(this._colSelect.get("value")).label;
+ },
+ curCondition: function(){
+ return this._condSelect.getOptions(this._condSelect.get("value")).label;
+ },
+ curValue: function(){
+ var cond = this._condSelect.get("value");
+ if(cond == "isempty"){return "";}
+ return this._curValueBox ? this._curValueBox.get("value") : "";
+ },
+ save: function(){
+ if(this.isEmpty()){
+ return null;
+ }
+ var colIdx = this._colSelect.get("value"),
+ type = this.dlg.getColumnType(colIdx),
+ value = this.curValue(),
+ cond = this._condSelect.get("value");
+ return {
+ "column": colIdx,
+ "condition": cond,
+ "value": value,
+ "formattedVal": this.formatValue(type, cond, value),
+ "type": type,
+ "colTxt": this.curColumn(),
+ "condTxt": this.curCondition()
+ };
+ },
+ load: function(obj){
+ var tmp = [
+ this._onChangeColumn,
+ this._onChangeCondition
+ ];
+ this._onChangeColumn = this._onChangeCondition = function(){};
+ if(obj.column){
+ this._colSelect.set("value", obj.column);
+ }
+ if(obj.condition){
+ this._condSelect.set("value", obj.condition);
+ }
+ if(obj.type){
+ this._setValueBoxByType(obj.type);
+ }else{
+ obj.type = this.dlg.getColumnType(this._colSelect.get("value"));
+ }
+ var value = obj.value || "";
+ if(value || (obj.type != "date" && obj.type != "time")){
+ this._curValueBox.set("value", value);
+ }
+ this._updateValueBox();
+ setTimeout(lang.hitch(this, function(){
+ this._onChangeColumn = tmp[0];
+ this._onChangeCondition = tmp[1];
+ }), 0);
+ },
+ getExpr: function(){
+ if(this.isEmpty()){
+ return null;
+ }
+ var colval = this._colSelect.get("value");
+ return this.dlg.getExprForCriteria({
+ "type": this.dlg.getColumnType(colval),
+ "column": colval,
+ "condition": this._condSelect.get("value"),
+ "value": this.curValue()
+ });
+ },
+ isEmpty: function(){
+ var cond = this._condSelect.get("value");
+ if(cond == "isempty"){return false;}
+ var v = this.curValue();
+ return v === "" || v === null || typeof v == "undefined" || (typeof v == "number" && isNaN(v));
+ },
+ updateRuleTitle: function(isEmpty){
+ var node = this._pane._buttonWidget.titleTextNode;
+ var title = [
+ "<div class='dojoxEllipsis'>"
+ ];
+ if(isEmpty || this.isEmpty()){
+ node.title = string.substitute(this.plugin.nls.ruleTitleTemplate, [this._ruleIndex || 1]);
+ title.push(node.title);
+ }else{
+ var type = this.dlg.getColumnType(this._colSelect.get("value"));
+ var column = this.curColumn();
+ var condition = this.curCondition();
+ var value = this.formatValue(type, this._condSelect.get("value"), this.curValue());
+ title.push(
+ column,
+ "&nbsp;<span class='dojoxGridRuleTitleCondition'>",
+ condition,
+ "</span>&nbsp;",
+ value
+ );
+ node.title = [column, " ", condition, " ", value].join('');
+ }
+ node.innerHTML = title.join('');
+ if(has("mozilla")){
+ var tt = html.create("div", {
+ "style": "width: 100%; height: 100%; position: absolute; top: 0; left: 0; z-index: 9999;"
+ }, node);
+ tt.title = node.title;
+ }
+ },
+ updateRuleIndex: function(index){
+ if(this._ruleIndex != index){
+ this._ruleIndex = index;
+ if(this.isEmpty()){
+ this.updateRuleTitle();
+ }
+ }
+ },
+ setAriaInfo: function(idx){
+ var dss = string.substitute, nls = this.plugin.nls;
+ this._colSelect.domNode.setAttribute("aria-label", dss(nls.waiColumnSelectTemplate, [idx]));
+ this._condSelect.domNode.setAttribute("aria-label", dss(nls.waiConditionSelectTemplate, [idx]));
+ this._pane._removeCBoxBtn.domNode.setAttribute("aria-label", dss(nls.waiRemoveRuleButtonTemplate, [idx]));
+ this._index = idx;
+ },
+ _getUsableConditions: function(type){
+ var conditions = lang.clone(this.dlg._dataTypeMap[type].conditions);
+ var typeDisabledConds = (this.plugin.args.disabledConditions || {})[type];
+ var colIdx = parseInt(this._colSelect.get("value"), 10);
+ var colDisabledConds = isNaN(colIdx) ?
+ (this.plugin.args.disabledConditions || {})["anycolumn"] :
+ this.plugin.grid.layout.cells[colIdx].disabledConditions;
+ if(!lang.isArray(typeDisabledConds)){
+ typeDisabledConds = [];
+ }
+ if(!lang.isArray(colDisabledConds)){
+ colDisabledConds = [];
+ }
+ var arr = typeDisabledConds.concat(colDisabledConds);
+ if(arr.length){
+ var disabledConds = {};
+ array.forEach(arr, function(c){
+ if(lang.isString(c)){
+ disabledConds[c.toLowerCase()] = true;
+ }
+ });
+ return array.filter(conditions, function(condOption){
+ return !(condOption.value in disabledConds);
+ });
+ }
+ return conditions;
+ },
+ _setConditionsByType: function(/* string */type){
+ var condSelect = this._condSelect;
+ condSelect.removeOption(condSelect.options);
+ condSelect.addOption(this._getUsableConditions(type));
+ this._showSelectOrLabel(this._condSelect, this._condSelectAlt);
+ },
+ _setValueBoxByType: function(/* string */type){
+ if(this._curValueBox){
+ this.valueNode.removeChild(this._curValueBox.domNode);
+ try{
+ this._curValueBox.destroyRecursive();
+ }catch(e){}
+ delete this._curValueBox;
+ }
+ //value box class
+ var vbcls = this.dlg._dataTypeMap[type].valueBoxCls[this._getValueBoxClsInfo(this._colSelect.get("value"), type)],
+ vboxArg = this._getValueBoxArgByType(type);
+ this._curValueBox = this[this._isRange ? "_createRangeBox" : "_createValueBox"](vbcls, vboxArg);
+ this.valueNode.appendChild(this._curValueBox.domNode);
+
+ //Can not move to setAriaInfo, 'cause the value box is created after the defpane is loaded.
+ this._curValueBox.domNode.setAttribute("aria-label", string.substitute(this.plugin.nls.waiValueBoxTemplate,[this._index]));
+ //Now our cbox is completely ready
+ this.dlg.onRendered(this);
+ },
+ //--------------------------UI Configuration--------------------------------------
+ _getValueBoxArgByType: function(/* string */type){
+ // summary:
+ // Get the arguments for the value box construction.
+ var g = this.plugin.grid,
+ cell = g.layout.cells[parseInt(this._colSelect.get("value"), 10)],
+ res = {
+ cbox: this
+ };
+ if(type == "string"){
+ if(cell && (cell.suggestion || cell.autoComplete)){
+ html.mixin(res, {
+ store: g.store,
+ searchAttr: cell.field || cell.name,
+ fetchProperties: {
+ sort: [{"attribute": cell.field || cell.name}],
+ query: g.query,
+ queryOptions: g.queryOptions
+ }
+ });
+ }
+ }else if(type == "boolean"){
+ html.mixin(res, this.dlg.builder.defaultArgs["boolean"]);
+ }
+ if(cell && cell.dataTypeArgs){
+ html.mixin(res, cell.dataTypeArgs);
+ }
+ return res;
+ },
+ formatValue: function(type, cond, v){
+ // summary:
+ // Format the value to be shown in tooltip.
+ if(cond == "isempty"){return "";}
+ if(type == "date" || type == "time"){
+ var opt = {selector: type},
+ fmt = dateLocale.format;
+ if(cond == "range"){
+ return string.substitute(this.plugin.nls.rangeTemplate, [fmt(v.start, opt), fmt(v.end, opt)]);
+ }
+ return fmt(v, opt);
+ }else if(type == "boolean"){
+ return v ? this._curValueBox._lblTrue : this._curValueBox._lblFalse;
+ }
+ return v;
+ },
+ _getValueBoxClsInfo: function(/* int|string */colIndex, /* string */type){
+ // summary:
+ // Decide which value box to use given data type and column index.
+ var cell = this.plugin.grid.layout.cells[parseInt(colIndex, 10)];
+ //Now we only need to handle string. But maybe we need to handle more types here in the future.
+ if(type == "string"){
+ return (cell && (cell.suggestion || cell.autoComplete)) ? "ac" : "dft";
+ }
+ return "dft";
+ }
+});
+
+
+var UniqueComboBox = declare("dojox.grid.enhanced.plugins.filter.UniqueComboBox", ComboBox, {
+ _openResultList: function(results){
+ var cache = {}, s = this.store, colName = this.searchAttr;
+ arguments[0] = array.filter(results, function(item){
+ var key = s.getValue(item, colName), existed = cache[key];
+ cache[key] = true;
+ return !existed;
+ });
+ this.inherited(arguments);
+ },
+ _onKey: function(evt){
+ if(evt.charOrCode === keys.ENTER && this._opened){
+ event.stop(evt);
+ }
+ this.inherited(arguments);
+ }
+});
+var BooleanValueBox = declare("dojox.grid.enhanced.plugins.filter.BooleanValueBox", [_Widget, _TemplatedMixin, _WidgetsInTemplateMixin], {
+ templateString: cache("dojox.grid","enhanced/templates/FilterBoolValueBox.html"),
+ widgetsInTemplate: true,
+ constructor: function(args){
+ var nls = args.cbox.plugin.nls;
+ this._baseId = args.cbox.id;
+ this._lblTrue = args.trueLabel || nls.trueLabel || "true";
+ this._lblFalse = args.falseLabel || nls.falseLabel || "false";
+ this.args = args;
+ },
+ postCreate: function(){
+ this.onChange();
+ },
+ onChange: function(){},
+
+ get: function(prop){
+ return this.rbTrue.get("checked");
+ },
+ set: function(prop, v){
+ this.inherited(arguments);
+ if(prop == "value"){
+ this.rbTrue.set("checked", !!v);
+ this.rbFalse.set("checked", !v);
+ }
+ }
+});
+var FilterDefDialog = declare("dojox.grid.enhanced.plugins.filter.FilterDefDialog", null, {
+ // summary:
+ // Create the filter definition UI.
+ curColIdx: -1,
+ _relOpCls: "logicall",
+ _savedCriterias: null,
+ plugin: null,
+ constructor: function(args){
+ var plugin = this.plugin = args.plugin;
+ this.builder = new FilterBuilder();
+ this._setupData();
+ this._cboxes = [];
+ this.defaultType = plugin.args.defaultType || "string";
+
+ (this.filterDefPane = new FilterDefPane({
+ "dlg": this
+ })).startup();
+ (this._defPane = new Dialog({
+ "refNode": this.plugin.grid.domNode,
+ "title": plugin.nls.filterDefDialogTitle,
+ "class": "dojoxGridFDTitlePane",
+ "iconClass": "dojoxGridFDPaneIcon",
+ "content": this.filterDefPane
+ })).startup();
+
+ this._defPane.connect(plugin.grid.layer('filter'), "filterDef", lang.hitch(this, "_onSetFilter"));
+ plugin.grid.setFilter = lang.hitch(this, "setFilter");
+ plugin.grid.getFilter = lang.hitch(this, "getFilter");
+ plugin.grid.getFilterRelation = lang.hitch(this, function(){
+ return this._relOpCls;
+ });
+
+ plugin.connect(plugin.grid.layout, "moveColumn", lang.hitch(this, "onMoveColumn"));
+ },
+ onMoveColumn: function(sourceViewIndex, destViewIndex, cellIndex, targetIndex, before){
+ if(this._savedCriterias && cellIndex != targetIndex){
+ if(before){ --targetIndex; }
+ var min = cellIndex < targetIndex ? cellIndex : targetIndex;
+ var max = cellIndex < targetIndex ? targetIndex : cellIndex;
+ var dir = targetIndex > min ? 1 : -1;
+ array.forEach(this._savedCriterias, function(sc){
+ var idx = parseInt(sc.column, 10);
+ if(!isNaN(idx) && idx >= min && idx <= max){
+ sc.column = String(idx == cellIndex ? idx + (max - min) * dir : idx - dir);
+ }
+ });
+ }
+ },
+ destroy: function(){
+ this._defPane.destroyRecursive();
+ this._defPane = null;
+ this.filterDefPane = null;
+ this.builder = null;
+ this._dataTypeMap = null;
+ this._cboxes = null;
+ var g = this.plugin.grid;
+ g.setFilter = null;
+ g.getFilter = null;
+ g.getFilterRelation = null;
+ this.plugin = null;
+ },
+ _setupData: function(){
+ var nls = this.plugin.nls;
+ this._dataTypeMap = {
+ // summary:
+ // All supported data types
+ "number":{
+ valueBoxCls: {
+ dft: NumberTextBox
+ },
+ conditions:[
+ {label: nls.conditionEqual, value: "equalto", selected: true},
+ {label: nls.conditionNotEqual, value: "notequalto"},
+ {label: nls.conditionLess, value: "lessthan"},
+ {label: nls.conditionLessEqual, value: "lessthanorequalto"},
+ {label: nls.conditionLarger, value: "largerthan"},
+ {label: nls.conditionLargerEqual, value: "largerthanorequalto"},
+ {label: nls.conditionIsEmpty, value: "isempty"}
+ ]
+ },
+ "string":{
+ valueBoxCls: {
+ dft: TextBox,
+ ac: UniqueComboBox //For autoComplete
+ },
+ conditions:[
+ {label: nls.conditionContains, value: "contains", selected: true},
+ {label: nls.conditionIs, value: "equalto"},
+ {label: nls.conditionStartsWith, value: "startswith"},
+ {label: nls.conditionEndWith, value: "endswith"},
+ {label: nls.conditionNotContain, value: "notcontains"},
+ {label: nls.conditionIsNot, value: "notequalto"},
+ {label: nls.conditionNotStartWith, value: "notstartswith"},
+ {label: nls.conditionNotEndWith, value: "notendswith"},
+ {label: nls.conditionIsEmpty, value: "isempty"}
+ ]
+ },
+ "date":{
+ valueBoxCls: {
+ dft: DateTextBox
+ },
+ conditions:[
+ {label: nls.conditionIs, value: "equalto", selected: true},
+ {label: nls.conditionBefore, value: "lessthan"},
+ {label: nls.conditionAfter, value: "largerthan"},
+ {label: nls.conditionRange, value: "range"},
+ {label: nls.conditionIsEmpty, value: "isempty"}
+ ]
+ },
+ "time":{
+ valueBoxCls: {
+ dft: TimeTextBox
+ },
+ conditions:[
+ {label: nls.conditionIs, value: "equalto", selected: true},
+ {label: nls.conditionBefore, value: "lessthan"},
+ {label: nls.conditionAfter, value: "largerthan"},
+ {label: nls.conditionRange, value: "range"},
+ {label: nls.conditionIsEmpty, value: "isempty"}
+ ]
+ },
+ "boolean": {
+ valueBoxCls: {
+ dft: BooleanValueBox
+ },
+ conditions: [
+ {label: nls.conditionIs, value: "equalto", selected: true},
+ {label: nls.conditionIsEmpty, value: "isempty"}
+ ]
+ }
+ };
+ },
+ setFilter: function(rules, ruleRelation){
+ rules = rules || [];
+ if(!lang.isArray(rules)){
+ rules = [rules];
+ }
+ var func = function(){
+ if(rules.length){
+ this._savedCriterias = array.map(rules, function(rule){
+ var type = rule.type || this.defaultType;
+ return {
+ "type": type,
+ "column": String(rule.column),
+ "condition": rule.condition,
+ "value": rule.value,
+ "colTxt": this.getColumnLabelByValue(String(rule.column)),
+ "condTxt": this.getConditionLabelByValue(type, rule.condition),
+ "formattedVal": rule.formattedVal || rule.value
+ };
+ }, this);
+ this._criteriasChanged = true;
+ if(ruleRelation === "logicall" || ruleRelation === "logicany"){
+ this._relOpCls = ruleRelation;
+ }
+ var exprs = array.map(rules, this.getExprForCriteria, this);
+ exprs = this.builder.buildExpression(exprs.length == 1 ? exprs[0] : {
+ "op": this._relOpCls,
+ "data": exprs
+ });
+ this.plugin.grid.layer("filter").filterDef(exprs);
+ this.plugin.filterBar.toggleClearFilterBtn(false);
+ }
+ this._closeDlgAndUpdateGrid();
+ };
+ if(this._savedCriterias){
+ this._clearWithoutRefresh = true;
+ var handle = connect.connect(this, "clearFilter", this, function(){
+ connect.disconnect(handle);
+ this._clearWithoutRefresh = false;
+ func.apply(this);
+ });
+ this.onClearFilter();
+ }else{
+ func.apply(this);
+ }
+ },
+ getFilter: function(){
+ return lang.clone(this._savedCriterias) || [];
+ },
+ getColumnLabelByValue: function(v){
+ var nls = this.plugin.nls;
+ if(v.toLowerCase() == "anycolumn"){
+ return nls["anyColumnOption"];
+ }else{
+ var cell = this.plugin.grid.layout.cells[parseInt(v, 10)];
+ return cell ? (cell.name || cell.field) : "";
+ }
+ },
+ getConditionLabelByValue: function(type, c){
+ var conditions = this._dataTypeMap[type].conditions;
+ for(var i = conditions.length - 1; i >= 0; --i){
+ var cond = conditions[i];
+ if(cond.value == c.toLowerCase()){
+ return cond.label;
+ }
+ }
+ return "";
+ },
+ addCriteriaBoxes: function(/* int */cnt){
+ // summary:
+ // Add *cnt* criteria boxes to the filter definition pane.
+ // Check overflow if necessary.
+ if(typeof cnt != "number" || cnt <= 0){
+ return;
+ }
+ var cbs = this._cboxes,
+ cc = this.filterDefPane.cboxContainer,
+ total = this.plugin.args.ruleCount,
+ len = cbs.length, cbox;
+ //If overflow, add to max rule count.
+ if(total > 0 && len + cnt > total){
+ cnt = total - len;
+ }
+ for(; cnt > 0; --cnt){
+ cbox = new CriteriaBox({
+ dlg: this
+ });
+ cbs.push(cbox);
+ cc.addChild(cbox);
+ }
+ //If there's no content box in it , AccordionContainer can not startup
+ cc.startup();
+ this._updatePane();
+ this._updateCBoxTitles();
+ cc.selectChild(cbs[cbs.length-1]);
+ //Asign an impossibly large scrollTop to scroll the criteria pane to the bottom.
+ this.filterDefPane.criteriaPane.scrollTop = 1000000;
+ if(cbs.length === 4){
+ if(has("ie") <= 6 && !this.__alreadyResizedForIE6){
+ var size = html.position(cc.domNode);
+ size.w -= metrics.getScrollbar().w;
+ cc.resize(size);
+ this.__alreadyResizedForIE6 = true;
+ }else{
+ cc.resize();
+ }
+ }
+ },
+ removeCriteriaBoxes: function(/* int|CriteriaBox|int[] */cnt,/* bool? */isIdx){
+ // summary:
+ // Remove criteria boxes from the filter definition pane.
+ var cbs = this._cboxes, cc = this.filterDefPane.cboxContainer,
+ len = cbs.length, start = len - cnt,
+ end = len - 1, cbox,
+ curIdx = array.indexOf(cbs, cc.selectedChildWidget.content);
+ if(lang.isArray(cnt)){
+ var i, idxes = cnt;
+ idxes.sort();
+ cnt = idxes.length;
+ //find a rule that's not deleted.
+ //must find and focus the last one, or the hack will not work.
+ for(i = len - 1; i >= 0 && array.indexOf(idxes, i) >= 0; --i){}
+ if(i >= 0){
+ //must select before remove
+ if(i != curIdx){
+ cc.selectChild(cbs[i]);
+ }
+ //idxes is sorted from small to large,
+ //so travel reversely won't need change index after delete from array.
+ for(i = cnt-1; i >= 0; --i){
+ if(idxes[i] >= 0 && idxes[i] < len){
+ cc.removeChild(cbs[idxes[i]]);
+ cbs.splice(idxes[i],1);
+ }
+ }
+ }
+ start = cbs.length;
+ }else{
+ if(isIdx === true){
+ if(cnt >= 0 && cnt < len){
+ start = end = cnt;
+ cnt = 1;
+ }else{
+ return;
+ }
+ }else{
+ if(cnt instanceof CriteriaBox){
+ cbox = cnt;
+ cnt = 1;
+ start = end = array.indexOf(cbs, cbox);
+ }else if(typeof cnt != "number" || cnt <= 0){
+ return;
+ }else if(cnt >= len){
+ cnt = end;
+ start = 1;
+ }
+ }
+ if(end < start){
+ return;
+ }
+ //must select before remove
+ if(curIdx >= start && curIdx <= end){
+ cc.selectChild(cbs[start ? start-1 : end+1]);
+ }
+ for(; end >= start; --end){
+ cc.removeChild(cbs[end]);
+ }
+ cbs.splice(start, cnt);
+ }
+ this._updatePane();
+ this._updateCBoxTitles();
+ if(cbs.length === 3){
+ //In ie6, resize back to the normal width will cause the title button look strange.
+ cc.resize();
+ }
+ },
+ getCriteria: function(/* int */idx){
+ // summary:
+ // Get the *idx*-th criteria.
+ if(typeof idx != "number"){
+ return this._savedCriterias ? this._savedCriterias.length : 0;
+ }
+ if(this._savedCriterias && this._savedCriterias[idx]){
+ return lang.mixin({
+ relation: this._relOpCls == "logicall" ? this.plugin.nls.and : this.plugin.nls.or
+ },this._savedCriterias[idx]);
+ }
+ return null;
+ },
+ getExprForCriteria: function(rule){
+ if(rule.column == "anycolumn"){
+ var cells = array.filter(this.plugin.grid.layout.cells, function(cell){
+ return !(cell.filterable === false || cell.hidden);
+ });
+ return {
+ "op": "logicany",
+ "data": array.map(cells, function(cell){
+ return this.getExprForColumn(rule.value, cell.index, rule.type, rule.condition);
+ }, this)
+ };
+ }else{
+ return this.getExprForColumn(rule.value, rule.column, rule.type, rule.condition);
+ }
+ },
+ getExprForColumn: function(value, colIdx, type, condition){
+ colIdx = parseInt(colIdx, 10);
+ var cell = this.plugin.grid.layout.cells[colIdx],
+ colName = cell.field || cell.name,
+ obj = {
+ "datatype": type || this.getColumnType(colIdx),
+ "args": cell.dataTypeArgs,
+ "isColumn": true
+ },
+ operands = [lang.mixin({"data": this.plugin.args.isServerSide ? colName : cell}, obj)];
+ obj.isColumn = false;
+ if(condition == "range"){
+ operands.push(lang.mixin({"data": value.start}, obj),
+ lang.mixin({"data": value.end}, obj));
+ }else if(condition != "isempty"){
+ operands.push(lang.mixin({"data": value}, obj));
+ }
+ return {
+ "op": condition,
+ "data": operands
+ };
+ },
+ getColumnType: function(/* int */colIndex){
+ var cell = this.plugin.grid.layout.cells[parseInt(colIndex, 10)];
+ if(!cell || !cell.datatype){
+ return this.defaultType;
+ }
+ var type = String(cell.datatype).toLowerCase();
+ return this._dataTypeMap[type] ? type : this.defaultType;
+ },
+ //////////////////////////////////////////////////////////////////////////////////////////////////////////
+ clearFilter: function(noRefresh){
+ // summary:
+ // Clear filter definition.
+ if(!this._savedCriterias){
+ return;
+ }
+ this._savedCriterias = null;
+ this.plugin.grid.layer("filter").filterDef(null);
+ try{
+ this.plugin.filterBar.toggleClearFilterBtn(true);
+ this.filterDefPane._clearFilterBtn.set("disabled", true);
+ this.removeCriteriaBoxes(this._cboxes.length-1);
+ this._cboxes[0].load({});
+ }catch(e){
+ //Any error means the filter is defined outside this plugin.
+ }
+ if(noRefresh){
+ this.closeDialog();
+ }else{
+ this._closeDlgAndUpdateGrid();
+ }
+ },
+ showDialog: function(/* int */colIndex){
+ // summary:
+ // Show the filter defintion dialog.
+ this._defPane.show();
+ this.plugin.filterStatusTip.closeDialog();
+ this._prepareDialog(colIndex);
+ },
+ closeDialog: function(){
+ // summary:
+ // Close the filter definition dialog.
+ if(this._defPane.open){
+ this._defPane.hide();
+ }
+ },
+ onFilter: function(e){
+ // summary:
+ // Triggered when the "Filter" button is clicked.
+ if(this.canFilter()){
+ this._defineFilter();
+ this._closeDlgAndUpdateGrid();
+ this.plugin.filterBar.toggleClearFilterBtn(false);
+ }
+ },
+ onClearFilter: function(e){
+ // summary:
+ // Triggered when the "Clear" button is clicked.
+ if(this._savedCriterias){
+ if(this._savedCriterias.length >= this.plugin.ruleCountToConfirmClearFilter){
+ this.plugin.clearFilterDialog.show();
+ }else{
+ this.clearFilter(this._clearWithoutRefresh);
+ }
+ }
+ },
+ onCancel: function(e){
+ // summary:
+ // Triggered when the "Cancel" buttton is clicked.
+ var sc = this._savedCriterias;
+ var cbs = this._cboxes;
+ if(sc){
+ this.addCriteriaBoxes(sc.length - cbs.length);
+ this.removeCriteriaBoxes(cbs.length - sc.length);
+ array.forEach(sc, function(c, i){
+ cbs[i].load(c);
+ });
+ }else{
+ this.removeCriteriaBoxes(cbs.length - 1);
+ cbs[0].load({});
+ }
+ this.closeDialog();
+ },
+ onRendered: function(cbox){
+ // summary:
+ // Triggered when the rendering of the filter definition dialog is completely finished.
+ // cbox:
+ // Current visible criteria box
+ if(!has("ff")){
+ var elems = dijitA11y._getTabNavigable(html.byId(cbox.domNode));
+ dijitFocus.focus(elems.lowest || elems.first);
+ }else{
+ var dp = this._defPane;
+ dp._getFocusItems(dp.domNode);
+ dijitFocus.focus(dp._firstFocusItem);
+ }
+ },
+ _onSetFilter: function(filterDef){
+ // summary:
+ // If someone clear the filter def in the store directly, we must clear it in the UI.
+ // If someone defines a filter, don't know how to handle it!
+ if(filterDef === null && this._savedCriterias){
+ this.clearFilter();
+ }
+ },
+ _prepareDialog: function(/* int */colIndex){
+ var sc = this._savedCriterias,
+ cbs = this._cboxes, i, cbox;
+ this.curColIdx = colIndex;
+ if(!sc){
+ if(cbs.length === 0){
+ this.addCriteriaBoxes(1);
+ }else{
+ //Re-populate columns anyway, because we don't know when the column is set to hidden.
+ for(i = 0; (cbox = cbs[i]); ++i){
+ cbox.changeCurrentColumn();
+ }
+ }
+ }else if(this._criteriasChanged){
+ this.filterDefPane._relSelect.set("value", this._relOpCls === "logicall" ? "0" : "1");
+ this._criteriasChanged = false;
+ var needNewCBox = sc.length > cbs.length ? sc.length - cbs.length : 0;
+ this.addCriteriaBoxes(needNewCBox);
+ this.removeCriteriaBoxes(cbs.length - sc.length);
+ this.filterDefPane._clearFilterBtn.set("disabled", false);
+ for(i = 0; i < cbs.length - needNewCBox; ++i){
+ cbs[i].load(sc[i]);
+ }
+ if(needNewCBox > 0){
+ var handled = [], handle = connect.connect(this, "onRendered", function(cbox){
+ var i = array.indexOf(cbs, cbox);
+ if(!handled[i]){
+ handled[i] = true;
+ if(--needNewCBox === 0){
+ connect.disconnect(handle);
+ }
+ cbox.load(sc[i]);
+ }
+ });
+ }
+ }
+ //Since we're allowed to remove cboxes when the definition pane is not shown,
+ //we have to resize the container to have a correct _verticalSpace.
+ this.filterDefPane.cboxContainer.resize();
+ },
+ _defineFilter: function(){
+ var cbs = this._cboxes,
+ filterCboxes = function(method){
+ return array.filter(array.map(cbs, function(cbox){
+ return cbox[method]();
+ }), function(result){
+ return !!result;
+ });
+ },
+ exprs = filterCboxes("getExpr");
+ this._savedCriterias = filterCboxes("save");
+ exprs = exprs.length == 1 ? exprs[0] : {
+ "op": this._relOpCls,
+ "data": exprs
+ };
+ exprs = this.builder.buildExpression(exprs);
+
+ this.plugin.grid.layer("filter").filterDef(exprs);
+ this.filterDefPane._clearFilterBtn.set("disabled", false);
+ },
+ _updateCBoxTitles: function(){
+ for(var cbs = this._cboxes, i = cbs.length; i > 0; --i){
+ cbs[i - 1].updateRuleIndex(i);
+ cbs[i - 1].setAriaInfo(i);
+ }
+ },
+ _updatePane: function(){
+ var cbs = this._cboxes,
+ defPane = this.filterDefPane;
+ defPane._addCBoxBtn.set("disabled", cbs.length == this.plugin.args.ruleCount);
+ defPane._filterBtn.set("disabled", !this.canFilter());
+ },
+ canFilter: function(){
+ return array.filter(this._cboxes, function(cbox){
+ return !cbox.isEmpty();
+ }).length > 0;
+ },
+ _closeDlgAndUpdateGrid: function(){
+ this.closeDialog();
+ var g = this.plugin.grid;
+ g.showMessage(g.loadingMessage);
+ setTimeout(lang.hitch(g, g._refresh), this._defPane.duration + 10);
+ }
+});
+
+return FilterDefDialog;
+});
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/FilterLayer.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/FilterLayer.js
new file mode 100644
index 0000000..e8f7ac4
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/FilterLayer.js
@@ -0,0 +1,411 @@
+//>>built
+define("dojox/grid/enhanced/plugins/filter/FilterLayer", [
+ "dojo/_base/declare",
+ "dojo/_base/lang",
+ "dojo/_base/window",
+ "dojo/_base/json",
+ "../_StoreLayer"
+], function(declare, lang, win, json, layers){
+
+ var cmdSetFilter = "filter",
+ cmdClearFilter = "clear",
+ hitchIfCan = function(scope, func){
+ return func ? lang.hitch(scope || win.global, func) : function(){};
+ },
+ shallowClone = function(obj){
+ var res = {};
+ if(obj && lang.isObject(obj)){
+ for(var name in obj){
+ res[name] = obj[name];
+ }
+ }
+ return res;
+ };
+ var _FilterLayerMixin = declare("dojox.grid.enhanced.plugins.filter._FilterLayerMixin", null, {
+/*=====
+ // _filter: _ConditionExpr
+ // The filter definition
+ _filter: null,
+
+ filterDef: function(filter){
+ // summary:
+ // Get/set/clear the filter definition
+ // tags:
+ // public
+ // filter: (_ConditionExpr|null)?
+ // null: clear filter definition
+ // undefined: it's getter
+ // returns:
+ // A filter definition if it's getter.
+ },
+=====*/
+ tags: ["sizeChange"],
+ name: function(){
+ // summary:
+ // override from _StoreLayer.name
+ return "filter"; //string
+ },
+ onFilterDefined: function(filter){},
+
+ onFiltered: function(filteredSize, totalSize){
+ // summary:
+ // Called when store data is filtered. This event is before *onComplete*, after *onBegin*.
+ // tags:
+ // callback extension
+ // filteredSize: Integer
+ // The number of remaining fetched items after filtering.
+ // totalSize: Integer
+ // The number of original fetched items.
+ }
+ });
+ var ServerSideFilterLayer = declare("dojox.grid.enhanced.plugins.filter.ServerSideFilterLayer", [layers._ServerSideLayer, _FilterLayerMixin], {
+ constructor: function(args){
+ this._onUserCommandLoad = args.setupFilterQuery || this._onUserCommandLoad;
+ this.filterDef(null);
+ },
+ filterDef: function(/* (_ConditionExpr|null)? */filter){
+ // summary:
+ // See _FilterLayerMixin.filterDef
+ if(filter){
+ this._filter = filter;
+ var obj = filter.toObject();
+ //Stateless implementation will need to parse the filter object.
+ this.command(cmdSetFilter, this._isStateful ? json.toJson(obj) : obj);
+ this.command(cmdClearFilter, null);
+ this.useCommands(true);
+ this.onFilterDefined(filter);
+ }else if(filter === null){
+ this._filter = null;
+ this.command(cmdSetFilter, null);
+ this.command(cmdClearFilter, true);
+ this.useCommands(true);
+ this.onFilterDefined(null);
+ }
+ return this._filter; //_ConditionExpr
+ },
+ onCommandLoad: function(/* (in)string */responce, /* (in|out)keywordArgs */ userRequest){
+ // summary:
+ // override from _ServerSideLayer.onCommandLoad
+ this.inherited(arguments);
+ var oldOnBegin = userRequest.onBegin;
+ if(this._isStateful){
+ var filteredSize;
+ if(responce){
+ this.command(cmdSetFilter, null);
+ this.command(cmdClearFilter, null);
+ this.useCommands(false);
+ var sizes = responce.split(',');
+ if(sizes.length >= 2){
+ filteredSize = this._filteredSize = parseInt(sizes[0], 10);
+ this.onFiltered(filteredSize, parseInt(sizes[1], 10));
+ }else{
+ //Error here.
+ return;
+ }
+ }else{
+ filteredSize = this._filteredSize;
+ }
+ if(this.enabled()){
+ userRequest.onBegin = function(size, req){
+ hitchIfCan(userRequest.scope, oldOnBegin)(filteredSize, req);
+ };
+ }
+ }else{
+ var _this = this;
+ userRequest.onBegin = function(size, req){
+ if(!_this._filter){
+ _this._storeSize = size;
+ }
+ _this.onFiltered(size, _this._storeSize || size);
+ req.onBegin = oldOnBegin;
+ hitchIfCan(userRequest.scope, oldOnBegin)(size, req);
+ };
+ }
+ }
+ });
+ var ClientSideFilterLayer = declare("dojox.grid.enhanced.plugins.filter.ClientSideFilterLayer", [layers._StoreLayer, _FilterLayerMixin], {
+ // summary:
+ // Add a client side filter layer on top of the data store,
+ // so any filter expression can be applied to the store.
+/*=====
+ //_items: Array,
+ // Cached items (may contain holes)
+ _items: [],
+
+ //_result: Array,
+ // Current fetch result
+ _result: [],
+
+ //_resultStartIdx: Integer,
+ // The index in cache of the first result item
+ _resultStartIdx: 0,
+
+ //_indexMap: Array,
+ // A map from the row index of this._items to the row index of the original store.
+ _indexMap: null,
+
+ //_getter: function(datarow, colArg, rowIndex, store);
+ // A user defined way to get data from store
+ _getter: null,
+
+ // _nextUnfetchedIdx: Integer
+ // The index of the next item in the store that is never fetched.
+ _nextUnfetchedIdx: 0,
+=====*/
+ // _storeSize: Integer
+ // The actual size of the original store
+ _storeSize: -1,
+
+ // _fetchAll
+ // If the store is small or store size must be correct when onBegin is called,
+ // we should fetch and filter all the items on the first query.
+ _fetchAll: true,
+
+ constructor: function(args){
+ this.filterDef(null);
+ args = lang.isObject(args) ? args : {};
+ this.fetchAllOnFirstFilter(args.fetchAll);
+ this._getter = lang.isFunction(args.getter) ? args.getter : this._defaultGetter;
+ },
+ _defaultGetter: function(datarow, colName, rowIndex, store){
+ return store.getValue(datarow, colName);
+ },
+ filterDef: function(/* (_ConditionExpr|null)? */filter){
+ // summary:
+ // See _FilterLayerMixin.filterDef
+ if(filter !== undefined){
+ this._filter = filter;
+ this.invalidate();
+ this.onFilterDefined(filter);
+ }
+ return this._filter; //_ConditionExpr
+ },
+ setGetter: function(/* function */getter){
+ // summary:
+ // Set the user defined way to retrieve data from store.
+ // tags:
+ // public
+ // getter: function(datarow, colArg, rowIndex, store);
+ if(lang.isFunction(getter)){
+ this._getter = getter;
+ }
+ },
+ fetchAllOnFirstFilter: function(/* bool? */toFetchAll){
+ // summary:
+ // The get/set function for fetchAll.
+ // tags:
+ // public
+ // toFetchAll: boolean?
+ // If provided, it's a set function, otherwise it's a get function.
+ // returns:
+ // Whether fetch all on first filter if this is a getter
+ if(toFetchAll !== undefined){
+ this._fetchAll = !!toFetchAll;
+ }
+ return this._fetchAll; //Boolean
+ },
+ invalidate: function(){
+ // summary:
+ // Clear all the status information of this layer
+ // tags:
+ // private
+ this._items = [];
+ this._nextUnfetchedIdx = 0;
+ this._result = [];
+ this._indexMap = [];
+ this._resultStartIdx = 0;
+ },
+ //----------------Private Functions-----------------------------
+ _fetch: function(userRequest,filterRequest){
+ // summary:
+ // Implement _StoreLayer._fetch
+ // tags:
+ // private callback
+ // filterRequest: dojo.data.api.Request
+ // The actual request used in store.fetch.
+ // This function is called recursively to fill the result store items
+ // until the user specified item count is reached. Only in recursive calls,
+ // this parameter is valid.
+ if(!this._filter){
+ //If we don't have any filter, use the original request and fetch.
+ var old_onbegin = userRequest.onBegin, _this = this;
+ userRequest.onBegin = function(size, r){
+ hitchIfCan(userRequest.scope, old_onbegin)(size, r);
+ _this.onFiltered(size, size);
+ };
+ this.originFetch(userRequest);
+ return userRequest;
+ }
+ try{
+ //If the fetch is at the beginning, user's start position is used;
+ //If we are in a recursion, our own request is used.
+ var start = filterRequest ? filterRequest._nextResultItemIdx : userRequest.start;
+ start = start || 0;
+ if(!filterRequest){
+ //Initially, we have no results.
+ this._result = [];
+ this._resultStartIdx = start;
+ var sortStr;
+ if(lang.isArray(userRequest.sort) && userRequest.sort.length > 0 &&
+ //Sort info will stay here in every re-fetch, so remember it!
+ (sortStr = json.toJson(userRequest.sort)) != this._lastSortInfo){
+ //If we should sort data, all the old caches are no longer valid.
+ this.invalidate();
+ this._lastSortInfo = sortStr;
+ }
+ }
+ //this._result contains the current fetch result (of every recursion).
+ var end = typeof userRequest.count == "number" ?
+ start + userRequest.count - this._result.length : this._items.length;
+ //Try to retrieve all the items from our cache.
+ //Only need items after userRequest.start, test it in case start is smaller.
+ if(this._result.length){
+ this._result = this._result.concat(this._items.slice(start, end));
+ }else{
+ this._result = this._items.slice(userRequest.start, typeof userRequest.count == "number" ?
+ userRequest.start + userRequest.count : this._items.length);
+ }
+ if(this._result.length >= userRequest.count || this._hasReachedStoreEnd()){
+ //We already have had enough items, or we have to stop fetching because there's nothing more to fetch.
+ this._completeQuery(userRequest);
+ }else{
+ //User's request hasn't been finished yet. Fetch more.
+ if(!filterRequest){
+ //Initially, we've got to create a new request object.
+ filterRequest = shallowClone(userRequest);
+ //Use our own onBegin function to remember the total size of the original store.
+ filterRequest.onBegin = lang.hitch(this, this._onFetchBegin);
+ filterRequest.onComplete = lang.hitch(this, function(items, req){
+ //We've fetched some more, so march ahead!
+ this._nextUnfetchedIdx += items.length;
+ //Actual filtering work goes here. Survived items are added to our cache.
+ //req is our own request object.
+ this._doFilter(items, req.start, userRequest);
+ //Recursively call this function. Let's do this again!
+ this._fetch(userRequest, req);
+ });
+ }
+ //Fetch starts from the next unfetched item.
+ filterRequest.start = this._nextUnfetchedIdx;
+ //If store is small, we should only fetch once.
+ if(this._fetchAll){
+ delete filterRequest.count;
+ }
+ //Remember we've (maybe) already added something to our result array, so next time we should not start over again.
+ filterRequest._nextResultItemIdx = end < this._items.length ? end : this._items.length;
+ //Actual fetch work goes here.
+ this.originFetch(filterRequest);
+ }
+ }catch(e){
+ if(userRequest.onError){
+ hitchIfCan(userRequest.scope, userRequest.onError)(e, userRequest);
+ }else{
+ throw e;
+ }
+ }
+ return userRequest;
+ },
+ _hasReachedStoreEnd: function(){
+ // summary:
+ // Check whether all the items in the original store have been fetched.
+ // tags:
+ // private
+ return this._storeSize >= 0 && this._nextUnfetchedIdx >= this._storeSize; //Boolean
+ },
+ _applyFilter: function(/* data item */datarow,/* Integer */rowIndex){
+ // summary:
+ // Apply the filter to a row of data
+ // tags:
+ // private
+ // returns:
+ // whether this row survived the filter.
+ var g = this._getter, s = this._store;
+ try{
+ return !!(this._filter.applyRow(datarow, function(item, arg){
+ return g(item, arg, rowIndex, s);
+ }).getValue());
+ }catch(e){
+ console.warn("FilterLayer._applyFilter() error: ", e);
+ return false;
+ }
+ },
+ _doFilter: function(/* Array */items,/* Integer */startIdx,/* object */userRequest){
+ // summary:
+ // Use the filter expression to filter items. Survived items are stored in this._items.
+ // The given items start from "startIdx" in the original store.
+ // tags:
+ // private
+ for(var i = 0, cnt = 0; i < items.length; ++i){
+ if(this._applyFilter(items[i], startIdx + i)){
+ hitchIfCan(userRequest.scope, userRequest.onItem)(items[i], userRequest);
+ cnt += this._addCachedItems(items[i], this._items.length);
+ this._indexMap.push(startIdx + i);
+ }
+ }
+ },
+ _onFetchBegin: function(/* Integer */size,/* request object */req){
+ // summary:
+ // This function is used to replace the user's onFetchBegin in store.fetch
+ // tags:
+ // private
+ this._storeSize = size;
+ },
+ _completeQuery: function(/* request object */userRequest){
+ // summary:
+ // Logically, the user's query is completed here, i.e., all the filtered results are ready.
+ // (or their index mappings are ready)
+ // tags:
+ // private
+ var size = this._items.length;
+ if(this._nextUnfetchedIdx < this._storeSize){
+ //FIXME: There's still some items in the original store that are not fetched & filtered.
+ //So we have to estimate a little bigger size to allow scrolling to these unfetched items.
+ //However, this behavior is ONLY correct in Grid! Any better way to do this?
+ size++;
+ }
+ hitchIfCan(userRequest.scope, userRequest.onBegin)(size,userRequest);
+ this.onFiltered(this._items.length, this._storeSize);
+ hitchIfCan(userRequest.scope, userRequest.onComplete)(this._result, userRequest);
+ },
+ _addCachedItems: function(/* Array */items,/* Integer */filterStartIdx){
+ // summary:
+ // Add data items to the cache. The insert point is at *filterStartIdx*
+ // tags:
+ // private
+ // items: Array
+ // Data items to add.
+ // filterStartIdx: Integer
+ // The start point to insert in the cache.
+ if(!lang.isArray(items)){
+ items = [items];
+ }
+ for(var k = 0; k < items.length; ++k){
+ this._items[filterStartIdx + k] = items[k];
+ }
+ return items.length;
+ },
+ onRowMappingChange: function(mapping){
+ //This function runs in FilterLayer scope!
+ if(this._filter){
+ var m = lang.clone(mapping),
+ alreadyUpdated = {};
+ for(var r in m){
+ r = parseInt(r, 10);
+ mapping[this._indexMap[r]] = this._indexMap[m[r]];
+ if(!alreadyUpdated[this._indexMap[r]]){
+ alreadyUpdated[this._indexMap[r]] = true;
+ }
+ if(!alreadyUpdated[r]){
+ alreadyUpdated[r] = true;
+ delete mapping[r];
+ }
+ }
+ }
+ }
+ });
+
+ return lang.mixin({
+ ServerSideFilterLayer: ServerSideFilterLayer,
+ ClientSideFilterLayer: ClientSideFilterLayer
+ }, layers);
+});
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/FilterStatusTip.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/FilterStatusTip.js
new file mode 100644
index 0000000..36f4430
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/FilterStatusTip.js
@@ -0,0 +1,148 @@
+//>>built
+define("dojox/grid/enhanced/plugins/filter/FilterStatusTip", [
+ "dojo/_base/declare",
+ "dojo/_base/array",
+ "dojo/_base/lang",
+ "dojo/query",
+ "dojo/cache",
+ "dojo/string",
+ "dojo/date/locale",
+ "dijit/_Widget",
+ "dijit/_TemplatedMixin",
+ "dijit/_WidgetsInTemplateMixin",
+ "dijit/TooltipDialog",
+ "dijit/form/Button",
+ "dijit/_base/popup",
+ "dojo/i18n!../../nls/Filter"
+], function(declare, array, lang, query, cache, string, dateLocale, _Widget,
+ _TemplatedMixin, _WidgetsInTemplateMixin, TooltipDialog, Button, popup){
+
+ var gridCssCls = "", headerCssCls = "", cellCssCls = "", rowCssCls = "",
+ oddRowCssCls = "dojoxGridFStatusTipOddRow",
+ handleHolderCssCls = "dojoxGridFStatusTipHandle",
+ conditionCssCls = "dojoxGridFStatusTipCondition",
+ _removeRuleIconCls = "dojoxGridFStatusTipDelRuleBtnIcon",
+ _statusFooter = "</tbody></table>";
+
+ var FilterStatusPane = declare("dojox.grid.enhanced.plugins.filter.FilterStatusPane", [_Widget, _TemplatedMixin], {
+ templateString: cache("dojox.grid", "enhanced/templates/FilterStatusPane.html")
+ });
+
+ return declare("dojox.grid.enhanced.plugins.filter.FilterStatusTip", null, {
+ // summary:
+ // Create the status tip UI.
+ constructor: function(args){
+ var plugin = this.plugin = args.plugin;
+ this._statusHeader = ["<table border='0' cellspacing='0' class='",
+ gridCssCls, "'><thead><tr class='",
+ headerCssCls, "'><th class='",
+ cellCssCls, "'><div>", plugin.nls["statusTipHeaderColumn"], "</div></th><th class='",
+ cellCssCls, " lastColumn'><div>", plugin.nls["statusTipHeaderCondition"], "</div></th></tr></thead><tbody>"
+ ].join('');
+ this._removedCriterias = [];
+ this._rules = [];
+ this.statusPane = new FilterStatusPane();
+ this._dlg = new TooltipDialog({
+ "class": "dojoxGridFStatusTipDialog",
+ content: this.statusPane,
+ autofocus: false
+ });
+ this._dlg.connect(this._dlg.domNode, 'onmouseleave', lang.hitch(this, this.closeDialog));
+ this._dlg.connect(this._dlg.domNode, 'click', lang.hitch(this, this._modifyFilter));
+ },
+ destroy: function(){
+ this._dlg.destroyRecursive();
+ },
+ //-----------------Public Functions------------------------
+ showDialog: function(/* int */pos_x,/* int */pos_y, columnIdx){
+ this._pos = {x:pos_x,y:pos_y};
+ popup.close(this._dlg);
+ this._removedCriterias = [];
+ this._rules = [];
+ this._updateStatus(columnIdx);
+ popup.open({
+ popup: this._dlg,
+ parent: this.plugin.filterBar,
+ onCancel: function(){},
+ x:pos_x - 12,
+ y:pos_y - 3
+ });
+ },
+ closeDialog: function(){
+ popup.close(this._dlg);
+ if(this._removedCriterias.length){
+ this.plugin.filterDefDialog.removeCriteriaBoxes(this._removedCriterias);
+ this._removedCriterias = [];
+ this.plugin.filterDefDialog.onFilter();
+ }
+ },
+ //-----------------Private Functions---------------------------
+ _updateStatus: function(columnIdx){
+ var res, p = this.plugin,
+ nls = p.nls,
+ sp = this.statusPane,
+ fdg = p.filterDefDialog;
+ if(fdg.getCriteria() === 0){
+ sp.statusTitle.innerHTML = nls["statusTipTitleNoFilter"];
+ sp.statusRel.innerHTML = "";
+ var cell = p.grid.layout.cells[columnIdx];
+ var colName = cell ? "'" + (cell.name || cell.field) + "'" : nls["anycolumn"];
+ res = string.substitute(nls["statusTipMsg"], [colName]);
+ }else{
+ sp.statusTitle.innerHTML = nls["statusTipTitleHasFilter"];
+ sp.statusRel.innerHTML = fdg._relOpCls == "logicall" ? nls["statusTipRelAll"] : nls["statusTipRelAny"];
+ this._rules = [];
+ var i = 0, c = fdg.getCriteria(i++);
+ while(c){
+ c.index = i - 1;
+ this._rules.push(c);
+ c = fdg.getCriteria(i++);
+ }
+ res = this._createStatusDetail();
+ }
+ sp.statusDetailNode.innerHTML = res;
+ this._addButtonForRules();
+ },
+ _createStatusDetail: function(){
+ return this._statusHeader + array.map(this._rules, function(rule, i){
+ return this._getCriteriaStr(rule, i);
+ }, this).join('') + _statusFooter;
+ },
+ _addButtonForRules: function(){
+ if(this._rules.length > 1){
+ query("." + handleHolderCssCls, this.statusPane.statusDetailNode).forEach(lang.hitch(this, function(nd, idx){
+ (new Button({
+ label: this.plugin.nls["removeRuleButton"],
+ showLabel: false,
+ iconClass: _removeRuleIconCls,
+ onClick: lang.hitch(this, function(e){
+ e.stopPropagation();
+ this._removedCriterias.push(this._rules[idx].index);
+ this._rules.splice(idx,1);
+ this.statusPane.statusDetailNode.innerHTML = this._createStatusDetail();
+ this._addButtonForRules();
+ })
+ })).placeAt(nd, "last");
+ }));
+ }
+ },
+ _getCriteriaStr: function(/* object */c, /* int */rowIdx){
+ var res = ["<tr class='", rowCssCls,
+ " ", (rowIdx % 2 ? oddRowCssCls : ""),
+ "'><td class='", cellCssCls, "'>", c.colTxt,
+ "</td><td class='", cellCssCls,
+ "'><div class='", handleHolderCssCls, "'><span class='", conditionCssCls,
+ "'>", c.condTxt, "&nbsp;</span>",
+ c.formattedVal, "</div></td></tr>"];
+ return res.join('');
+ },
+ _modifyFilter: function(){
+ this.closeDialog();
+ var p = this.plugin;
+ p.filterDefDialog.showDialog(p.filterBar.getColumnIdx(this._pos.x));
+ }
+ });
+
+
+ return FilterStatusTip;
+});
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/_ConditionExpr.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/_ConditionExpr.js
new file mode 100644
index 0000000..87f3461
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/_ConditionExpr.js
@@ -0,0 +1,243 @@
+//>>built
+define("dojox/grid/enhanced/plugins/filter/_ConditionExpr", [
+ "dojo/_base/declare",
+ "dojo/_base/lang",
+ "dojo/_base/array"
+], function(declare, lang, array){
+
+var _ConditionExpr = declare("dojox.grid.enhanced.plugins.filter._ConditionExpr", null, {
+ // summary:
+ // The most abstract class for all condition expressions.
+ // A condition expression can be applied on a data row (e.g. an item in a store)
+ // and generate a result condition expression.
+ // tags:
+ // abstract
+
+ _name: "expr",
+
+ applyRow: function(/* data item */datarow,/* function(row,colArg) */getter){
+ // summary:
+ // *Unimplemented Interface*
+ // Apply this condition expression on the given datarow, return a result expression.
+ // taqs:
+ // public extension
+ // datarow: object
+ // A data item of a store.
+ // getter: function(datarow, colArg)
+ // A user defined function that extract cell data from *datarow*.
+ // *colArg* is an argument that provides a kind of column information.
+ // It is defined by user in the constructor of a _DataExpr object.
+ // returns:
+ // MUST return a _ConditionExpr object
+ throw new Error("_ConditionExpr.applyRow: unimplemented interface");
+ },
+
+ toObject: function(){
+ // summary:
+ // Convert this data expression to a simple object. Mainly used for serialization.
+ // tags:
+ // public extension
+ // returns:
+ // An object for serialization.
+ return {}; //Object
+ },
+
+ getName: function(){
+ // summary:
+ // Get the name of this kind of expression.
+ // tags:
+ // public extension
+ // returns:
+ // the name of this kind of expression
+ return this._name; //String
+ }
+});
+
+var _DataExpr = declare("dojox.grid.enhanced.plugins.filter._DataExpr", _ConditionExpr, {
+ // summary:
+ // The most abstract class for all data expressions.
+ // A _DataExpr is a condition expression for a single data value.
+ // If the data value to be represent is a pure value (literal value, like string/number/Date/...)
+ // this _DataExpr is nothing more than a simple wrapper.
+ // If the data value to be represent is in a store, then _DataExpr is responsible to extract it
+ // from the store when this condition is applied to a data row.
+ // private fields:
+ // _value: anything
+ // _colArg: anything
+ _name: "data",
+
+ constructor: function(/* anything */dataValue,/* bool */isColumn, /* object */convertArgs){
+ // summary:
+ // If a _DataExpr is constructed with only one argument, this argument is regarded as a pure value.
+ // If the second argument is exactly a boolean true (no implict type transformation,
+ // so as to allow derived classes accept more arguments while retain *isColumn* to be optional),
+ // then this _DataExpr represents a column, and it's applyRow method is not a no-op.
+ // dataValue: anything
+ // If *isColumn* is a boolean true, then it should be a kind of column information, like field name
+ // or column index. Otherwise, it is regarded as a pure value, and the getValue method will simply
+ // return it.
+ // isColumn: boolean?
+ // Optional. To specify whether this _DataExpr represents a column or a pure value.
+ this._convertArgs = convertArgs || {};
+ if(lang.isFunction(this._convertArgs.convert)){
+ this._convertData = lang.hitch(this._convertArgs.scope, this._convertArgs.convert);
+ }
+ if(isColumn){
+ this._colArg = dataValue;
+ }else{
+ this._value = this._convertData(dataValue, this._convertArgs);
+ }
+ },
+
+ getValue: function(){
+ // summary:
+ // If this is a pure value wrapper, simply return the value.
+ // Otherwise (it's a column), return is undefined.
+ // tags:
+ // public
+ // returns:
+ // the value of this data expression.
+ return this._value; //String
+ },
+
+ applyRow: function(/* data item */datarow,/* function(row,colIdx) */getter){
+ // summary:
+ // Implement _ConditionExpr.applyRow.
+ // If this is a pure value, simply return self.
+ // Otherwise, extract the cell data from datarow using the given getter function,
+ // and then convert this cell data to a _DataExpr and return the expression.
+ return typeof this._colArg == "undefined" ? this : //_ConditionExpr
+ new (lang.getObject(this.declaredClass))(
+ this._convertData(getter(datarow, this._colArg), this._convertArgs)
+ );
+ },
+
+ _convertData: function(/* anything */dataValue){
+ // summary:
+ //
+ // tags:
+ // protected extension
+ // dataValue: anything
+ // This argument should come from a store.
+ // returns:
+ return dataValue;
+ },
+
+ toObject: function(){
+ // summary:
+ // Overrided from _ConditionExpr.toObject
+ return { //String
+ op: this.getName(),
+ data: this._colArg === undefined ? this._value : this._colArg,
+ isCol: this._colArg !== undefined
+ };
+ }
+});
+
+var _OperatorExpr = declare("dojox.grid.enhanced.plugins.filter._OperatorExpr", _ConditionExpr, {
+ // summary:
+ // The most abstract class for all operator expressions.
+ // An operator expression is a _ConditionExpr that represents an operation.
+ _name: "operator",
+
+ constructor: function(/* Array | operand1,operand2,... */){
+ // summary:
+ // The arguments are operands (or an array of operands, if the first argument
+ // is an Array) of this operator, ordering from left to right.
+ // Every operand should be a _ConditionExpr.
+ if(lang.isArray(arguments[0])){
+ this._operands = arguments[0];
+ }else{
+ this._operands = [];
+ for(var i = 0; i < arguments.length; ++i){
+ this._operands.push(arguments[i]);
+ }
+ }
+ },
+ toObject: function(){
+ // summary:
+ // Overrided from _ConditionExpr.toObject
+ return { //Object
+ op: this.getName(),
+ data: array.map(this._operands,function(operand){
+ return operand.toObject();
+ })
+ };
+ }
+});
+
+var _UniOpExpr = declare("dojox.grid.enhanced.plugins.filter._UniOpExpr", _OperatorExpr, {
+ // summary:
+ // The most abstract class for all uni-operator expressions.
+ // A uni-operator expression is an _OperatorExpr that only allow one operand.
+ _name: "uniOperator",
+
+ applyRow: function(/* data item */datarow,/* function(row,colArg) */getter){
+ // summary:
+ // Implement _ConditionExpr.applyRow.
+ // Apply the restriction of "only one operand" and confirm the operand is a valid _ConditionExpr.
+ // Then do the calculation of this operator.
+ if(!(this._operands[0] instanceof _ConditionExpr)){
+ throw new Error("_UniOpExpr: operand is not expression.");
+ }
+ return this._calculate(this._operands[0],datarow,getter); //_ConditionExpr
+ },
+
+ _calculate: function(/* _ConditionExpr */operand,/* data item*/datarow,/* function(row,colArg) */getter){
+ // summary:
+ // *Unimplemented Interface*
+ // Do the actrual work of applyRow here.
+ // tags:
+ // protected extension
+ // operand: _ConditionExpr
+ // datarow: object
+ // getter: function(row,colArg)
+ // returns:
+ // MUST return a _ConditionExpr object.
+ throw new Error("_UniOpExpr._calculate: unimplemented interface");
+ }
+});
+
+var _BiOpExpr = declare("dojox.grid.enhanced.plugins.filter._BiOpExpr", _OperatorExpr, {
+ // summary:
+ // The most abstract class for all bi-operator expressions.
+ // A bi-operator expression is an _OperatorExpr that allow and only allow two operands.
+ _name: "biOperator",
+
+ applyRow: function(/* data item */datarow,/* function(row,colArg) */getter){
+ // summary:
+ // Implement _ConditionExpr.applyRow.
+ // Apply the restriction of "two operands" and confirm operands are valid _ConditionExpr's.
+ if(!(this._operands[0] instanceof _ConditionExpr)){
+ throw new Error("_BiOpExpr: left operand is not expression.");
+ }else if(!(this._operands[1] instanceof _ConditionExpr)){
+ throw new Error("_BiOpExpr: right operand is not expression.");
+ }
+ return this._calculate(this._operands[0],this._operands[1],datarow,getter);
+ },
+
+ _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,/* data item*/datarow,/* function(row,colArg) */getter){
+ // summary:
+ // *Unimplemented Interface*
+ // Do the actrual work of applyRow here.
+ // tags:
+ // protected extension
+ // left_operand: _ConditionExpr
+ // right_operand: _ConditionExpr
+ // datarow: object
+ // getter: function(row,colArg)
+ // returns:
+ // MUST return a _ConditionExpr object.
+ throw new Error("_BiOpExpr._calculate: unimplemented interface");
+ }
+});
+
+return {
+ _ConditionExpr: _ConditionExpr,
+ _DataExpr: _DataExpr,
+ _OperatorExpr: _OperatorExpr,
+ _UniOpExpr: _UniOpExpr,
+ _BiOpExpr: _BiOpExpr
+};
+
+});
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/_DataExprs.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/_DataExprs.js
new file mode 100644
index 0000000..b19c2c4
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/_DataExprs.js
@@ -0,0 +1,85 @@
+//>>built
+define("dojox/grid/enhanced/plugins/filter/_DataExprs", [
+ "dojo/_base/declare",
+ "dojo/_base/lang",
+ "dojo/date/locale",
+ "./_ConditionExpr"
+], function(declare, lang, dateLocale, exprs){
+
+ var BooleanExpr = declare("dojox.grid.enhanced.plugins.filter.BooleanExpr", exprs._DataExpr, {
+ // summary:
+ // A condition expression wrapper for boolean values
+ _name: "bool",
+ _convertData: function(/* anything */dataValue){
+ // summary:
+ // override from _DataExpr
+ return !!dataValue; //Boolean
+ }
+ });
+ var StringExpr = declare("dojox.grid.enhanced.plugins.filter.StringExpr", exprs._DataExpr, {
+ // summary:
+ // A condition expression wrapper for string values
+ _name: "string",
+ _convertData: function(/* anything */dataValue){
+ // summary:
+ // override from _DataExpr
+ return String(dataValue); //String
+ }
+ });
+ var NumberExpr = declare("dojox.grid.enhanced.plugins.filter.NumberExpr", exprs._DataExpr, {
+ // summary:
+ // A condition expression wrapper for number values
+ _name: "number",
+ _convertDataToExpr: function(/* anything */dataValue){
+ // summary:
+ // override from _DataExpr
+ return parseFloat(dataValue); //Number
+ }
+ });
+ var DateExpr = declare("dojox.grid.enhanced.plugins.filter.DateExpr", exprs._DataExpr, {
+ // summary:
+ // A condition expression wrapper for date values
+ _name: "date",
+ _convertData: function(/* anything */dataValue){
+ // summary:
+ // override from _DataExpr
+ if(dataValue instanceof Date){
+ return dataValue;
+ }else if(typeof dataValue == "number"){
+ return new Date(dataValue);
+ }else{
+ var res = dateLocale.parse(String(dataValue), lang.mixin({selector: this._name}, this._convertArgs));
+ if(!res){
+ throw new Error("Datetime parse failed: " + dataValue);
+ }
+ return res;
+ }
+ },
+ toObject: function(){
+ // summary:
+ // Overrided from _DataExpr.toObject
+ if(this._value instanceof Date){
+ var tmp = this._value;
+ this._value = this._value.valueOf();
+ var res = this.inherited(arguments);
+ this._value = tmp;
+ return res;
+ }else{
+ return this.inherited(arguments);
+ }
+ }
+ });
+ var TimeExpr = declare("dojox.grid.enhanced.plugins.filter.TimeExpr", DateExpr, {
+ // summary:
+ // A condition expression wrapper for time values
+ _name: "time"
+ });
+
+ return lang.mixin({
+ BooleanExpr: BooleanExpr,
+ StringExpr: StringExpr,
+ NumberExpr: NumberExpr,
+ DateExpr: DateExpr,
+ TimeExpr: TimeExpr
+ }, exprs);
+});
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/_FilterExpr.js b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/_FilterExpr.js
new file mode 100644
index 0000000..f1c2461
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/plugins/filter/_FilterExpr.js
@@ -0,0 +1,248 @@
+//>>built
+define("dojox/grid/enhanced/plugins/filter/_FilterExpr", [
+ "dojo/_base/declare",
+ "dojo/_base/lang",
+ "dojo/date",
+ "./_DataExprs"
+], function(declare, lang, date, exprs){
+//This is the main file that should be 'required' if filter expression facility is necessary.
+
+ /* Logic Operations */
+ var LogicAND = declare("dojox.grid.enhanced.plugins.filter.LogicAND", exprs._BiOpExpr, {
+ // summary:
+ // A logic AND condition expression.
+ _name: "and",
+ _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,
+ /* data item*/datarow,/* function(row,colIdx) */getter){
+ // summary:
+ // Override from _BiOpExpr
+ var res = left_operand.applyRow(datarow, getter).getValue() &&
+ right_operand.applyRow(datarow, getter).getValue();
+ return new exprs.BooleanExpr(res); //_ConditionExpr
+ }
+ });
+ var LogicOR = declare("dojox.grid.enhanced.plugins.filter.LogicOR", exprs._BiOpExpr, {
+ // summary:
+ // A logic OR condition expression.
+ _name: "or",
+ _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,
+ /* data item*/datarow,/* function(row,colIdx) */getter){
+ // summary:
+ // Override from _BiOpExpr
+ var res = left_operand.applyRow(datarow, getter).getValue() ||
+ right_operand.applyRow(datarow, getter).getValue();
+ return new exprs.BooleanExpr(res); //_ConditionExpr
+ }
+ });
+ var LogicXOR = declare("dojox.grid.enhanced.plugins.filter.LogicXOR", exprs._BiOpExpr, {
+ // summary:
+ // A logic XOR condition expression.
+ _name: "xor",
+ _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,
+ /* data item*/datarow,/* function(row,colIdx) */getter){
+ // summary:
+ // Override from _BiOpExpr
+ var left_res = left_operand.applyRow(datarow, getter).getValue();
+ var right_res = right_operand.applyRow(datarow, getter).getValue();
+ return new exprs.BooleanExpr((!!left_res) != (!!right_res)); //_ConditionExpr
+ }
+ });
+ var LogicNOT = declare("dojox.grid.enhanced.plugins.filter.LogicNOT", exprs._UniOpExpr, {
+ // summary:
+ // A logic NOT condition expression.
+ _name: "not",
+ _calculate: function(/* _ConditionExpr */operand,/* data item*/datarow,/* function(row,colIdx) */getter){
+ // summary:
+ // Override from _UniOpExpr
+ return new exprs.BooleanExpr(!operand.applyRow(datarow, getter).getValue()); //_ConditionExpr
+ }
+ });
+ var LogicALL = declare("dojox.grid.enhanced.plugins.filter.LogicALL", exprs._OperatorExpr, {
+ // summary:
+ // A logic ALL condition expression, equals a sequence of logic ANDs
+ _name: "all",
+ applyRow: function(/* data item */datarow,/* function(row,colIdx) */ getter){
+ // summary:
+ // Override from _ConditionExpr
+ for(var i = 0, res = true; res && (this._operands[i] instanceof exprs._ConditionExpr); ++i){
+ res = this._operands[i].applyRow(datarow,getter).getValue();
+ }
+ return new exprs.BooleanExpr(res); //_ConditionExpr
+ }
+ });
+ var LogicANY = declare("dojox.grid.enhanced.plugins.filter.LogicANY", exprs._OperatorExpr, {
+ // summary:
+ // A logic ANY condition expression, equals a sequence of logic ORs
+ _name: "any",
+ applyRow: function(/* data item */datarow,/* function(row,colIdx) */ getter){
+ for(var i = 0,res = false; !res && (this._operands[i] instanceof exprs._ConditionExpr); ++i){
+ res = this._operands[i].applyRow(datarow,getter).getValue();
+ }
+ return new exprs.BooleanExpr(res); //_ConditionExpr
+ }
+ });
+
+ /* Comparison Operations */
+ function compareFunc(left,right,row,getter){
+ left = left.applyRow(row, getter);
+ right = right.applyRow(row, getter);
+ var left_res = left.getValue();
+ var right_res = right.getValue();
+ if(left instanceof exprs.TimeExpr){
+ return date.compare(left_res,right_res,"time");
+ }else if(left instanceof exprs.DateExpr){
+ return date.compare(left_res,right_res,"date");
+ }else{
+ if(left instanceof exprs.StringExpr){
+ left_res = left_res.toLowerCase();
+ right_res = String(right_res).toLowerCase();
+ }
+ return left_res == right_res ? 0 : (left_res < right_res ? -1 : 1);
+ }
+ }
+ var EqualTo = declare("dojox.grid.enhanced.plugins.filter.EqualTo", exprs._BiOpExpr, {
+ // summary:
+ // An "equal to" condition expression.
+ _name: "equal",
+ _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,
+ /* data item*/datarow,/* function(row,colIdx) */getter){
+ // summary:
+ // Override from _BiOpExpr
+ var res = compareFunc(left_operand,right_operand,datarow,getter);
+ return new exprs.BooleanExpr(res === 0); //_ConditionExpr
+ }
+ });
+ var LessThan = declare("dojox.grid.enhanced.plugins.filter.LessThan", exprs._BiOpExpr, {
+ // summary:
+ // A "less than" condition expression.
+ _name: "less",
+ _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,
+ /* data item*/datarow,/* function(row,colIdx) */getter){
+ // summary:
+ // Override from _BiOpExpr
+ var res = compareFunc(left_operand,right_operand,datarow,getter);
+ return new exprs.BooleanExpr(res < 0); //_ConditionExpr
+ }
+ });
+ var LessThanOrEqualTo = declare("dojox.grid.enhanced.plugins.filter.LessThanOrEqualTo", exprs._BiOpExpr, {
+ // summary:
+ // A "less than or equal to" condition expression.
+ _name: "lessEqual",
+ _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,
+ /* data item*/datarow,/* function(row,colIdx) */getter){
+ // summary:
+ // Override from _BiOpExpr
+ var res = compareFunc(left_operand,right_operand,datarow,getter);
+ return new exprs.BooleanExpr(res <= 0); //_ConditionExpr
+ }
+ });
+ var LargerThan = declare("dojox.grid.enhanced.plugins.filter.LargerThan", exprs._BiOpExpr, {
+ // summary:
+ // A "larger than" condition expression.
+ _name: "larger",
+ _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,
+ /* data item*/datarow,/* function(row,colIdx) */getter){
+ // summary:
+ // Override from _BiOpExpr
+ var res = compareFunc(left_operand,right_operand,datarow,getter);
+ return new exprs.BooleanExpr(res > 0); //_ConditionExpr
+ }
+ });
+ var LargerThanOrEqualTo = declare("dojox.grid.enhanced.plugins.filter.LargerThanOrEqualTo", exprs._BiOpExpr, {
+ // summary:
+ // A "larger than or equal to" condition expression.
+ _name: "largerEqual",
+ _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,
+ /* data item*/datarow,/* function(row,colIdx) */getter){
+ // summary:
+ // Override from _BiOpExpr
+ var res = compareFunc(left_operand,right_operand,datarow,getter);
+ return new exprs.BooleanExpr(res >= 0); //_ConditionExpr
+ }
+ });
+
+ /* String Operations */
+ var Contains = declare("dojox.grid.enhanced.plugins.filter.Contains", exprs._BiOpExpr, {
+ // summary:
+ // A "contains" condition expression.
+ _name: "contains",
+ _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,
+ /* data item*/datarow,/* function(row,colIdx) */getter){
+ // summary:
+ // Override from _BiOpExpr
+ var left_res = String(left_operand.applyRow(datarow, getter).getValue()).toLowerCase();
+ var right_res = String(right_operand.applyRow(datarow, getter).getValue()).toLowerCase();
+ return new exprs.BooleanExpr(left_res.indexOf(right_res) >= 0); //_ConditionExpr
+ }
+ });
+ var StartsWith = declare("dojox.grid.enhanced.plugins.filter.StartsWith", exprs._BiOpExpr, {
+ // summary:
+ // A "starts with" condition expression.
+ _name: "startsWith",
+ _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,
+ /* data item*/datarow,/* function(row,colIdx) */getter){
+ // summary:
+ // Override from _BiOpExpr
+ var left_res = String(left_operand.applyRow(datarow, getter).getValue()).toLowerCase();
+ var right_res = String(right_operand.applyRow(datarow, getter).getValue()).toLowerCase();
+ return new exprs.BooleanExpr(left_res.substring(0, right_res.length) == right_res); //_ConditionExpr
+ }
+ });
+ var EndsWith = declare("dojox.grid.enhanced.plugins.filter.EndsWith", exprs._BiOpExpr, {
+ // summary:
+ // An "ends with" condition expression.
+ _name: "endsWith",
+ _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,
+ /* data item*/datarow,/* function(row,colIdx) */getter){
+ // summary:
+ // Override from _BiOpExpr
+ var left_res = String(left_operand.applyRow(datarow, getter).getValue()).toLowerCase();
+ var right_res = String(right_operand.applyRow(datarow, getter).getValue()).toLowerCase();
+ return new exprs.BooleanExpr(left_res.substring(left_res.length - right_res.length) == right_res); //_ConditionExpr
+ }
+ });
+ var Matches = declare("dojox.grid.enhanced.plugins.filter.Matches", exprs._BiOpExpr, {
+ // summary:
+ // A "regular expression match" condition expression.
+ // The second operand's value will be regarded as an regular expression string.
+ _name: "matches",
+ _calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,
+ /* data item*/datarow,/* function(row,colIdx) */getter){
+ // summary:
+ // Override from _BiOpExpr
+ var left_res = String(left_operand.applyRow(datarow, getter).getValue());
+ var right_res = new RegExp(right_operand.applyRow(datarow, getter).getValue());
+ return new exprs.BooleanExpr(left_res.search(right_res) >= 0); //_ConditionExpr
+ }
+ });
+ var IsEmpty = declare("dojox.grid.enhanced.plugins.filter.IsEmpty", exprs._UniOpExpr, {
+ // summary:
+ // Check empty
+ _name: "isEmpty",
+ _calculate: function(/* _ConditionExpr */operand,/* data item*/datarow,/* function(row,colIdx) */getter){
+ // summary:
+ // Override from _BiOpExpr
+ var res = operand.applyRow(datarow, getter).getValue();
+ return new exprs.BooleanExpr(res === "" || res == null);
+ }
+ });
+
+ return lang.mixin({
+ LogicAND: LogicAND,
+ LogicOR: LogicOR,
+ LogicXOR: LogicXOR,
+ LogicNOT: LogicNOT,
+ LogicALL: LogicALL,
+ LogicANY: LogicANY,
+ EqualTo: EqualTo,
+ LessThan: LessThan,
+ LessThanOrEqualTo: LessThanOrEqualTo,
+ LargerThan: LargerThan,
+ LargerThanOrEqualTo: LargerThanOrEqualTo,
+ Contains: Contains,
+ StartsWith: StartsWith,
+ EndsWith: EndsWith,
+ Matches: Matches,
+ IsEmpty: IsEmpty
+ }, exprs);
+});
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/resources/Common.css b/js/dojo-1.7.2/dojox/grid/enhanced/resources/Common.css
new file mode 100644
index 0000000..fc3d346
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/resources/Common.css
@@ -0,0 +1,27 @@
+/* Indirect Selection */
+.dojoxGridRowSelector {
+ cursor: pointer;
+}
+.dojoxGridRowSelectorStatusText{
+ visibility:hidden;
+}
+.dijit_a11y .dojoxGridRowSelected {
+ opacity:0.8 !important;
+}
+.dijit_a11y .dojoxGridBorderDIV {
+ border:2px solid #000 !important;
+}
+.dijit_a11y .dojoxGridRowSelector {
+ height:100% !important;
+}
+.dijit_a11y .dojoxGridRowSelectorStatusText{
+ font-size:larger !important;
+ visibility:visible;
+}
+.dijit_a11y .dijitCheckBox .dojoxGridRowSelectorStatusText{
+ font-weight:bolder !important;
+ font-size:x-large !important;
+}
+.dijit_a11y .dijitCheckBoxChecked .dojoxGridRowSelectorStatusText{
+ font-size:small !important;
+}
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/resources/Common_rtl.css b/js/dojo-1.7.2/dojox/grid/enhanced/resources/Common_rtl.css
new file mode 100644
index 0000000..796e935
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/resources/Common_rtl.css
@@ -0,0 +1,15 @@
+.dojoxGridRtl .dojoxGridLoading,
+.dojoxGridRtl .dojoxGridError,
+.dojoxGridRtl .dojoxGridNoData {
+ background-position:right;
+ padding-right:25px;
+ padding-left:0px;
+}
+.dojoxGridRtl .dojoxGridHeader {
+ margin-left: 0;
+ margin-right: -1px;
+}
+
+.dojoxGridRtl .dojoxGridCell {
+ text-align: right;
+}
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/resources/DnD.css b/js/dojo-1.7.2/dojox/grid/enhanced/resources/DnD.css
new file mode 100644
index 0000000..c364b0e
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/resources/DnD.css
@@ -0,0 +1,78 @@
+.dojoxGridBorderDIV {
+ width:2px;
+ background-color: gray;
+ font-size:0em;
+ position:absolute;
+ z-index:9999;
+}
+.dojoxGridCellBorderDIV {
+ position:absolute;
+ background-color: transparent;
+ border: none;
+}
+.dojoxGridCellBorderLeftTopDIV {
+ position: absolute;
+ left: 0;
+ top: 0;
+ border-style: solid;
+ border-width: 2px 0 0 2px;
+ border-color: gray transparent transparent gray;
+}
+.dojoxGridCellBorderRightBottomDIV {
+ position: absolute;
+ right: 0;
+ bottom: 0;
+ border-style: solid;
+ border-width: 0 2px 2px 0;
+ border-color: transparent gray gray transparent;
+}
+.dojoxGridDnDItemIcon {
+ background-image: url("images/sprite_icons.png");
+}
+.dojoxGridDnDIconRowSingle {
+ background-position: -256px 5px;
+}
+.dojoxGridDnDIconRowMulti {
+ background-position: -256px -16px;
+}
+.dojoxGridDnDIconColSingle {
+ background-position: -277px 3px;
+}
+.dojoxGridDnDIconColMulti {
+ background-position: -277px -17px;
+}
+.dojoxGridDnDIconCellSingle {
+ background-position: -235px 5px;
+}
+.dojoxGridDnDIconCellMulti {
+ background-position: -236px -16px;
+}
+.dojoxGridDndAvatar {
+ background-color:white;
+ border: 1px solid #CCCCCC;
+ padding: 0px;
+ -moz-box-shadow: 5px 5px 7px #999;
+ -webkit-box-shadow: 5px 5px 7px #999;
+ box-shadow: 5px 5px 7px #999;
+ z-index: 999;
+}
+.dojoxGridDndAvatar td {
+ padding: 3px;
+}
+.dojoxGridDnDIcon,
+.dojoxGridDnDItemIcon {
+ width: 16px;
+ height: 16px;
+}
+.dojoDndMove .dojoxGridDnDIcon {
+ background: url(../../../../dojo/resources/images/dndNoMove.png) no-repeat center center;
+}
+.dojoDndCopy .dojoxGridDnDIcon {
+ background: url(../../../../dojo/resources/images/dndNoCopy.png) no-repeat center center;
+}
+.dojoDndMove .dojoDndAvatarCanDrop .dojoxGridDnDIcon {
+ background: url(../../../../dojo/resources/images/dndMove.png) no-repeat center center;
+}
+.dojoDndCopy .dojoDndAvatarCanDrop .dojoxGridDnDIcon {
+ background: url(../../../../dojo/resources/images/dndCopy.png) no-repeat center center;
+}
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/resources/DnD_rtl.css b/js/dojo-1.7.2/dojox/grid/enhanced/resources/DnD_rtl.css
new file mode 100644
index 0000000..d7f270f
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/resources/DnD_rtl.css
@@ -0,0 +1,12 @@
+.dojoxGridRtl .dojoxGridCellBorderLeftTopDIV{
+ left: auto;
+ right: 0;
+ border-width: 2px 2px 0 0;
+ border-color: gray gray transparent transparent;
+}
+.dojoxGridRtl .dojoxGridCellBorderRightBottomDIV{
+ right: auto;
+ left: 0;
+ border-width: 0 0 2px 2px;
+ border-color: transparent transparent gray gray;
+}
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/resources/EnhancedGrid.css b/js/dojo-1.7.2/dojox/grid/enhanced/resources/EnhancedGrid.css
new file mode 100644
index 0000000..7f02773
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/resources/EnhancedGrid.css
@@ -0,0 +1,8 @@
+@import url("Common.css");
+@import url("Filter.css");
+@import url("Pagination.css");
+@import url("DnD.css");
+@import url("Sorter.css");
+@import url("../../../widget/Toaster/Toaster.css");
+@import url("../../../html/resources/ellipsis.css");
+
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/resources/EnhancedGrid_rtl.css b/js/dojo-1.7.2/dojox/grid/enhanced/resources/EnhancedGrid_rtl.css
new file mode 100644
index 0000000..0aae662
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/resources/EnhancedGrid_rtl.css
@@ -0,0 +1,6 @@
+@import url("../../resources/Grid_rtl.css");
+@import url("Common_rtl.css");
+@import url("Filter_rtl.css");
+@import url("Pagination_rtl.css");
+@import url("DnD_rtl.css");
+@import url("Sorter_rtl.css");
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/resources/Filter.css b/js/dojo-1.7.2/dojox/grid/enhanced/resources/Filter.css
new file mode 100644
index 0000000..46ca5fe
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/resources/Filter.css
@@ -0,0 +1,292 @@
+/* filter bar */
+.dojoxGridFBar {
+ width: 100%;
+ cursor: pointer;
+}
+.dojoxGridFBar .dojoxGridFBarBtn {
+ margin: 0;
+}
+.dojoxGridFBarBtnTD {
+ width: 38px;
+}
+.dojoxGridFBar .dojoxGridFBarBtn .dijitButtonNode {
+ -moz-border-radius: 1px;
+ -webkit-border-radius: 1px;
+ padding-top: 0;
+ padding-bottom: 0;
+ padding-right: 2px;
+}
+.dojoxGridFBarDefFilterBtnIcon {
+ background: url("images/sprite_icons.png") no-repeat;
+ background-position: -100px -18px;
+ width: 14px;
+ height: 14px;
+}
+.dj_ie .dojoxGridFBarInner{
+ display: inline-block;
+ width: 100%;
+}
+.dojoxGridFBarStatus {
+ margin-left: 9px;
+ float: left;
+}
+.dojoxGridFBarClearFilterBtn {
+ margin: 0 0 0 10px;
+ vertical-align: top;
+ float: left;
+}
+.dojoxGridFBarInfoTD .dojoxGridFBarClearFilterBtn .dijitButtonNode,
+.dojoxGridFBarInfoTD .dojoxGridFBarCloseBtn .dijitButtonNode,
+.dojoxGridFDPane .dijitAccordionTitle .dijitButtonNode,
+.dojoxGridFStatusTipDetail .dijitButton .dijitButtonNode {
+ -moz-border-radius: 0;
+ -moz-box-shadow: none;
+ -webkit-border-radius: 0;
+ -webkit-box-shadow: none;
+ background-image: none;
+ background-color: transparent;
+ margin: 0;
+ padding: 0;
+ border: none;
+}
+.dj_ie .dojoxGridFBarInner {
+ position: relative;
+}
+.dojoxGridFBarCloseBtn {
+ margin: 0 4px 0 0;
+ float: right;
+}
+.dj_ie .dojoxGridFBarCloseBtn {
+ float: none;
+ position: absolute;
+ right: 0;
+}
+.dojoxGridFBarCloseBtnIcon {
+ background: url("images/sprite_icons.png") no-repeat;
+ background-position: -119px -20px;
+ width: 14px;
+ height: 14px;
+}
+.dijitButtonHover .dojoxGridFBarCloseBtnIcon {
+ background-position: -140px -20px;
+}
+.dijitButtonActive .dojoxGridFBarCloseBtnIcon {
+ background-position: -160px -20px;
+}
+
+/* filter def dialog */
+.dojoxGridFDTitlePane {
+ width: 316px;
+ height: 330px;
+}
+.dijit_a11y .dojoxGridFDTitlePane .dijitArrowButtonInner{
+ /* This should be fixed in dijit */
+ display:none !important;
+}
+.dojoxGridFDTitlePane .dijitDialogPaneContent {
+ padding: 7px 5px 9px 5px;
+ height: 290px !important;
+}
+.dojoxGridFDTitlePane .dijitTitlePaneTitle {
+ cursor: move;
+}
+.dojoxGridFDPaneRelation {
+ margin: 0 0 3px 4px;
+}
+.dojoxGridFDPane {
+ width: 100%;
+ height: 100%;
+ position: relative;
+}
+.dojoxGridFDPaneRulePane {
+ height: 222px;
+ overflow: auto;
+ /* for ie6/7 only */
+ position: relative;
+}
+.dj_ie6 .dojoxGridFDPaneRulePane {
+ width: 100%;
+}
+.dojoxGridFDPane .dijitAccordionContainer .dijitContentPane {
+ padding: 6px 9px;
+}
+.dojoxGridFDPane .dijitAccordionTitle {
+ position: relative;
+ /* for non-claro theme, this can ensure a correct height change when adding/removing child */
+ min-height: 17px;
+}
+.dojoxGridFDPane .dijitAccordionTitle .dijitButton {
+ position: absolute;
+ margin: 0;
+ right: 3px;
+ top: 4px;
+}
+.dj_ie6 .dojoxGridFDPane .dijitAccordionTitle .dijitButton {
+ top: 2px;
+}
+.dojoxGridFDPane .dijitAccordionTitleFocus {
+ margin-right: 14px;
+}
+.dojoxGridFDPane .dijitAccordionText {
+ display: inline-block;
+ position: relative;
+}
+.dojoxGridFCBoxRemoveCBoxBtnIcon {
+ background-image: url("images/sprite_icons.png");
+ background-position: -198px -18px;
+ width: 16px;
+ height: 16px;
+}
+.dijitButtonHover .dojoxGridFCBoxRemoveCBoxBtnIcon {
+ background-position: -198px 2px;
+}
+.dojoxGridRuleTitleCondition {
+ font-style: italic;
+}
+.dojoxGridFDPaneModes .dijitSelect {
+ position: relative;
+}
+.dojoxGridFDPaneBtns {
+ position: absolute;
+ right: 0;
+ bottom: 0;
+}
+.dj_ie7 .dojoxGridFDPaneBtns,
+.dj_ie6 .dojoxGridFDPaneBtns {
+ z-index: -1;
+}
+.dojoxGridFDPaneBtns .dijitButton {
+ float: right;
+}
+.dojoxGridFDPaneAddCBoxBtn {
+ margin-top: 9px;
+}
+.dojoxGridFDPaneAddCBoxBtnIcon {
+ background-image: url("images/sprite_icons.png");
+ background-position: -218px 2px;
+ width: 16px;
+ height: 16px;
+}
+.dijitButtonDisabled .dojoxGridFDPaneAddCBoxBtnIcon {
+ background-position: -218px -18px;
+}
+
+/* criteria box */
+.dojoxGridFCBox {
+ height: 125px;
+}
+.dojoxGridFCBoxSelCol,
+.dojoxGridFCBoxCondition {
+ height: 40px;
+}
+.dojoxGridFCBox .dojoxGridFCBoxColSelect,
+.dojoxGridFCBox .dojoxGridFCBoxCondSelect,
+.dojoxGridFCBox .dojoxGridFCBoxValueBox {
+ margin: 0.1em 0 0 0;
+ width: 100%;
+ /* inherited is inline-block this will cause width "error" in non IE for html tables */
+ display: inline-table;
+}
+.dojoxGridFCBoxCondSelectAlt {
+ width: 100%;
+ padding: 5px 0 0 0;
+ font-weight: bold;
+}
+.dojoxGridFCBox .dijitSelect .dijitArrowButton {
+ width: 18px;
+}
+.dojoxGridFCBoxStartValue {
+ width: 45%;
+}
+.dojoxGridFCBoxEndValue {
+ float: right;
+ width: 45%;
+}
+.dojoxGridFCBoxRangeValueTxt {
+ margin-left: 4px;
+}
+
+/* status tip */
+.dojoxGridFStatusTipDialog .dijitTooltipContainer {
+ padding: 9px 5px;
+}
+.dojoxGridFStatusTip thead,
+.dojoxGridFStatusTip tr {
+ height: 19px;
+}
+.dojoxGridFStatusTip th {
+ max-width: 150px;
+ width: expression(this.clientWidth > 150 ? "150px" : "auto");
+}
+.dojoxGridFStatusTip th div {
+ padding: 2px 5px;
+}
+.dojoxGridFStatusTip td {
+ padding: 2px 6px;
+ max-width: 150px;
+ overflow: hidden;
+ width: expression(this.clientWidth > 150 ? "150px" : "auto");
+}
+.dojoxGridFStatusTipHead {
+ margin-bottom: 9px;
+}
+.dojoxGridFStatusTipTitle {
+ font-weight: bold;
+ margin-right: 1em;
+}
+.dojoxGridFStatusTipHandle {
+ position: relative;
+ padding-right: 16px;
+}
+.dojoxGridFStatusTipDetail .dijitButton {
+ position: absolute;
+ margin: 0;
+ padding: 0;
+ top: -1px;
+ right:0;
+}
+.dojoxGridFStatusTipDelRuleBtnIcon {
+ background-image: url("images/sprite_icons.png");
+ background-position: -198px -18px;
+ height: 16px;
+ width: 16px;
+}
+.dijitButtonHover .dojoxGridFStatusTipDelRuleBtnIcon {
+ background-position: -198px 2px;
+}
+
+/* clear dlg */
+.dj_ie7 .dojoxGridClearFilterConfirm,
+.dj_ie6 .dojoxGridClearFilterConfirm {
+ width: 300px;
+}
+.dojoxGridClearFilterBtns{
+ padding: 10px;
+ height: 18px;
+}
+.dojoxGridClearFilterBtns .dijitButton {
+ float: right;
+}
+
+/* bool value box */
+.dojoxGridTrueBox {
+ float: left;
+ width: 49%;
+}
+.dojoxGridFalseBox {
+ float: left;
+ width: 49%;
+}
+.dojoxGridBoolValueBox .dijitRadio {
+ vertical-align: middle;
+}
+.dojoxGridTrueLabel,
+.dojoxGridFalseLabel {
+ width: 116px;
+ display:inline-block;
+ vertical-align: middle;
+}
+.dj_ie7 .dojoxGridTrueLabel,
+.dj_ie7 .dojoxGridFalseLabel {
+ display: inline;
+}
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/resources/Filter_rtl.css b/js/dojo-1.7.2/dojox/grid/enhanced/resources/Filter_rtl.css
new file mode 100644
index 0000000..c9f2333
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/resources/Filter_rtl.css
@@ -0,0 +1,84 @@
+/* filter bar */
+.dojoxGridRtl .dojoxGridFBarDefFilterBtnIcon {
+ background: url("images/sprite_icons.png") no-repeat;
+ background-position: -180px -18px;
+}
+.dojoxGridRtl .dojoxGridFBarStatus {
+ margin-left: 0;
+ margin-right: 9px;
+ float: right;
+}
+.dojoxGridRtl .dojoxGridFBarClearFilterBtn {
+ margin-left: 0;
+ margin-right: 10px;
+ float: right;
+}
+.dojoxGridRtl .dojoxGridFBarCloseBtn {
+ margin: 0 0 0 4px;
+ float: left;
+}
+.dj_ie .dojoxGridRtl .dojoxGridFBarCloseBtn {
+ left: 2px;
+ right: auto;
+}
+/* filter def dialog */
+.dijitRtl .dojoxGridFDPaneRelation {
+ margin: 0 4px 3px 0;
+}
+.dijitRtl .dojoxGridFDPane .dijitAccordionTitleFocus {
+ margin-right: 0;
+ margin-left: 14px;
+}
+.dijitRtl .dojoxGridFDPane .dijitAccordionTitle .dijitButton {
+ left: 3px;
+ right: auto;
+}
+.dj_ie6 .dijitRtl .dojoxGridFDPane .dijitAccordionTitle .dijitButton{
+ left: -290px;
+}
+.dijitRtl .dojoxGridFDPaneBtns {
+ left: 0;
+ right: auto;
+}
+.dijitRtl .dojoxGridFDPaneBtns .dijitButton,
+.dijitRtl .dojoxGridClearFilterBtns .dijitButton,
+.dijitRtl .dojoxGridFCBoxEndValue {
+ float: left;
+}
+.dijitRtl .dojoxGridFCBoxRangeValueTxt {
+ margin-left: 0;
+ margin-right: 4px;
+}
+
+/* status tip */
+.dijitRtl .dojoxGridFStatusTipTitle {
+ margin-left: 1em;
+ margin-right: 0;
+}
+.dijitRtl .dojoxGridFStatusTipHandle {
+ padding-left: 16px;
+ padding-right: 0;
+}
+.dijitRtl .dojoxGridFStatusTipDetail .dijitButton {
+ left: 0;
+ right: auto;
+}
+
+/* bool value box */
+.dijitRtl .dojoxGridTrueBox,
+.dijitRtl .dojoxGridFalseBox {
+ float: right;
+}
+
+/* For Claro */
+.claro .dojoxGridRtl .dojoxGridFBar {
+ border-right: 1px solid white;
+}
+
+.claro .dijitRtl .dojoxGridFStatusTip th div {
+ border-left: 1px solid #BCBCBC;
+ border-right: 1px solid white;
+}
+.claro .dijitRtl .dojoxGridFStatusTip th.lastColumn div {
+ border-left: 1px solid #BCBCBC;
+}
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/resources/Pagination.css b/js/dojo-1.7.2/dojox/grid/enhanced/resources/Pagination.css
new file mode 100644
index 0000000..bc1ae55
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/resources/Pagination.css
@@ -0,0 +1,147 @@
+.dojoxGridPaginator {
+ border-top:1px #DBDBDB solid;
+ text-align:center;
+ width: 100%;
+ height: 24px;
+ table-layout : fixed;
+ background-color: #EAEAEA;
+}
+.dojoxGridDescriptionTd {
+ text-align: left;
+ width: 35%;
+}
+.dojoxGridDescription {
+ text-align: left;
+ margin-left: 9px;
+ overflow: hidden;
+}
+.dojoxGridPaginatorFastStep {
+ text-align: right;
+ width: 35%;
+ overflow: hidden;
+}
+.dojoxGridPaginatorStep {
+ float: right;
+}
+.dojoxGridPaginatorGotoTd {
+ width: 20px!important;
+}
+.dojoxGridPaginatorGotoDiv {
+ cursor: pointer;
+ width: 12px!important;
+ height: 16px!important;
+ margin: 0 6px 0 2px;
+ background: url("images/sprite_icons.png") no-repeat -77px 4px;
+}
+.dojoxGridPaginatorGotoDivDisabled {
+ cursor: not-allowed;
+ background: url("images/sprite_icons.png") no-repeat -77px -16px;
+}
+.dojoxGridWardButton {
+ margin-top: 2px;
+ width: 12px!important;
+ height: 12px!important;
+ float: left;
+ background: url("images/sprite_icons.png") no-repeat;
+}
+.dojoxGridWardButtonInner {
+ visibility: hidden;
+}
+.dijit_a11y .dojoxGridWardButtonInner {
+ visibility: visible;
+ margin-bottom: 8px;
+}
+.dojoxGridfirstPageBtn {
+ cursor: pointer;
+ margin-left: 1px;
+ background-position: -57px 3px;
+}
+.dojoxGridfirstPageBtnDisable {
+ margin-left: 1px;
+ cursor: not-allowed;
+ background-position: -57px -17px;
+}
+.dojoxGridprevPageBtn {
+ cursor: pointer;
+ margin: 2px 2px 0 9px;
+ background-position: 3px 3px;
+}
+.dojoxGridprevPageBtnDisable {
+ cursor: not-allowed;
+ margin: 2px 2px 0 9px;
+ background-position: 3px -17px;
+}
+.dojoxGridlastPageBtn {
+ cursor: pointer;
+ margin: 2px 9px 0 9px;
+ background-position: -37px 3px;
+}
+.dojoxGridlastPageBtnDisable {
+ cursor: not-allowed;
+ margin: 2px 9px 0 9px;
+ background-position: -37px -17px;
+}
+
+.dojoxGridnextPageBtn {
+ cursor: pointer;
+ margin-left: 3px;
+ background-position: -17px 3px;
+}
+.dojoxGridnextPageBtnDisable {
+ margin-left: 3px;
+ cursor: not-allowed;
+ background-position: -17px -17px;
+}
+.dojoxGridInactived {
+ font-weight: normal;
+ color: #5D88AF;
+ cursor: pointer;
+ margin: 1px 6px 0 5px;
+ float: left;
+ zoom: 1; /* for IE */
+}
+.dojoxGridActived {
+ font-weight: bold;
+ color: black;
+ margin: 1px 6px 0 5px;
+ float: left;
+ text-decoration: none!important;
+ zoom: 1; /* for IE */
+}
+.dojoxGridInactiveSwitch {
+ font-weight: normal;
+ color: #5D88AF;
+ float: left;
+ cursor: pointer;
+ margin: 1px 7px 0 7px;
+ zoom: 1; /* for IE */
+}
+.dojoxGridActivedSwitch {
+ font-weight: bold;
+ color: black;
+ float: left;
+ margin: 1px 7px 0 7px;
+ text-decoration: none!important;
+ zoom: 1; /* for IE */
+}
+.dojoxGridSeparator {
+ float: left;
+}
+.dojoxGridPageTextHover {
+ text-decoration: underline;
+}
+.dojoxGridDialogMargin {
+ width: 220px!important;
+ margin-bottom: 10px;
+}
+.dj_ie6 .dojoxGridDialogMargin {
+ position: relative;
+}
+.dojoxGridDialogButton {
+ width: 220px!important;
+ text-align: right;
+}
+.dojoxGridButtonFocus {
+ outline: none;
+ border: 0.5px dotted darkblue !important;
+}
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/resources/Pagination_rtl.css b/js/dojo-1.7.2/dojox/grid/enhanced/resources/Pagination_rtl.css
new file mode 100644
index 0000000..e3a2dd1
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/resources/Pagination_rtl.css
@@ -0,0 +1,68 @@
+.dojoxGridRtl .dojoxGridDescription {
+ text-align: right;
+ margin-right: 9px;
+}
+.dojoxGridRtl .dojoxGridPaginatorStep {
+ float: left;
+}
+.dojoxGridRtl .dojoxGridPaginatorGotoDiv {
+ margin: 0 2px 0 6px;
+}
+.dojoxGridRtl .dojoxGridWardButton {
+ float: right;
+}
+.dojoxGridRtl .dojoxGridInactived {
+ margin: 1px 5px 0 6px;
+ float: right;
+}
+.dojoxGridRtl .dojoxGridActived {
+ margin: 1px 5px 0 6px;
+ float: right;
+}
+.dijitRtl .dojoxGridDialogButton {
+ float: left;
+ margin-bottom: 10px;
+}
+.dijitRtl .dojoxGridInactiveSwitch {
+ float: right;
+}
+.dijitRtl .dojoxGridActivedSwitch {
+ float: right;
+}
+.dijitRtl .dojoxGridSeparator {
+ float: right;
+}
+.dijitRtl .dojoxGridfirstPageBtn {
+ cursor: pointer;
+ margin: 2px 1px 0 0;
+ background-position: -37px 3px;
+}
+.dijitRtl .dojoxGridfirstPageBtnDisable {
+ margin: 2px 1px 0 0;
+ background-position: -37px -17px;
+}
+.dijitRtl .dojoxGridprevPageBtn {
+ cursor: pointer;
+ margin: 2px 9px 0 5px;
+ background-position: -17px 3px;
+}
+.dijitRtl .dojoxGridprevPageBtnDisable {
+ margin: 2px 9px 0 5px;
+ background-position: -17px -17px;
+}
+.dijitRtl .dojoxGridlastPageBtn {
+ cursor: pointer;
+ background-position: -57px 3px;
+}
+.dijitRtl .dojoxGridlastPageBtnDisable {
+ background-position: -57px -17px;
+}
+.dijitRtl .dojoxGridnextPageBtn {
+ cursor: pointer;
+ margin: 2px 3px 0 0;
+ background-position: 3px 3px;
+}
+.dijitRtl .dojoxGridnextPageBtnDisable {
+ margin: 2px 3px 0 0;
+ background-position: 3px -17px;
+} \ No newline at end of file
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/resources/Sorter.css b/js/dojo-1.7.2/dojox/grid/enhanced/resources/Sorter.css
new file mode 100644
index 0000000..11e6fc5
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/resources/Sorter.css
@@ -0,0 +1,179 @@
+/*
+.dojoxGrid
+ Sorted, SingleSorted | NestSorted
+.dojoxGridCell
+ Over, SortFocus, ShowIndex
+.dojoxGridSortNode
+ Asc | Desc, Main|Sub
+.dojoxGridSortBtn
+ :hover, Single|Nested
+*/
+.dojoxGrid .dojoxGridSortNode {
+ position: relative;
+ border: 1px solid transparent;
+ cursor: pointer;
+}
+.dj_ie6 .dojoxGrid .dojoxGridSortNode,
+.dj_ie7 .dojoxGrid .dojoxGridSortNode {
+ overflow: hidden;
+ width:100%;
+}
+.dojoxGrid .dojoxGridSortNoWrap {
+ white-space:nowrap;
+ word-wrap: normal;
+}
+.dojoxGridSortBtn {
+ width: 10px;
+ height:100%;
+ visibility: hidden;
+ top: 0;
+ display:block;
+ position: absolute;
+ color: #000;
+ background: #DFEAF1 url(images/sprite_icons.png) no-repeat 100px 0;
+ text-decoration: none;
+ outline: none;
+ right: 0;
+ border: 1px solid transparent;
+ box-sizing: border-box; /* css3 rec */
+ -moz-box-sizing: border-box; /* ff */
+ -ms-box-sizing: border-box; /* ie8 */
+ -webkit-box-sizing: border-box; /* safari3 */
+ -khtml-box-sizing: border-box; /* konqueror */
+}
+.dj_ie6 .dojoxGridSortBtn,
+.dj_ie6 .dojoxGrid .dojoxGridSortNode {
+ border: none;
+}
+.dojoxGridSortBtnNested {
+ right: 10px;
+}
+.dojoxGridCellSortFocus .dojoxGridSortBtn {
+ border-left: 1px solid #999999;
+ background-color: #DFEAF1;
+}
+.dojoxGridCellOver .dojoxGridSortBtn {
+ border-left: 1px solid #999999;
+ background-color: #9dcfff;
+}
+.dojoxGridSortNode {
+ outline: none;
+}
+
+/*Control the title node width*/
+.dojoxGridSorted .dojoxGridCellOver .dojoxGridSortNode,
+.dojoxGridCellSortFocus .dojoxGridSortNode,
+.dojoxGridSingleSorted .dojoxGridHeader .dojoxGridCellOver .dojoxGridSortNodeMain,
+.dojoxGridSingleSorted .dojoxGridHeader .dojoxGridCellSortFocus .dojoxGridSortNodeMain {
+ margin-right: 5px;
+}
+.dojoxGridSorted .dojoxGridCellOver .dojoxGridSortNode,
+.dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortNode {
+ margin-right: 24px;
+}
+/*html > body used for !dj_ie6, TBD - a better way*/
+html > body .dojoxGridCellOver .dojoxGridSortNode .dojoxGridSortBtnSingle {
+ right: -5px;
+}
+html > body .dojoxGridCellSortFocus .dojoxGridSortNode .dojoxGridSortBtnSingle,
+html > body .dojoxGridSorted .dojoxGridCellOver .dojoxGridSortNodeMain .dojoxGridSortBtnSingle,
+html > body .dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortNodeMain .dojoxGridSortBtnSingle {
+ right: -10px;
+}
+html > body .dojoxGridSorted .dojoxGridCellOver .dojoxGridSortBtnSingle,
+html > body .dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortBtnSingle,
+html > body .dojoxGridNestSorted .dojoxGridCellOver .dojoxGridSortNodeMain .dojoxGridSortBtnSingle,
+html > body .dojoxGridNestSorted .dojoxGridCellSortFocus .dojoxGridSortNodeMain .dojoxGridSortBtnSingle {
+ right: -28px;
+}
+html > body .dojoxGridSorted .dojoxGridCellOver .dojoxGridSortBtnNested,
+html > body .dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortBtnNested {
+ right: -17px;
+}
+
+.dojoxGrid .dojoxGridHeader .dojoxGridRowTable .dojoxGridNoSort .dojoxGridSortNode {
+ margin: 0!important;
+}
+
+.dj_ie7 .dojoxGridSortBtn {
+ right: 0!important;
+}
+.dj_ie7 .dojoxGridSortBtnNested {
+ right: 10px!important;
+}
+
+/*Focus border*/
+/*Control visibility*/
+.dojoxGrid .dojoxGridCellOver .dojoxGridSortNode .dojoxGridSortBtnSingle, /* single sort btn is always visible when mouseover*/
+.dojoxGrid .dojoxGridCellSortFocus .dojoxGridSortNode .dojoxGridSortBtnSingle,
+.dojoxGridSorted .dojoxGridCellOver .dojoxGridSortNode .dojoxGridSortBtnNested, /* in a sorted grid, nest btn is always visible when mouseover (except 1)*/
+.dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortNode .dojoxGridSortBtnNested,
+.dojoxGrid .dojoxGridCellShowIndex .dojoxGridSortNode .dojoxGridSortBtnNested, /* in a single sort grid, when mouseover other columns, show 1 on the main sort column*/
+.dojoxGrid .dojoxGridSortNodeSorted .dojoxGridSortBtn { /* in a sorted column, single or nested sort btn are always visible (except 2)*/
+ visibility: visible;
+}
+.dojoxGridSingleSorted .dojoxGridCellOver .dojoxGridSortNodeMain .dojoxGridSortBtnNested, /*(1)in a single sorted grid, nest btn is hidden in sort column when mouseover*/
+.dojoxGridSingleSorted .dojoxGridCellSortFocus .dojoxGridSortNodeMain .dojoxGridSortBtnNested,
+.dojoxGridSingleSorted .dojoxGridSortNode .dojoxGridSortBtnNested { /*(2)all nested btn is hidden in single sort grid without mouse over*/
+ visibility: hidden;
+}
+
+/*
+-119 asc
+-99 desc
+-159 do asc
+-139 do desc
+-179 no sort
+*/
+/*Control background image*/
+.dojoxGridSortNodeAsc .dojoxGridSortBtnSingle {
+ background-position: -119px 5px;
+ visibility: visible;
+}
+.dojoxGridSortNodeDesc .dojoxGridSortBtnSingle {
+ background-position: -99px 5px;
+ visibility: visible;
+}
+/*hover single sort*/
+.dojoxGridCellOver .dojoxGridSortBtnSingle,
+.dojoxGridCellSortFocus .dojoxGridSortBtnSingle {
+ background-position: -159px 5px;
+}
+.dojoxGridCellOver .dojoxGridSortNodeAsc .dojoxGridSortBtnSingle,
+.dojoxGridCellSortFocus .dojoxGridSortNodeAsc .dojoxGridSortBtnSingle,
+.dojoxGrid .dojoxGridCellOver .dojoxGridSortNode .dojoxGridSortBtnAsc,
+.dojoxGrid .dojoxGridCellSortFocus .dojoxGridSortNode .dojoxGridSortBtnAsc {
+ background-position: -139px 5px;
+}
+.dojoxGridCellOver .dojoxGridSortNodeDesc .dojoxGridSortBtnSingle,
+.dojoxGridCellSortFocus .dojoxGridSortNodeDesc .dojoxGridSortBtnSingle,
+.dojoxGrid .dojoxGridCellOver .dojoxGridSortNode .dojoxGridSortBtnDesc,
+.dojoxGrid .dojoxGridCellSortFocus .dojoxGridSortNode .dojoxGridSortBtnDesc {
+ background-position: -179px 5px;
+}
+/*hover nested sort*/
+.dojoxGridCellOver .dojoxGridSortBtnNested,
+.dojoxGridCellSortFocus .dojoxGridSortBtnNested {
+ background-position: -149px 5px;
+ width: 19px;
+}
+.dojoxGridCellOver .dojoxGridSortNodeAsc .dojoxGridSortBtnNested,
+.dojoxGridCellSortFocus .dojoxGridSortNodeAsc .dojoxGridSortBtnNested {
+ background-position: -129px 5px;
+}
+.dojoxGridCellOver .dojoxGridSortNodeDesc .dojoxGridSortBtnNested,
+.dojoxGridCellSortFocus .dojoxGridSortNodeDesc .dojoxGridSortBtnNested {
+ background-position: -169px 5px;
+}
+.dojoxGridNestSorted .dojoxGridCellOver .dojoxGridSortBtnSingle,
+.dojoxGridNestSorted .dojoxGridCellSortFocus .dojoxGridSortBtnSingle {
+ background-position: -159px 5px;
+}
+.dojoxGridCellOver .dojoxGridSortBtn:hover {
+ background-color:#A3E4FF;
+}
+.dojoxGrid .dojoxGridSortNodeFocus,
+.dojoxGridCellSortFocus .dojoxGridRowSelector,
+.dojoxGridCellSortFocus .dojoxGridSortBtnFocus {
+ border: 1px dashed #666;
+} \ No newline at end of file
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/resources/Sorter_rtl.css b/js/dojo-1.7.2/dojox/grid/enhanced/resources/Sorter_rtl.css
new file mode 100644
index 0000000..3faaedb
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/resources/Sorter_rtl.css
@@ -0,0 +1,78 @@
+.dojoxGridRtl .dojoxGridSortBtnSingle {
+ right: auto;
+ left: 0px;
+}
+.dojoxGridRtl .dojoxGridSortBtnNested {
+ right: auto;
+ left: 10px;
+}
+
+.dojoxGridRtl .dojoxGridCellOver .dojoxGridSortBtn,
+.dj_ie6 dojoxGridRtl .dojoxGridCellOver .dojoxGridSortBtn,
+.dojoxGridRtl .dojoxGridCellSortFocus .dojoxGridSortBtn {
+ border-left: none;
+ border-right: 1px solid #999999;
+}
+
+/*Control the title node width*/
+.dijitRtl .dojoxGridCellOver .dojoxGridSortNode,
+.dijitRtl .dojoxGridCellSortFocus .dojoxGridSortNode,
+.dijitRtl .dojoxGridSingleSorted .dojoxGridHeader .dojoxGridCellOver .dojoxGridSortNodeMain,
+.dijitRtl .dojoxGridSingleSorted .dojoxGridHeader .dojoxGridCellSortFocus .dojoxGridSortNodeMain {
+ margin-right: auto;
+ margin-left: 10px;
+}
+.dijitRtl .dojoxGridSorted .dojoxGridCellOver .dojoxGridSortNode,
+.dijitRtl .dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortNode {
+ margin-right: auto;
+ margin-left: 24px;
+}
+/*html > body used for !dj_ie6, TBD - a better way*/
+html.dijitRtl > body .dojoxGridCellOver .dojoxGridSortNode .dojoxGridSortBtnSingle {
+ right: auto;
+ left: -10px;
+}
+html.dijitRtl > body .dojoxGridCellSortFocus .dojoxGridSortNode .dojoxGridSortBtnSingle,
+html.dijitRtl > body .dojoxGridSorted .dojoxGridCellOver .dojoxGridSortNodeMain .dojoxGridSortBtnSingle,
+html.dijitRtl > body .dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortNodeMain .dojoxGridSortBtnSingle {
+ right: auto;
+ left: -10px;
+}
+html.dijitRtl > body .dojoxGridSorted .dojoxGridCellOver .dojoxGridSortBtnSingle,
+html.dijitRtl > body .dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortBtnSingle,
+html.dijitRtl > body .dojoxGridNestSorted .dojoxGridCellOver .dojoxGridSortNodeMain .dojoxGridSortBtnSingle,
+html.dijitRtl > body .dojoxGridNestSorted .dojoxGridCellSortFocus .dojoxGridSortNodeMain .dojoxGridSortBtnSingle {
+ right: auto;
+ left: -28px;
+}
+html.dijitRtl > body .dojoxGridSorted .dojoxGridCellOver .dojoxGridSortBtnNested,
+html.dijitRtl > body .dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortBtnNested {
+ right: auto;
+ left: -17px;
+}
+.dojoxGridRtl .dojoxGridCellOver .dojoxGridSortBtnNested,
+.dojoxGridRtl .dojoxGridCellSortFocus .dojoxGridSortBtnNested {
+ background-position: -159px 5px;
+ padding-left:8px;
+}
+.dojoxGridRtl .dojoxGridCellOver .dojoxGridSortNodeAsc .dojoxGridSortBtnNested,
+.dojoxGridRtl .dojoxGridCellSortFocus .dojoxGridSortNodeAsc .dojoxGridSortBtnNested {
+ background-position: -139px 5px;
+}
+
+.dojoxGridRtl .dojoxGridCellOver .dojoxGridSortNodeDesc .dojoxGridSortBtnNested,
+.dojoxGridRtl .dojoxGridCellSortFocus .dojoxGridSortNodeDesc .dojoxGridSortBtnNested {
+ background-position: -179px 5px;
+}
+.dojoxGridRtl .dojoxGridCellOver .dojoxGridSortBtnNested,
+.dojoxGridRtl .dojoxGridCellSortFocus .dojoxGridSortBtnNested {
+ padding-left: 8px;
+ padding-right: 0;
+}
+
+.dj_ie6 .dojoxGridRtl .dojoxGridCellOver .dojoxGridSortBtnNested,
+.dj_ie6 .dojoxGridRtl .dojoxGridCellSortFocus .dojoxGridSortBtnNested,
+.dj_ie6 .dojoxGridRtl .dojoxGridCellOver .dojoxGridSortBtnNested,
+.dj_ie6 .dojoxGridRtl .dojoxGridCellSortFocus .dojoxGridSortBtnNested {
+ padding-left:0px;
+}
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/resources/claro/Common.css b/js/dojo-1.7.2/dojox/grid/enhanced/resources/claro/Common.css
new file mode 100644
index 0000000..cec6c02
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/resources/claro/Common.css
@@ -0,0 +1,26 @@
+.claro .dojoxGridHeader .dojoxGridHeaderActive {
+ background-color:#91c9fe;
+}
+.claro td.dojoxGridRowSelected {
+ border-collapse:separate;
+ background:url("../../../resources/images/row_back.png") #CEE6FA repeat-x;
+}
+.claro .dojoxGridRowOver td.dojoxGridRowSelected {
+ border-top:1px solid #769DC0;
+ border-bottom:1px solid #769DC0;
+}
+.claro .dojoxGridRowActive td.dojoxGridRowSelected {
+ background-image:url("../../../resources/images/td_button_down.png");
+}
+.dj_ie6 .claro .dojoxGridRowOver .dojoxGridCell {
+ border-color: #ABD6FF;
+}
+.dj_ie6 .claro .dojoxGridRowActive .dojoxGridCell {
+ border-color: #7DBEFA;
+}
+
+/* Pagination */
+.claro .dojoxGridPaginator{
+ background: url("../../../resources/images/header_shadow.png") repeat-x scroll center bottom #E5EDF4;
+ /*background-color: #EAF1F6;*/
+}
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/resources/claro/EnhancedGrid.css b/js/dojo-1.7.2/dojox/grid/enhanced/resources/claro/EnhancedGrid.css
new file mode 100644
index 0000000..5c3b1a6
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/resources/claro/EnhancedGrid.css
@@ -0,0 +1,4 @@
+@import url("../../../resources/claroGrid.css");
+@import url("../EnhancedGrid.css");
+@import url("Common.css");
+@import url("Filter.css");
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/resources/claro/Filter.css b/js/dojo-1.7.2/dojox/grid/enhanced/resources/claro/Filter.css
new file mode 100644
index 0000000..f2069f6
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/resources/claro/Filter.css
@@ -0,0 +1,58 @@
+.claro .dojoxGridFBarInfoTD {
+ background: url("../../../resources/images/header_shadow.png") #F2F9FF repeat-x bottom;
+ background: -moz-linear-gradient(top, #F2F9FF, #EAF5FF);
+ background: -webkit-gradient(linear, left top, left bottom, from(#F2F9FF), to(#EAF5FF));
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#FFF2F9FF, endColorstr=#FFEAF5FF);
+}
+.claro .dojoxGridFBarHover .dojoxGridFBarInfoTD {
+ background: url("../../../resources/images/header_shadow.png") #F2F9FF repeat-x bottom;
+ background: -moz-linear-gradient(top, #ECF6FF 2px, #F2F9FF, #EAF5FF 6px);
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0.1, #ECF6FF), color-stop(0.6, #F2F9FF), color-stop(0.8, #EAF5FF));
+}
+.dj_gecko .claro .dojoxGridFBarInfoTD,
+.dj_webkit .claro .dojoxGridFBarInfoTD {
+ border-top: 1px solid #BFD6EB;
+ border-bottom: 1px solid #BFD6EB;
+}
+.dj_ie .claro .dojoxGridFBarInner{
+ border-top: 1px solid #BFD6EB;
+ border-bottom: 1px solid #BFD6EB;
+ display:inline-block;
+ width: 100%;
+}
+.claro .dojoxGridFBarClearFilterBtn {
+ color: #5B83B6;
+}
+.claro .dojoxGridFBarInfoTD .dojoxGridFBarClearFilterBtn.dijitButtonHover .dijitButtonText {
+ text-decoration: underline;
+}
+.claro .dojoxGridFBar {
+ border-left: 1px solid white;
+}
+.claro .dojoxGridFStatusTip table {
+ border: 1px solid #BCBCBC;
+}
+.claro .dojoxGridFStatusTip th {
+ background-color: #E8EFF4;
+ border-bottom: 1px solid #BCBCBC;
+}
+.claro .dojoxGridFStatusTip th div {
+ background-color: #E8EFF4;
+ border-left: 1px solid white;
+ border-right: 1px solid #BCBCBC;
+ border-top: 1px solid white;
+ border-bottom: 1px solid white;
+}
+.claro .dojoxGridFStatusTip th.lastColumn div {
+ border-right: 1px solid white;
+}
+.claro .dojoxGridFStatusTip td {
+ border-top: 1px solid white;
+ border-bottom: 1px solid white;
+}
+.claro .dojoxGridFStatusTipCondition {
+ font-style: italic;
+}
+.claro .dojoxGridFStatusTipOddRow {
+ background-color: #F1F8FF;
+}
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/resources/claroEnhancedGrid.css b/js/dojo-1.7.2/dojox/grid/enhanced/resources/claroEnhancedGrid.css
new file mode 100644
index 0000000..2cbc1de
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/resources/claroEnhancedGrid.css
@@ -0,0 +1,2 @@
+/*backward compatible*/
+@import "claro/EnhancedGrid.css"; \ No newline at end of file
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/resources/images/sprite_icons.png b/js/dojo-1.7.2/dojox/grid/enhanced/resources/images/sprite_icons.png
new file mode 100644
index 0000000..28be879
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/resources/images/sprite_icons.png
Binary files differ
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/resources/tundra/Common.css b/js/dojo-1.7.2/dojox/grid/enhanced/resources/tundra/Common.css
new file mode 100644
index 0000000..81287aa
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/resources/tundra/Common.css
@@ -0,0 +1,40 @@
+/* overwrite */
+.tundra .dojoxGridHeader .dojoxGridCell{
+ background: #fafafa url(../../../../../dijit/themes/tundra/images/titleBar.png) repeat-x bottom left;
+ border-top: 1px solid #bfbfbf;
+ /*border-left-width: 0px;*/
+}
+.tundra .dojoxGridCell {
+ padding:0px;
+ /*display:inline;*/
+ /*position:relative;*/
+ /*border-left-width: 0px;*/
+}
+.dj_ie6 .tundra .dojoxGridMasterView .dojoxGridCellOver{
+ border: 1px dashed #e9e9e9;
+}
+.dj_ie6 .tundra .dojoxGridHeader .dojoxGridCellOver{
+ border-bottom: none !important;
+ border-right: 1px solid #D5CDB5 !important;
+ border-top: 1px solid #D5CDB5 !important;
+}
+.tundra .dojoxGridRowbarInner {
+ width:20px;
+}
+.tundra .dojoxGridCellOver .dojoxGridSortNode,
+.tundra .dojoxGridCellSortFocus .dojoxGridSortNode {
+ cursor:pointer;
+ background: #f8fafd url("../../../../../dijit/themes/tundra/images/accordionItemHover.gif") bottom repeat-x;
+}
+/* end overwrite */
+
+/* fix safari focus border - overwrite */
+.dj_webkit .tundra .dojoxGridCell,
+.dj_webkit .tundra .dojoxGridCellFocus {
+ outline: none;
+}
+
+/*Pagination*/
+.tundra .dojoxGridPaginator {
+ background: url("../../../../../dijit/themes/tundra/images/titleBar.png") repeat-x top left;
+}
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/resources/tundra/EnhancedGrid.css b/js/dojo-1.7.2/dojox/grid/enhanced/resources/tundra/EnhancedGrid.css
new file mode 100644
index 0000000..f8159c8
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/resources/tundra/EnhancedGrid.css
@@ -0,0 +1,5 @@
+@import url("../../../resources/tundraGrid.css");
+@import url("../EnhancedGrid.css");
+@import url("Common.css");
+@import url("Filter.css");
+@import url("Sorter.css");
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/resources/tundra/Filter.css b/js/dojo-1.7.2/dojox/grid/enhanced/resources/tundra/Filter.css
new file mode 100644
index 0000000..b7b7b83
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/resources/tundra/Filter.css
@@ -0,0 +1,38 @@
+.tundra .dojoxGridFBar {
+ background-color: #eeeeee;
+ border: 1px solid #bfbfbf;
+}
+.tundra .dojoxGridFBarFiltered {
+ background: #fafafa url(../../../../../dijit/themes/tundra/images/titleBar.png) repeat-x bottom left;
+}
+.tundra .dojoxGridFBarHover {
+ background-color: #cccccc;
+ background-image: none;
+}
+.tundra .dojoxGridFStatusTip table {
+ border: 1px solid #eeeeee;
+}
+.tundra .dojoxGridFStatusTip th {
+ background: #fafafa url(../../../../../dijit/themes/tundra/images/titleBar.png) repeat-x bottom left;
+ border-bottom: 1px solid #eeeeee;
+}
+.tundra .dojoxGridFStatusTip th div {
+ border-left: 1px solid white;
+ border-right: 1px solid #eeeeee;
+ border-top: 1px solid white;
+ border-bottom: 1px solid white;
+}
+.tundra .dojoxGridFStatusTip th.lastColumn div {
+ border-right: 1px solid white;
+}
+.tundra .dojoxGridFStatusTip td {
+ border-top: 1px solid white;
+ border-bottom: 1px solid white;
+}
+.tundra .dojoxGridFStatusTipRel,
+.tundra .dojoxGridFStatusTipCondition {
+ font-style: italic;
+}
+.tundra .dojoxGridFStatusTipOddRow {
+ background-color: #f2f5f9;
+}
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/resources/tundra/Sorter.css b/js/dojo-1.7.2/dojox/grid/enhanced/resources/tundra/Sorter.css
new file mode 100644
index 0000000..480dd7e
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/resources/tundra/Sorter.css
@@ -0,0 +1,83 @@
+.tundra .dojoxGridSortBtn {
+ padding-top: 3px;
+}
+.tundra .dojoxGridSortBtnNested {
+ right: 11px;
+}
+.tundra .dojoxGridCellOver .dojoxGridSortBtn,
+.tundra .dojoxGridCellSortFocus .dojoxGridSortBtn {
+ background-color: #ccc;
+}
+
+/*Control the title node width*/
+.tundra .dojoxGridCellOver .dojoxGridSortNode,
+.tundra .dojoxGridCellSortFocus .dojoxGridSortNode,
+.tundra .dojoxGridSingleSorted .dojoxGridHeader .dojoxGridCellOver .dojoxGridSortNodeMain,
+.tundra .dojoxGridSingleSorted .dojoxGridHeader .dojoxGridCellSortFocus .dojoxGridSortNodeMain {
+ margin-right: 12px;
+}
+.tundra .dojoxGridSorted .dojoxGridCellOver .dojoxGridSortNode,
+.tundra .dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortNode {
+ margin-right: 31px;
+}
+
+/*ie 6 doesn't need below*/
+.tundra .dojoxGridCellOver .dojoxGridSortNode .dojoxGridSortBtnSingle,
+.tundra .dojoxGridCellSortFocus .dojoxGridSortNode .dojoxGridSortBtnSingle,
+.tundra .dojoxGridSorted .dojoxGridCellOver .dojoxGridSortNodeMain .dojoxGridSortBtnSingle,
+.tundra .dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortNodeMain .dojoxGridSortBtnSingle {
+ right: -12px;
+}
+.tundra .dojoxGridSorted .dojoxGridCellOver .dojoxGridSortBtnSingle,
+.tundra .dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortBtnSingle,
+.tundra .dojoxGridNestSorted .dojoxGridCellOver .dojoxGridSortNodeMain .dojoxGridSortBtnSingle,
+.tundra .dojoxGridNestSorted .dojoxGridCellSortFocus .dojoxGridSortNodeMain .dojoxGridSortBtnSingle {
+ right: -31px;
+}
+.tundra .dojoxGridSorted .dojoxGridCellOver .dojoxGridSortBtnNested,
+.tundra .dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortBtnNested {
+ right: -20px;
+}
+/*ie6 hack end*/
+
+/*Control background image*/
+.tundra .dojoxGridSortNodeAsc .dojoxGridSortBtnSingle {
+ background-position: -119px 8px;
+}
+.tundra .dojoxGridSortNodeDesc .dojoxGridSortBtnSingle {
+ background-position: -99px 8px;
+}
+/*hover single sort*/
+.tundra .dojoxGridCellOver .dojoxGridSortBtnSingle,
+.tundra .dojoxGridCellSortFocus .dojoxGridSortBtnSingle {
+ background-position: -159px 8px;
+}
+.tundra .dojoxGridCellOver .dojoxGridSortNodeAsc .dojoxGridSortBtnSingle,
+.tundra .dojoxGridCellSortFocus .dojoxGridSortNodeAsc .dojoxGridSortBtnSingle,
+.tundra .dojoxGrid .dojoxGridCellOver .dojoxGridSortNode .dojoxGridSortBtnAsc,
+.tundra .dojoxGrid .dojoxGridCellSortFocus .dojoxGridSortNode .dojoxGridSortBtnAsc {
+ background-position: -139px 8px;
+}
+.tundra .dojoxGridCellOver .dojoxGridSortNodeDesc .dojoxGridSortBtnSingle,
+.tundra .dojoxGridCellSortFocus .dojoxGridSortNodeDesc .dojoxGridSortBtnSingle,
+.tundra .dojoxGrid .dojoxGridCellOver .dojoxGridSortNode .dojoxGridSortBtnDesc,
+.tundra .dojoxGrid .dojoxGridCellSortFocus .dojoxGridSortNode .dojoxGridSortBtnDesc {
+ background-position: -179px 8px;
+}
+/*hover nested sort*/
+.tundra .dojoxGridCellOver .dojoxGridSortBtnNested,
+.tundra .dojoxGridCellSortFocus .dojoxGridSortBtnNested {
+ background-position: -150px 8px;
+}
+.tundra .dojoxGridCellOver .dojoxGridSortNodeAsc .dojoxGridSortBtnNested,
+.tundra .dojoxGridCellSortFocus .dojoxGridSortNodeAsc .dojoxGridSortBtnNested {
+ background-position: -130px 8px;
+}
+.tundra .dojoxGridCellOver .dojoxGridSortNodeDesc .dojoxGridSortBtnNested,
+.tundra .dojoxGridCellSortFocus .dojoxGridSortNodeDesc .dojoxGridSortBtnNested {
+ background-position: -170px 8px;
+}
+.tundra .dojoxGridNestSorted .dojoxGridCellOver .dojoxGridSortBtnSingle,
+.tundra .dojoxGridNestSorted .dojoxGridCellSortFocus .dojoxGridSortBtnSingle {
+ background-position: -159px 8px;
+} \ No newline at end of file
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/resources/tundraEnhancedGrid.css b/js/dojo-1.7.2/dojox/grid/enhanced/resources/tundraEnhancedGrid.css
new file mode 100644
index 0000000..a770d0c
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/resources/tundraEnhancedGrid.css
@@ -0,0 +1,2 @@
+/*backward compatible*/
+@import "tundra/EnhancedGrid.css"; \ No newline at end of file
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/templates/ClearFilterConfirmPane.html b/js/dojo-1.7.2/dojox/grid/enhanced/templates/ClearFilterConfirmPane.html
new file mode 100644
index 0000000..1637b2e
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/templates/ClearFilterConfirmPane.html
@@ -0,0 +1,9 @@
+<div class="dojoxGridClearFilterConfirm">
+ <div class="dojoxGridClearFilterMsg">
+ ${_clearFilterMsg}
+ </div>
+ <div class="dojoxGridClearFilterBtns" dojoAttachPoint="btnsNode">
+ <span dojoType="dijit.form.Button" label="${_cancelBtnLabel}" dojoAttachPoint="cancelBtn" dojoAttachEvent="onClick:_onCancel"></span>
+ <span dojoType="dijit.form.Button" label="${_clearBtnLabel}" dojoAttachPoint="clearBtn" dojoAttachEvent="onClick:_onClear"></span>
+ </div>
+</div>
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/templates/CriteriaBox.html b/js/dojo-1.7.2/dojox/grid/enhanced/templates/CriteriaBox.html
new file mode 100644
index 0000000..ad9a1ec
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/templates/CriteriaBox.html
@@ -0,0 +1,20 @@
+<div class="dojoxGridFCBox">
+ <div class="dojoxGridFCBoxSelCol" dojoAttachPoint="selColNode">
+ <span class="dojoxGridFCBoxField">${_colSelectLabel}</span>
+ <select dojoAttachPoint="_colSelect" dojoType="dijit.form.Select"
+ class="dojoxGridFCBoxColSelect"
+ dojoAttachEvent="onChange:_onChangeColumn">
+ </select>
+ </div>
+ <div class="dojoxGridFCBoxCondition" dojoAttachPoint="condNode">
+ <span class="dojoxGridFCBoxField">${_condSelectLabel}</span>
+ <select dojoAttachPoint="_condSelect" dojoType="dijit.form.Select"
+ class="dojoxGridFCBoxCondSelect"
+ dojoAttachEvent="onChange:_onChangeCondition">
+ </select>
+ <div class="dojoxGridFCBoxCondSelectAlt" dojoAttachPoint="_condSelectAlt" style="display:none;"></div>
+ </div>
+ <div class="dojoxGridFCBoxValue" dojoAttachPoint="valueNode">
+ <span class="dojoxGridFCBoxField">${_valueBoxLabel}</span>
+ </div>
+</div>
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/templates/FilterBar.html b/js/dojo-1.7.2/dojox/grid/enhanced/templates/FilterBar.html
new file mode 100644
index 0000000..cbcb68d
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/templates/FilterBar.html
@@ -0,0 +1,15 @@
+<table class="dojoxGridFBar" border="0" cellspacing="0" dojoAttachEvent="onclick:_onClickFilterBar, onmouseenter:_onMouseEnter, onmouseleave:_onMouseLeave, onmousemove:_onMouseMove"
+ ><tr><td class="dojoxGridFBarBtnTD"
+ ><span dojoType="dijit.form.Button" class="dojoxGridFBarBtn" dojoAttachPoint="defineFilterButton" label="..." iconClass="dojoxGridFBarDefFilterBtnIcon" showLabel="true" dojoAttachEvent="onClick:_showFilterDefDialog, onMouseEnter:_onEnterButton, onMouseLeave:_onLeaveButton, onMouseMove:_onMoveButton"></span
+ ></td><td class="dojoxGridFBarInfoTD"
+ ><span class="dojoxGridFBarInner"
+ ><span class="dojoxGridFBarStatus" dojoAttachPoint="statusBarNode">${_noFilterMsg}</span
+ ><span dojoType="dijit.form.Button" class="dojoxGridFBarClearFilterBtn" dojoAttachPoint="clearFilterButton"
+ label="${_filterBarClearBtnLabel}" iconClass="dojoxGridFBarClearFilterBtnIcon" showLabel="true"
+ dojoAttachEvent="onClick:_clearFilterDefDialog, onMouseEnter:_onEnterButton, onMouseLeave:_onLeaveButton, onMouseMove:_onMoveButton"></span
+ ><span dojotype="dijit.form.Button" class="dojoxGridFBarCloseBtn" dojoAttachPoint="closeFilterBarButton"
+ label="${_closeFilterBarBtnLabel}" iconClass="dojoxGridFBarCloseBtnIcon" showLabel="false"
+ dojoAttachEvent="onClick:_closeFilterBar, onMouseEnter:_onEnterButton, onMouseLeave:_onLeaveButton, onMouseMove:_onMoveButton"></span
+ ></span
+ ></td></tr
+></table>
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/templates/FilterBoolValueBox.html b/js/dojo-1.7.2/dojox/grid/enhanced/templates/FilterBoolValueBox.html
new file mode 100644
index 0000000..6779e70
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/templates/FilterBoolValueBox.html
@@ -0,0 +1,11 @@
+<div class="dojoxGridBoolValueBox">
+ <div class="dojoxGridTrueBox">
+ <input dojoType="dijit.form.RadioButton" type='radio' name='a1' id='${_baseId}_rbTrue' checked="true"
+ dojoAttachPoint="rbTrue" dojoAttachEvent="onChange: onChange"/>
+ <div class="dojoxGridTrueLabel" for='${_baseId}_rbTrue'>${_lblTrue}</div>
+ </div>
+ <div class="dojoxGridFalseBox">
+ <input dojoType="dijit.form.RadioButton" dojoAttachPoint="rbFalse" type='radio' name='a1' id='${_baseId}_rbFalse'/>
+ <div class="dojoxGridTrueLabel" for='${_baseId}_rbFalse'>${_lblFalse}</div>
+ </div>
+</div>
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/templates/FilterDefPane.html b/js/dojo-1.7.2/dojox/grid/enhanced/templates/FilterDefPane.html
new file mode 100644
index 0000000..5783f36
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/templates/FilterDefPane.html
@@ -0,0 +1,27 @@
+<div class="dojoxGridFDPane">
+ <div class="dojoxGridFDPaneRelation">${_relMsgFront}
+ <span class="dojoxGridFDPaneModes" dojoAttachPoint="criteriaModeNode">
+ <select dojoAttachPoint="_relSelect" dojoType="dijit.form.Select" dojoAttachEvent="onChange: _onRelSelectChange">
+ <option value="0">${_relAll}</option>
+ <option value="1">${_relAny}</option>
+ </select>
+ </span>
+ ${_relMsgTail}
+ </div>
+ <div dojoAttachPoint="criteriaPane" class="dojoxGridFDPaneRulePane"></div>
+ <div dojoAttachPoint="_addCBoxBtn" dojoType="dijit.form.Button"
+ class="dojoxGridFDPaneAddCBoxBtn" iconClass="dojoxGridFDPaneAddCBoxBtnIcon"
+ dojoAttachEvent="onClick:_onAddCBox" label="${_addRuleBtnLabel}" showLabel="false">
+ </div>
+ <div class="dojoxGridFDPaneBtns" dojoAttachPoint="buttonsPane">
+ <span dojoAttachPoint="_cancelBtn" dojoType="dijit.form.Button"
+ dojoAttachEvent="onClick:_onCancel" label="${_cancelBtnLabel}">
+ </span>
+ <span dojoAttachPoint="_clearFilterBtn" dojoType="dijit.form.Button"
+ dojoAttachEvent="onClick:_onClearFilter" label="${_clearBtnLabel}" disabled="true">
+ </span>
+ <span dojoAttachPoint="_filterBtn" dojoType="dijit.form.Button"
+ dojoAttachEvent="onClick:_onFilter" label="${_filterBtnLabel}" disabled="true">
+ </span>
+ </div>
+</div>
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/templates/FilterStatusPane.html b/js/dojo-1.7.2/dojox/grid/enhanced/templates/FilterStatusPane.html
new file mode 100644
index 0000000..67be8d4
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/templates/FilterStatusPane.html
@@ -0,0 +1,8 @@
+<div class="dojoxGridFStatusTip"
+ ><div class="dojoxGridFStatusTipHead"
+ ><span class="dojoxGridFStatusTipTitle" dojoAttachPoint="statusTitle"></span
+ ><span class="dojoxGridFStatusTipRel" dojoAttachPoint="statusRel"></span
+ ></div
+ ><div class="dojoxGridFStatusTipDetail" dojoAttachPoint="statusDetailNode"
+ ></div
+></div>
diff --git a/js/dojo-1.7.2/dojox/grid/enhanced/templates/Pagination.html b/js/dojo-1.7.2/dojox/grid/enhanced/templates/Pagination.html
new file mode 100644
index 0000000..ad55539
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/enhanced/templates/Pagination.html
@@ -0,0 +1,18 @@
+<div dojoAttachPoint="paginatorBar"
+ ><table cellpadding="0" cellspacing="0" class="dojoxGridPaginator"
+ ><tr
+ ><td dojoAttachPoint="descriptionTd" class="dojoxGridDescriptionTd"
+ ><div dojoAttachPoint="descriptionDiv" class="dojoxGridDescription"></div
+ ></div></td
+ ><td dojoAttachPoint="sizeSwitchTd"></td
+ ><td dojoAttachPoint="pageStepperTd" class="dojoxGridPaginatorFastStep"
+ ><div dojoAttachPoint="pageStepperDiv" class="dojoxGridPaginatorStep"></div
+ ></td
+ ><td dojoAttachPoint="gotoPageTd" class="dojoxGridPaginatorGotoTd"
+ ><div dojoAttachPoint="gotoPageDiv" class="dojoxGridPaginatorGotoDiv" dojoAttachEvent="onclick:_openGotopageDialog, onkeydown:_openGotopageDialog"
+ ><span class="dojoxGridWardButtonInner">&#8869;</span
+ ></div
+ ></td
+ ></tr
+ ></table
+></div>
diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_ar.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_ar.js
new file mode 100644
index 0000000..390c46a
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_ar.js
@@ -0,0 +1,13 @@
+require({cache:{
+'dijit/nls/ar/loading':function(){
+define(
+"dijit/nls/ar/loading", //begin v1.x content
+({
+ loadingState: "جاري التحميل...",
+ errorState: "عفوا، حدث خطأ"
+})
+//end v1.x content
+);
+
+}}});
+define("dojox/grid/nls/DataGrid_ar", [], 1);
diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_ca.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_ca.js
new file mode 100644
index 0000000..1feb0e3
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_ca.js
@@ -0,0 +1,14 @@
+require({cache:{
+'dijit/nls/ca/loading':function(){
+define(
+"dijit/nls/ca/loading", //begin v1.x content
+({
+ loadingState: "S'està carregant...",
+ errorState: "Ens sap greu. S'ha produït un error."
+})
+
+//end v1.x content
+);
+
+}}});
+define("dojox/grid/nls/DataGrid_ca", [], 1);
diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_cs.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_cs.js
new file mode 100644
index 0000000..b94f219
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_cs.js
@@ -0,0 +1,13 @@
+require({cache:{
+'dijit/nls/cs/loading':function(){
+define(
+"dijit/nls/cs/loading", //begin v1.x content
+({
+ loadingState: "Probíhá načítání...",
+ errorState: "Omlouváme se, došlo k chybě"
+})
+//end v1.x content
+);
+
+}}});
+define("dojox/grid/nls/DataGrid_cs", [], 1);
diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_da.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_da.js
new file mode 100644
index 0000000..5c34308
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_da.js
@@ -0,0 +1,13 @@
+require({cache:{
+'dijit/nls/da/loading':function(){
+define(
+"dijit/nls/da/loading", //begin v1.x content
+({
+ loadingState: "Indlæser...",
+ errorState: "Der er opstået en fejl"
+})
+//end v1.x content
+);
+
+}}});
+define("dojox/grid/nls/DataGrid_da", [], 1);
diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_de-de.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_de-de.js
new file mode 100644
index 0000000..accf1f4
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_de-de.js
@@ -0,0 +1,16 @@
+require({cache:{
+'dijit/nls/de/loading':function(){
+define(
+"dijit/nls/de/loading", //begin v1.x content
+({
+ loadingState: "Wird geladen...",
+ errorState: "Es ist ein Fehler aufgetreten."
+})
+//end v1.x content
+);
+
+},
+'dijit/nls/de-de/loading':function(){
+define('dijit/nls/de-de/loading',{});
+}}});
+define("dojox/grid/nls/DataGrid_de-de", [], 1);
diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_el.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_el.js
new file mode 100644
index 0000000..4435820
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_el.js
@@ -0,0 +1,13 @@
+require({cache:{
+'dijit/nls/el/loading':function(){
+define(
+"dijit/nls/el/loading", //begin v1.x content
+({
+ loadingState: "Φόρτωση...",
+ errorState: "Σας ζητούμε συγνώμη, παρουσιάστηκε σφάλμα"
+})
+//end v1.x content
+);
+
+}}});
+define("dojox/grid/nls/DataGrid_el", [], 1);
diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_en-gb.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_en-gb.js
new file mode 100644
index 0000000..8f29801
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_en-gb.js
@@ -0,0 +1,8 @@
+require({cache:{
+'dijit/nls/en/loading':function(){
+define('dijit/nls/en/loading',{});
+},
+'dijit/nls/en-gb/loading':function(){
+define('dijit/nls/en-gb/loading',{});
+}}});
+define("dojox/grid/nls/DataGrid_en-gb", [], 1);
diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_en-us.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_en-us.js
new file mode 100644
index 0000000..b976308
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_en-us.js
@@ -0,0 +1,8 @@
+require({cache:{
+'dijit/nls/en/loading':function(){
+define('dijit/nls/en/loading',{});
+},
+'dijit/nls/en-us/loading':function(){
+define('dijit/nls/en-us/loading',{});
+}}});
+define("dojox/grid/nls/DataGrid_en-us", [], 1);
diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_es-es.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_es-es.js
new file mode 100644
index 0000000..28678e3
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_es-es.js
@@ -0,0 +1,16 @@
+require({cache:{
+'dijit/nls/es/loading':function(){
+define(
+"dijit/nls/es/loading", //begin v1.x content
+({
+ loadingState: "Cargando...",
+ errorState: "Lo siento, se ha producido un error"
+})
+//end v1.x content
+);
+
+},
+'dijit/nls/es-es/loading':function(){
+define('dijit/nls/es-es/loading',{});
+}}});
+define("dojox/grid/nls/DataGrid_es-es", [], 1);
diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_fi-fi.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_fi-fi.js
new file mode 100644
index 0000000..179a611
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_fi-fi.js
@@ -0,0 +1,16 @@
+require({cache:{
+'dijit/nls/fi/loading':function(){
+define(
+"dijit/nls/fi/loading", //begin v1.x content
+({
+ loadingState: "Lataus on meneillään...",
+ errorState: "On ilmennyt virhe."
+})
+//end v1.x content
+);
+
+},
+'dijit/nls/fi-fi/loading':function(){
+define('dijit/nls/fi-fi/loading',{});
+}}});
+define("dojox/grid/nls/DataGrid_fi-fi", [], 1);
diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_fr-fr.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_fr-fr.js
new file mode 100644
index 0000000..cc3b0b6
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_fr-fr.js
@@ -0,0 +1,16 @@
+require({cache:{
+'dijit/nls/fr/loading':function(){
+define(
+"dijit/nls/fr/loading", //begin v1.x content
+({
+ loadingState: "Chargement...",
+ errorState: "Une erreur est survenue"
+})
+//end v1.x content
+);
+
+},
+'dijit/nls/fr-fr/loading':function(){
+define('dijit/nls/fr-fr/loading',{});
+}}});
+define("dojox/grid/nls/DataGrid_fr-fr", [], 1);
diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_he-il.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_he-il.js
new file mode 100644
index 0000000..4860cea
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_he-il.js
@@ -0,0 +1,16 @@
+require({cache:{
+'dijit/nls/he/loading':function(){
+define(
+"dijit/nls/he/loading", //begin v1.x content
+({
+ loadingState: "טעינה...‏",
+ errorState: "אירעה שגיאה"
+})
+//end v1.x content
+);
+
+},
+'dijit/nls/he-il/loading':function(){
+define('dijit/nls/he-il/loading',{});
+}}});
+define("dojox/grid/nls/DataGrid_he-il", [], 1);
diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_hu.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_hu.js
new file mode 100644
index 0000000..727babd
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_hu.js
@@ -0,0 +1,13 @@
+require({cache:{
+'dijit/nls/hu/loading':function(){
+define(
+"dijit/nls/hu/loading", //begin v1.x content
+({
+ loadingState: "Betöltés...",
+ errorState: "Sajnálom, hiba történt"
+})
+//end v1.x content
+);
+
+}}});
+define("dojox/grid/nls/DataGrid_hu", [], 1);
diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_it-it.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_it-it.js
new file mode 100644
index 0000000..e1e511f
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_it-it.js
@@ -0,0 +1,16 @@
+require({cache:{
+'dijit/nls/it/loading':function(){
+define(
+"dijit/nls/it/loading", //begin v1.x content
+({
+ loadingState: "Caricamento in corso...",
+ errorState: "Si è verificato un errore"
+})
+//end v1.x content
+);
+
+},
+'dijit/nls/it-it/loading':function(){
+define('dijit/nls/it-it/loading',{});
+}}});
+define("dojox/grid/nls/DataGrid_it-it", [], 1);
diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_ja-jp.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_ja-jp.js
new file mode 100644
index 0000000..11bd0e3
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_ja-jp.js
@@ -0,0 +1,16 @@
+require({cache:{
+'dijit/nls/ja/loading':function(){
+define(
+"dijit/nls/ja/loading", //begin v1.x content
+({
+ loadingState: "ロード中...",
+ errorState: "エラーが発生しました。"
+})
+//end v1.x content
+);
+
+},
+'dijit/nls/ja-jp/loading':function(){
+define('dijit/nls/ja-jp/loading',{});
+}}});
+define("dojox/grid/nls/DataGrid_ja-jp", [], 1);
diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_ko-kr.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_ko-kr.js
new file mode 100644
index 0000000..2b41718
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_ko-kr.js
@@ -0,0 +1,16 @@
+require({cache:{
+'dijit/nls/ko/loading':function(){
+define(
+"dijit/nls/ko/loading", //begin v1.x content
+({
+ loadingState: "로드 중...",
+ errorState: "죄송합니다. 오류가 발생했습니다."
+})
+//end v1.x content
+);
+
+},
+'dijit/nls/ko-kr/loading':function(){
+define('dijit/nls/ko-kr/loading',{});
+}}});
+define("dojox/grid/nls/DataGrid_ko-kr", [], 1);
diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_nb.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_nb.js
new file mode 100644
index 0000000..5a97924
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_nb.js
@@ -0,0 +1,13 @@
+require({cache:{
+'dijit/nls/nb/loading':function(){
+define(
+"dijit/nls/nb/loading", //begin v1.x content
+({
+ loadingState: "Laster inn...",
+ errorState: "Det oppsto en feil"
+})
+//end v1.x content
+);
+
+}}});
+define("dojox/grid/nls/DataGrid_nb", [], 1);
diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_nl-nl.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_nl-nl.js
new file mode 100644
index 0000000..9ea82a6
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_nl-nl.js
@@ -0,0 +1,16 @@
+require({cache:{
+'dijit/nls/nl/loading':function(){
+define(
+"dijit/nls/nl/loading", //begin v1.x content
+({
+ loadingState: "Bezig met laden...",
+ errorState: "Er is een fout opgetreden"
+})
+//end v1.x content
+);
+
+},
+'dijit/nls/nl-nl/loading':function(){
+define('dijit/nls/nl-nl/loading',{});
+}}});
+define("dojox/grid/nls/DataGrid_nl-nl", [], 1);
diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_pl.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_pl.js
new file mode 100644
index 0000000..b05d618
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_pl.js
@@ -0,0 +1,13 @@
+require({cache:{
+'dijit/nls/pl/loading':function(){
+define(
+"dijit/nls/pl/loading", //begin v1.x content
+({
+ loadingState: "Ładowanie...",
+ errorState: "Niestety, wystąpił błąd"
+})
+//end v1.x content
+);
+
+}}});
+define("dojox/grid/nls/DataGrid_pl", [], 1);
diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_pt-br.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_pt-br.js
new file mode 100644
index 0000000..adc10b5
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_pt-br.js
@@ -0,0 +1,16 @@
+require({cache:{
+'dijit/nls/pt/loading':function(){
+define(
+"dijit/nls/pt/loading", //begin v1.x content
+({
+ loadingState: "Carregando...",
+ errorState: "Desculpe, ocorreu um erro"
+})
+//end v1.x content
+);
+
+},
+'dijit/nls/pt-br/loading':function(){
+define('dijit/nls/pt-br/loading',{});
+}}});
+define("dojox/grid/nls/DataGrid_pt-br", [], 1);
diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_pt-pt.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_pt-pt.js
new file mode 100644
index 0000000..9166a57
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_pt-pt.js
@@ -0,0 +1,24 @@
+require({cache:{
+'dijit/nls/pt/loading':function(){
+define(
+"dijit/nls/pt/loading", //begin v1.x content
+({
+ loadingState: "Carregando...",
+ errorState: "Desculpe, ocorreu um erro"
+})
+//end v1.x content
+);
+
+},
+'dijit/nls/pt-pt/loading':function(){
+define(
+"dijit/nls/pt-pt/loading", //begin v1.x content
+({
+ loadingState: "A carregar...",
+ errorState: "Lamentamos, mas ocorreu um erro"
+})
+//end v1.x content
+);
+
+}}});
+define("dojox/grid/nls/DataGrid_pt-pt", [], 1);
diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_ru.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_ru.js
new file mode 100644
index 0000000..82e1d68
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_ru.js
@@ -0,0 +1,13 @@
+require({cache:{
+'dijit/nls/ru/loading':function(){
+define(
+"dijit/nls/ru/loading", //begin v1.x content
+({
+ loadingState: "Загрузка...",
+ errorState: "Извините, возникла ошибка"
+})
+//end v1.x content
+);
+
+}}});
+define("dojox/grid/nls/DataGrid_ru", [], 1);
diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_sk.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_sk.js
new file mode 100644
index 0000000..7131b05
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_sk.js
@@ -0,0 +1,14 @@
+require({cache:{
+'dijit/nls/sk/loading':function(){
+define(
+"dijit/nls/sk/loading", //begin v1.x content
+({
+ loadingState: "Zavádzanie...",
+ errorState: "Nastala chyba"
+})
+
+//end v1.x content
+);
+
+}}});
+define("dojox/grid/nls/DataGrid_sk", [], 1);
diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_sl.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_sl.js
new file mode 100644
index 0000000..d77812e
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_sl.js
@@ -0,0 +1,13 @@
+require({cache:{
+'dijit/nls/sl/loading':function(){
+define(
+"dijit/nls/sl/loading", //begin v1.x content
+({
+ loadingState: "Nalaganje ...",
+ errorState: "Oprostite, prišlo je do napake."
+})
+//end v1.x content
+);
+
+}}});
+define("dojox/grid/nls/DataGrid_sl", [], 1);
diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_sv.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_sv.js
new file mode 100644
index 0000000..349064c
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_sv.js
@@ -0,0 +1,13 @@
+require({cache:{
+'dijit/nls/sv/loading':function(){
+define(
+"dijit/nls/sv/loading", //begin v1.x content
+({
+ loadingState: "Läser in...",
+ errorState: "Det uppstod ett fel."
+})
+//end v1.x content
+);
+
+}}});
+define("dojox/grid/nls/DataGrid_sv", [], 1);
diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_th.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_th.js
new file mode 100644
index 0000000..103309b
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_th.js
@@ -0,0 +1,14 @@
+require({cache:{
+'dijit/nls/th/loading':function(){
+define(
+"dijit/nls/th/loading", //begin v1.x content
+({
+ loadingState: "กำลังโหลด...",
+ errorState: "ขออภัย เกิดข้อผิดพลาด"
+})
+
+//end v1.x content
+);
+
+}}});
+define("dojox/grid/nls/DataGrid_th", [], 1);
diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_tr.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_tr.js
new file mode 100644
index 0000000..a90dfaa
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_tr.js
@@ -0,0 +1,13 @@
+require({cache:{
+'dijit/nls/tr/loading':function(){
+define(
+"dijit/nls/tr/loading", //begin v1.x content
+({
+ loadingState: "Yükleniyor...",
+ errorState: "Üzgünüz, bir hata oluştu"
+})
+//end v1.x content
+);
+
+}}});
+define("dojox/grid/nls/DataGrid_tr", [], 1);
diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_zh-cn.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_zh-cn.js
new file mode 100644
index 0000000..61e19ec
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_zh-cn.js
@@ -0,0 +1,16 @@
+require({cache:{
+'dijit/nls/zh/loading':function(){
+define(
+"dijit/nls/zh/loading", //begin v1.x content
+({
+ loadingState: "正在加载...",
+ errorState: "对不起,发生了错误"
+})
+//end v1.x content
+);
+
+},
+'dijit/nls/zh-cn/loading':function(){
+define('dijit/nls/zh-cn/loading',{});
+}}});
+define("dojox/grid/nls/DataGrid_zh-cn", [], 1);
diff --git a/js/dojo-1.7.2/dojox/grid/nls/DataGrid_zh-tw.js b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_zh-tw.js
new file mode 100644
index 0000000..a4aa781
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/nls/DataGrid_zh-tw.js
@@ -0,0 +1,24 @@
+require({cache:{
+'dijit/nls/zh/loading':function(){
+define(
+"dijit/nls/zh/loading", //begin v1.x content
+({
+ loadingState: "正在加载...",
+ errorState: "对不起,发生了错误"
+})
+//end v1.x content
+);
+
+},
+'dijit/nls/zh-tw/loading':function(){
+define(
+"dijit/nls/zh-tw/loading", //begin v1.x content
+({
+ loadingState: "載入中...",
+ errorState: "抱歉,發生錯誤"
+})
+//end v1.x content
+);
+
+}}});
+define("dojox/grid/nls/DataGrid_zh-tw", [], 1);
diff --git a/js/dojo-1.7.2/dojox/grid/resources/Expando.html b/js/dojo-1.7.2/dojox/grid/resources/Expando.html
new file mode 100644
index 0000000..c7e7c22
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/resources/Expando.html
@@ -0,0 +1,5 @@
+<div class="dojoxGridExpando"
+ ><div class="dojoxGridExpandoNode" dojoAttachEvent="onclick:onToggle"
+ ><div class="dojoxGridExpandoNodeInner" dojoAttachPoint="expandoInner"></div
+ ></div
+></div>
diff --git a/js/dojo-1.7.2/dojox/grid/resources/Grid.css b/js/dojo-1.7.2/dojox/grid/resources/Grid.css
new file mode 100644
index 0000000..037d906
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/resources/Grid.css
@@ -0,0 +1,415 @@
+.dojoxGrid {
+ position: relative;
+ background-color: #EBEADB;
+ font-family: Geneva, Arial, Helvetica, sans-serif;
+ -moz-outline-style: none;
+ outline: none;
+ overflow: hidden;
+ height: 0;
+}
+
+.dojoxGrid table {
+ padding: 0;
+}
+
+.dojoxGrid td {
+ -moz-outline: none;
+}
+
+/* master header */
+
+.dojoxGridMasterHeader {
+ position: relative;
+}
+
+/* master view */
+
+.dojoxGridMasterView {
+ position: relative;
+}
+
+/* master messages */
+
+.dojoxGridMasterMessages {
+ position: relative;
+ padding: 1em;
+ text-align: center;
+ background-color: white;
+}
+
+/* views */
+
+.dojoxGridView {
+ position: absolute;
+ overflow: hidden;
+}
+
+/* header */
+
+.dojoxGridHeader {
+ position: absolute;
+ overflow: hidden;
+ cursor: default;
+}
+
+.dojoxGridHeader {
+ background-color: #E8E1CF;
+}
+
+.dojoxGridHeader table {
+ text-align: center;
+}
+
+.dojoxGridHeader .dojoxGridCell {
+ border: 1px solid;
+ border-color: #F6F4EB #ACA899 #ACA899 #F6F4EB;
+ background: url(images/grid_dx_gradient.gif) #E8E1CF top repeat-x;
+ padding-bottom: 2px;
+}
+
+.dojoxGridHeader .dojoxGridCellOver {
+ background-image: none;
+ background-color: white;
+ border-bottom-color: #FEBE47;
+ margin-bottom: 0;
+ padding-bottom: 0;
+ border-bottom-width: 3px;
+}
+
+.dojoxGridHeader .dojoxGridCellFocus {
+ border: 1px dashed blue;
+}
+
+.dojoxGridHeader.dojoxGridCellFocus.dojoxGridCellOver {
+ background-image: none;
+ background-color: white;
+ border-bottom-color: #FEBE47;
+ margin-bottom: 0;
+ padding-bottom: 0;
+ border-bottom-width: 3px;
+}
+.dojoxGridArrowButtonNode {
+ display: none;
+ padding-left: 16px;
+}
+.dojoxGridArrowButtonChar {
+ display:inline;
+}
+
+/* Need to explicitly define how to treat hovering over the arrow on IE */
+.dojoxGridArrowButtonNode:hover {
+ cursor: default;
+}
+.dojoxGridArrowButtonChar:hover {
+ cursor: default;
+}
+.dojoxGridSortUp:hover {
+ cursor: default;
+}
+.dojoxGridSortDown:hover {
+ cursor: default;
+}
+
+.dijit_a11y .dojoxGridArrowButtonChar {
+ display:inline !important;
+}
+
+/* content */
+
+.dojoxGridScrollbox {
+ position: relative;
+ overflow: auto;
+ background-color: white;
+ width: 100%;
+}
+
+.dojoxGridContent {
+ position: relative;
+ overflow: hidden;
+ -moz-outline-style: none;
+ outline: none;
+}
+
+/* rowbar */
+
+.dojoxGridRowbar {
+ border: 1px solid;
+ border-color: #F6F4EB #ACA899 #ACA899 #F6F4EB;
+ border-top: none;
+ background: url(images/grid_dx_gradient.gif) #E8E1CF top repeat-x;
+}
+
+.dojoxGridRowbarInner {
+ border-top: 1px solid #F6F4EB;
+}
+
+.dojoxGridRowbarOver {
+ background-image: none;
+ background-color: white;
+ border-top-color: #FEBE47;
+ border-bottom-color: #FEBE47;
+}
+
+.dojoxGridRowbarSelected {
+ background-color: #D9E8F9;
+}
+
+/* rows */
+
+.dojoxGridRow {
+ position: relative;
+ width: 9000em;
+}
+
+.dojoxGridRow {
+ /*border: 1px solid #E8E4D8;*/
+ border: 1px solid #E8E4D8;
+ border-color: #F8F7F1;
+ /*padding: 0 0 1px 0;*/
+ border-left: none;
+ border-right: none;
+ background-color: white;
+ border-top: none;
+}
+
+.dojoxGridRowOver {
+ border-top-color: #FEBE47;
+ border-bottom-color: #FEBE47;
+ /*border-bottom-width: 2px;
+ padding-bottom: 0;*/
+ /*background-color: #FFDD9D;*/
+ /*background-color: #FDFDFD;*/
+}
+
+.dojoxGridRowOdd {
+ background-color: #FFFDF3;
+ /*background-color: #F9F7E8;*/
+}
+
+.dojoxGridRowSelected {
+ background-color: #D9E8F9;
+}
+
+.dojoxGridRowTable {
+ table-layout: fixed;
+ width: 0;
+ empty-cells: show;
+}
+.dj_ie .dojoxGridRowTable {
+ border-collapse: collapse;
+}
+
+.dojoxGridInvisible {
+ visibility: hidden;
+}
+
+.Xdojo-ie .dojoxGridInvisible {
+ display: none;
+}
+
+.dojoxGridInvisible td, .dojoxGridHeader .dojoxGridInvisible td {
+ border-top-width: 0;
+ border-bottom-width: 0;
+ padding-top: 0;
+ padding-bottom: 0;
+ height: 0;
+ overflow: hidden;
+}
+
+/* cells */
+
+.dojoxGridCell {
+ border: 1px solid;
+ border-color: #EBEADB;
+ border-right-color: #D5CDB5;
+ padding: 3px 3px 3px 3px;
+ text-align: left;
+ overflow: hidden;
+}
+
+.dojoxGridCellFocus {
+ border: 1px dashed blue;
+}
+
+.dojoxGridCellOver {
+ border: 1px dotted #FEBE47;
+}
+
+.dojoxGridCellFocus.dojoxGridCellOver {
+ border: 1px dashed green;
+}
+
+/* editing */
+
+.dojoxGridRowEditing td {
+ background-color: #F4FFF4;
+}
+
+.dojoxGridRow-inserting td {
+ background-color: #F4FFF4;
+}
+.dojoxGridRow-inflight td {
+ background-color: #F2F7B7;
+}
+.dojoxGridRow-error td {
+ background-color: #F8B8B6;
+}
+
+.dojoxGridInput, .dojoxGridSelect, .dojoxGridTextarea {
+ margin: 0;
+ padding: 0;
+ border-style: none;
+ width: 100%;
+ font-size: 100%;
+ font-family: inherit;
+}
+
+.dojoxGridHiddenFocus {
+ position: absolute;
+ top: -1000px;
+ height: 0;
+ width: 0;
+}
+
+.dijit_a11y .dojoxGridRowbarSelected {
+ border-top: 1px solid white;
+ border-bottom: 1px dashed black;
+ border-top: 0;
+ background: none;
+}
+
+.dijit_a11y .dojoxGridRowbarSelected .dojoxGridRowbarInner {
+ border: 0;
+ border-top: 1px solid white;
+}
+
+.dijit_a11y .dojoxGridRowSelected {
+ border: 1px solid black !important;
+}
+
+/* Drag and Drop */
+.dojoxGridDndAvatar {
+ font-size: 100%;
+}
+.dojoxGrid .dojoDndItemBefore {
+ border-left-color: red;
+}
+.dojoxGrid .dojoDndItemAfter {
+ border-right-color: red;
+}
+.dijit_a11y .dojoDndItemBefore {
+ border-left: double;
+}
+.dijit_a11y .dojoDndItemAfter {
+ border-right: double;
+}
+.dojoxGridDndAvatarItem td {
+ border: 1px solid;
+ border-color: #F6F4EB #ACA899 #ACA899 #F6F4EB;
+ background: url(images/grid_dx_gradient.gif) #E8E1CF top repeat-x;
+ padding: 0pt;
+ margin: 0pt;
+}
+.dojoxGridDndAvatarItem td.dojoxGridDndAvatarItemImage {
+ border: 0;
+ border-color: #F6F4EB #ACA899 #ACA899 #F6F4EB;
+ background-color: transparent;
+ padding: 3px;
+ padding-bottom: 2px;
+ margin: 0;
+}
+.dojoDndMove .dojoxGridDndAvatarItem .dojoxGridDndAvatarItemImage {
+ background-image: url(../../../dojo/resources/images/dndNoMove.png);
+ background-repeat: no-repeat;
+ background-position: center center;
+}
+.dojoDndCopy .dojoxGridDndAvatarItem .dojoxGridDndAvatarItemImage {
+ background-image: url(../../../dojo/resources/images/dndNoCopy.png);
+ background-repeat: no-repeat;
+ background-position: center center;
+}
+.dojoDndMove .dojoDndAvatarCanDrop .dojoxGridDndAvatarItem .dojoxGridDndAvatarItemImage {
+ background-image: url(../../../dojo/resources/images/dndMove.png);
+ background-repeat: no-repeat;
+ background-position: center center;
+}
+.dojoDndCopy .dojoDndAvatarCanDrop .dojoxGridDndAvatarItem .dojoxGridDndAvatarItemImage {
+ background-image: url(../../../dojo/resources/images/dndCopy.png);
+ background-repeat: no-repeat;
+ background-position: center center;
+}
+
+.dojoxGridColPlaceBottom {
+ background: transparent url(images/grid_sort_up.gif) no-repeat scroll left top;
+}
+.dojoxGridColPlaceTop {
+ background: transparent url(images/grid_sort_down.gif) no-repeat scroll left top;
+}
+
+.dojoxGridColPlaceTop, .dojoxGridColPlaceBottom {
+ font-size:1px;
+ height:6px;
+ z-index:10000;
+ top:0;
+ overflow:hidden;
+ position:absolute;
+ line-height:1px;
+ width:8px;
+}
+.dojoxGridResizeColLine {
+ width: 1px;
+ background-color: #777;
+ position: absolute;
+ cursor: col-resize;
+ z-index:10000;
+}
+.dojoxGridColNoResize,
+.dojoxGridColNoResize .dojoDndItemOver {
+ cursor: not-allowed !important;
+}
+.dojoxGridColResize,
+.dojoxGridColResize .dojoDndItemOver,
+.dojoxGridColumnResizing,
+.dojoxGridColumnResizing .dojoDndItemOver,
+.dojoxGridColumnResizing .dojoxGridHeader {
+ cursor: col-resize !important;
+}
+
+.dojoxGridColPlaceBottom {
+ background: transparent url(images/grid_sort_up.gif) no-repeat scroll left top;
+}
+.dojoxGridColPlaceTop {
+ background: transparent url(images/grid_sort_down.gif) no-repeat scroll left top;
+}
+
+.dojoxGridColPlaceTop, .dojoxGridColPlaceBottom {
+ font-size:1px;
+ height:6px;
+ z-index:10000;
+ top:0;
+ overflow:hidden;
+ position:absolute;
+ line-height:1px;
+ width:8px;
+}
+.dojoxGridResizeColLine {
+ width: 1px;
+ background-color: #777;
+ position: absolute;
+}
+
+/* Tree Grid */
+.dojoxGridExpandoCell {
+ vertical-align: middle;
+}
+.dojoxGridSummarySpan {
+ visibility: hidden;
+}
+.dojoxGridSummaryRow .dojoxGridSummarySpan,
+.dojoxGridRowCollapsed .dojoxGridSummarySpan {
+ visibility: visible;
+}
+.dojoxGridNoChildren .dojoxGridExpando {
+ visibility: hidden !important;
+ width: 0px !important;
+} \ No newline at end of file
diff --git a/js/dojo-1.7.2/dojox/grid/resources/Grid_rtl.css b/js/dojo-1.7.2/dojox/grid/resources/Grid_rtl.css
new file mode 100644
index 0000000..77d2dd5
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/resources/Grid_rtl.css
@@ -0,0 +1,15 @@
+.dj_ie .dojoxGridRtl .dojoxGridHeader table {
+ float:none;
+}
+
+.dojoxGridRtl .dojoxGridCell {
+ text-align:right;
+}
+
+.dj_ie8 .dojoxGridRtl .dojoxGridCell {
+ border-left: none;
+}
+
+.dojoxGridRtl .dojoxGridArrowButtonNode {
+ float:left;
+} \ No newline at end of file
diff --git a/js/dojo-1.7.2/dojox/grid/resources/View.html b/js/dojo-1.7.2/dojox/grid/resources/View.html
new file mode 100644
index 0000000..578b705
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/resources/View.html
@@ -0,0 +1,12 @@
+<div class="dojoxGridView" role="presentation">
+ <div class="dojoxGridHeader" dojoAttachPoint="headerNode" role="presentation">
+ <div dojoAttachPoint="headerNodeContainer" style="width:9000em" role="presentation">
+ <div dojoAttachPoint="headerContentNode" role="row"></div>
+ </div>
+ </div>
+ <input type="checkbox" class="dojoxGridHiddenFocus" dojoAttachPoint="hiddenFocusNode" role="presentation" />
+ <input type="checkbox" class="dojoxGridHiddenFocus" role="presentation" />
+ <div class="dojoxGridScrollbox" dojoAttachPoint="scrollboxNode" role="presentation">
+ <div class="dojoxGridContent" dojoAttachPoint="contentNode" hidefocus="hidefocus" role="presentation"></div>
+ </div>
+</div>
diff --git a/js/dojo-1.7.2/dojox/grid/resources/_Grid.html b/js/dojo-1.7.2/dojox/grid/resources/_Grid.html
new file mode 100644
index 0000000..2db90e1
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/resources/_Grid.html
@@ -0,0 +1,6 @@
+<div hidefocus="hidefocus" role="grid" dojoAttachEvent="onmouseout:_mouseOut">
+ <div class="dojoxGridMasterHeader" dojoAttachPoint="viewsHeaderNode" role="presentation"></div>
+ <div class="dojoxGridMasterView" dojoAttachPoint="viewsNode" role="presentation"></div>
+ <div class="dojoxGridMasterMessages" style="display: none;" dojoAttachPoint="messagesNode"></div>
+ <span dojoAttachPoint="lastFocusNode" tabindex="0"></span>
+</div>
diff --git a/js/dojo-1.7.2/dojox/grid/resources/claroGrid.css b/js/dojo-1.7.2/dojox/grid/resources/claroGrid.css
new file mode 100644
index 0000000..f15ff84
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/resources/claroGrid.css
@@ -0,0 +1,311 @@
+/* Claro styles for DataGrid */
+@import url("Grid.css");
+
+.claro .dojoxGrid {
+ margin:0px;
+ padding:0px;
+ border-collapse:collapse;
+ background-color: #fff;
+ border: 1px solid #DBDBDB;
+}
+/* messages */
+.claro .dojoxGridMasterMessages {
+ background-color: #fefefe;
+}
+.claro .dojoxGridLoading,
+.claro .dojoxGridError {
+ background-position:left center;
+ background-repeat: no-repeat;
+ padding-left:25px;
+}
+.claro .dojoxGridLoading {
+ background-image:url("../../../dijit/themes/claro/images/loadingAnimation.gif");
+}
+.claro .dojoxGridError {
+ background-image: url('../../../dijit/icons/images/commonIconsObjActEnabled.png');
+ background-position: -496px;
+ width: 16px;
+ height: 16px;
+}
+
+/* header */
+.claro .dojoxGridHeader {
+ background: transparent;
+ margin-left: -2px;
+}
+.claro .dojoxGridHeader .dojoxGridCell {
+ padding: 2px 5px;
+ vertical-align: top;
+ background: transparent;
+ border-style:solid;
+ border-width:1px;
+ border-color: #FFFFFF #BCBCBC #BCBCBC #FFFFFF;
+}
+.dj_ie6 .claro .dojoxGridHeader .dojoxGridCell {
+ border-color:#BCBCBC #BCBCBC #BCBCBC #e5edf4;
+}
+.claro .dojoxGridHeader .dojoxGridCellOver {
+ background: #9dcfff;
+}
+
+/* header sorting arrow */
+.claro .dojoxGridSortNode {
+ text-decoration:none;
+ display:block;
+ white-space: normal;
+ background: none;
+ border: none;
+ padding: 0;
+}
+.claro .dojoxGridCellOver .dojoxGridSortNode {
+ background-color:#9dcfff;
+}
+.claro .dojoxGridArrowButtonChar {
+ display:none;
+ float:right;
+}
+.claro .dojoxGridArrowButtonNode {
+ background:transparent url("../../../dijit/themes/claro/images/spriteArrows.png") no-repeat scroll left center;
+ display:block;
+ float:right;
+ height:1em;
+ margin:2px 4px 0 5px;
+ padding-left:0;
+ width:7px;
+}
+.claro .dojoxGridSortUp .dojoxGridArrowButtonNode {
+ background-position:-21px 50%;
+}
+
+/* header rows */
+.claro .dojoxGridMasterHeader {
+ background: url("images/header.png") #EDF2F7 repeat-x bottom;
+ background: -moz-linear-gradient(top, #EDF2F7, #D0DFEA);
+ background: -webkit-gradient(linear, left top, left bottom, from(#EDF2F7), to(#D0DFEA));
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#FFEDF2F7, endColorstr=#FFD0DFEA);
+ border: 1px solid #FFFFFF;
+ border-right: none;
+}
+.claro .dojoxGridMasterHeader .dojoxGridRowTable {
+ border-left: 1px solid #BCBCBC;
+ border-right: 1px solid #FFFFFF;
+ background-color: transparent;
+}
+.dj_ie .claro .dojoxGridHeader .dojoxGridRowTable {
+ border-collapse:separate;
+}
+.claro .dojoxGridHeader .dojoxGridRowTable tr {
+ background: none;
+}
+.claro .dojoxGridHeader tr:first-child .dojoxGridCell {
+ border-top: 1px solid transparent;
+}
+.claro .dojoxGridHeader:first-child .dojoxGridRowTable {
+ border-left-width: 0;
+}
+.claro .dojoxGridHeader:first-child {
+ margin-left: -1px;
+}
+/* Grid view content */
+.claro .dojoxGridScrollbox {
+ background-color: #fefefe;
+}
+
+/* rowbar - row headers */
+.claro .dojoxGridRowbar {
+ background:url("images/header.png") #e5edf4 repeat-x top;
+ border:none;
+ border-right:1px solid #BCBCBC;
+}
+.claro .dojoxGridRowbarTable {
+ background:transparent url("images/header_shadow.png") repeat-x scroll center bottom;
+}
+.dj_ie6 .claro .dojoxGridRowbar,
+.dj_ie6 .claro .dojoxGridRowbarTable {
+ background-image:none;
+}
+.claro .dojoxGridRowbarInner {
+ border:none;
+ border-bottom:1px solid #ccc;
+}
+.claro .dojoxGridRowbarOver .dojoxGridRowbarTable {
+ background-color:#abd5fd;
+}
+.claro .dojoxGridRowbarSelected {
+ background-color:#abd5fd;
+ border-right:1px solid #ccc;
+}
+
+/* rows */
+.claro .dojoxGridRow {
+ border:none;
+ background-color:#fff;
+}
+.dj_ie .claro .dojoxGridMasterView .dojoxGridRowTable {
+ border-collapse:separate;/*IE, separate is must to show the border of tr and td*/
+}
+.claro .dojoxGridRowTable tr {
+ background:url("images/row_back.png") #fff repeat-x;
+}
+.claro .dojoxGridRowOdd .dojoxGridRowTable tr {
+ background-color:#f7fcff;
+}
+.claro .dojoxGridRowSelected .dojoxGridRowTable tr {
+ background-color:#cee6fa;
+}
+
+/* cells */
+.claro .dojoxGridCell {
+ outline: none;
+ padding: 3px 5px;
+ word-wrap: break-word;
+ border:1px solid transparent;
+ border-color: transparent #E5DAC8 #E5DAC8 transparent;
+}
+.dj_ie6 .claro .dojoxGridCell {
+ border-color: #F5F5F5;
+}
+.dj_ie6 .claro .dojoxGridRowOdd .dojoxGridCell {
+ border-left-color:#f4f9fd;
+ border-right-color:#f4f9fd;
+}
+.dj_ie6 .claro .dojoxGridRowSelected .dojoxGridCell {
+ border-left-color:#d3e9fb;
+ border-right-color:#d3e9fb;
+}
+.claro .dojoxGridRowSelected .dojoxGridCell {
+ border-top:1px solid #BFD6EB;
+ border-bottom:1px solid #BFD6EB;
+}
+.claro .dojoxGridCellFocus {
+ outline: none;
+ border:1px dashed darkblue !important;
+}
+
+/* Single Affordance Hover Effect */
+.claro .dojoxGridRowOver .dojoxGridCell {
+ background:url("images/row_back.png") #ABD6FF repeat-x;
+ border-top:1px solid #769DC0;
+ border-bottom:1px solid #769DC0;
+}
+.dj_ie6 .claro .dojoxGridRowOver .dojoxGridCell,
+.dj_ie7 .claro .dojoxGridRowOver .dojoxGridCell {
+ border-left:1px solid #ABD6FF;
+ border-right:1px solid #ABD6FF;
+}
+.claro .dojoxGridRowActive .dojoxGridCell {
+ background:url("images/td_button_down.png") #7DBEFA repeat-x;
+}
+.dj_ie6 .claro .dojoxGridRowActive .dojoxGridCell,
+.dj_ie7 .claro .dojoxGridRowActive .dojoxGridCell {
+ border-left:1px solid #7DBEFA;
+ border-right:1px solid #7DBEFA;
+}
+
+/* Double Affordance Hover Effect */
+.claro .dojoxGridDoubleAffordance .dojoxGridRowOver .dojoxGridCellOver {
+ border:solid 1px #769dc0;
+ background-color:#93cafe;
+ border-collapse:separate;/*FF*/
+}
+.claro .dojoxGridDoubleAffordance .dojoxGridRowActive .dojoxGridCell{
+ background-image:url("images/row_back.png");
+}
+.claro .dojoxGridDoubleAffordance .dojoxGridRowActive .dojoxGridCellActive {
+ background:url("images/td_button_down.png") #93cafe repeat-x;
+}
+.dj_ie6 .claro .dojoxGridCell {
+ background-image:none !important;
+}
+
+/* editing */
+.claro .dojoxGridRowEditing td {
+ /* background-color: #F4FFF4; */
+ background-color: #cee6fa;
+ /* padding: 0px 3px 0px 3px; */
+}
+.claro .dojoxGridRow-inserting td {
+ background-color: #F4FFF4;
+}
+.claro .dojoxGridRow-inflight td {
+ background-color: #F2F7B7;
+}
+.claro .dojoxGridRow-error td {
+ background-color: #F8B8B6;
+}
+
+/* Drag and Drop */
+.claro .dojoxGrid .dojoDndItemBefore {
+ border-left-color: #3559ac;
+}
+.claro .dojoxGrid .dojoDndItemAfter {
+ border-right-color: #3559ac;
+}
+
+/* Tree Grid */
+.claro .dojoxGridExpando {
+ float: left;
+ height: 18px;
+ width: 18px;
+ text-align: center;
+ margin-top: -3px;
+}
+.dijitRtl .claro .dojoxGridExpando {
+ float: right;
+}
+.claro .dojoxGridExpandoCell {
+ padding-top: 5px;
+ background-position: left top !important;
+}
+.claro .dojoxGridExpandoNode {
+ background-image: url('../../../dijit/themes/claro/images/treeExpandImages.png');
+ width: 16px;
+ height: 16px;
+ cursor: pointer;
+ background-position: 1px 0px; /* for closed state */
+}
+.dj_ie6 .claro .dojoxGridExpandoNode {
+ background-image: url('../../../dijit/themes/claro/images/treeExpandImages8bit.png');
+}
+.claro .dojoxGridRowOver .dojoxGridExpandoNode {
+ background-position: -17px 0px;
+}
+.claro .dojoxGridExpandoOpened .dojoxGridExpandoNode {
+ background-position: -35px 0px;
+}
+.claro .dojoxGridRowOver .dojoxGridExpandoOpened .dojoxGridExpandoNode {
+ background-position: -53px 0px;
+}
+.claro .dojoxGridExpandoLoading .dojoxGridExpandoNode {
+ background-image: url('../../../dijit/themes/claro/images/loadingAnimation.gif');
+}
+.claro .dojoxGridTreeModel .dojoxGridNoChildren .dojoxGridExpando {
+ visibility: visible !important;
+ width: 18px !important;
+}
+.claro .dojoxGridTreeModel .dojoxGridNoChildren .dojoxGridExpandoNode,
+.dj_ie6 .claro .dojoxGridTreeModel .dojoxGridNoChildren .dojoxGridExpandoNode {
+ background-image:none;
+}
+.claro .dojoxGridExpandoNodeInner {
+ visibility: hidden;
+}
+.dijit_a11y .dojoxGridExpandoNodeInner {
+ visibility: visible;
+}
+
+.claro .dojoxGridSummaryRow .dojoxGridCell {
+ border:1px solid transparent;
+}
+.dj_ie6 .claro .dojoxGridSummaryRow .dojoxGridCell {
+ border-color:#fff
+}
+.claro tr.dojoxGridSubRowAlt {
+ background-color:#f4f9fd;
+}
+.claro .dojoxGridRowOdd tr.dojoxGridSubRowAlt {
+ background-color:#fff;
+}
+.claro .dojoxGridRow .dojoxGridRowTable tr.dojoxGridRowSelected {
+ background-color:#cee6fa;
+}
diff --git a/js/dojo-1.7.2/dojox/grid/resources/images/grid_dx_gradient.gif b/js/dojo-1.7.2/dojox/grid/resources/images/grid_dx_gradient.gif
new file mode 100644
index 0000000..57f67ba
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/resources/images/grid_dx_gradient.gif
Binary files differ
diff --git a/js/dojo-1.7.2/dojox/grid/resources/images/grid_sort_down.gif b/js/dojo-1.7.2/dojox/grid/resources/images/grid_sort_down.gif
new file mode 100644
index 0000000..7a73f82
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/resources/images/grid_sort_down.gif
Binary files differ
diff --git a/js/dojo-1.7.2/dojox/grid/resources/images/grid_sort_up.gif b/js/dojo-1.7.2/dojox/grid/resources/images/grid_sort_up.gif
new file mode 100644
index 0000000..9452da0
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/resources/images/grid_sort_up.gif
Binary files differ
diff --git a/js/dojo-1.7.2/dojox/grid/resources/images/header.png b/js/dojo-1.7.2/dojox/grid/resources/images/header.png
new file mode 100644
index 0000000..aa3e5ba
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/resources/images/header.png
Binary files differ
diff --git a/js/dojo-1.7.2/dojox/grid/resources/images/header_shadow.png b/js/dojo-1.7.2/dojox/grid/resources/images/header_shadow.png
new file mode 100644
index 0000000..59b2c83
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/resources/images/header_shadow.png
Binary files differ
diff --git a/js/dojo-1.7.2/dojox/grid/resources/images/row_back.png b/js/dojo-1.7.2/dojox/grid/resources/images/row_back.png
new file mode 100644
index 0000000..643db07
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/resources/images/row_back.png
Binary files differ
diff --git a/js/dojo-1.7.2/dojox/grid/resources/images/tabEnabled_rotated.png b/js/dojo-1.7.2/dojox/grid/resources/images/tabEnabled_rotated.png
new file mode 100644
index 0000000..e326abd
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/resources/images/tabEnabled_rotated.png
Binary files differ
diff --git a/js/dojo-1.7.2/dojox/grid/resources/images/tabHover_rotated.png b/js/dojo-1.7.2/dojox/grid/resources/images/tabHover_rotated.png
new file mode 100644
index 0000000..1a30e10
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/resources/images/tabHover_rotated.png
Binary files differ
diff --git a/js/dojo-1.7.2/dojox/grid/resources/images/td_button_down.png b/js/dojo-1.7.2/dojox/grid/resources/images/td_button_down.png
new file mode 100644
index 0000000..ab27e3e
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/resources/images/td_button_down.png
Binary files differ
diff --git a/js/dojo-1.7.2/dojox/grid/resources/nihiloGrid.css b/js/dojo-1.7.2/dojox/grid/resources/nihiloGrid.css
new file mode 100644
index 0000000..4fc1bcc
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/resources/nihiloGrid.css
@@ -0,0 +1,237 @@
+@import url("Grid.css");
+
+.nihilo .dojoxGrid {
+ background-color: #e9e9e9;
+ font-size: 0.85em; /* inherit font-family from dojo.css */
+}
+
+/* master messages */
+
+.nihilo .dojoxGridMasterMessages {
+ background-color: #fefefe;
+}
+
+/* header */
+
+.nihilo .dojoxGridHeader {
+ background-color: #e9e9e9;
+}
+
+.nihilo .dojoxGridHeader .dojoxGridCell {
+ border-width: 1px;
+ padding-bottom: 0px;
+ border-color: transparent #ACA899 #919191 transparent;
+ background: url(../../../dijit/themes/nihilo/images/titleBar.png) #e9e9e9 repeat-x top;
+ color: #000 !important;
+}
+
+.nihilo .dojoxGridHeader .dojoxGridCellOver {
+ background: url(../../../dijit/themes/nihilo/images/titleBarActive.png) #e9e9e9 repeat-x top;
+}
+
+.nihilo .dojoxGridHeader .dojoxGridCellFocus {
+ border-color: #ACA899 #919191;
+ border-style: dashed;
+}
+
+.nihilo .dojoxGridArrowButtonChar {
+ float: right;
+ display: none;
+}
+.nihilo .dojoxGridArrowButtonNode {
+ display: block !important;
+ padding-left: 0px;
+ float: right;
+ background:url("../../../dijit/themes/nihilo/images/spriteArrows.png") left center no-repeat;
+ width: 11px;
+ height: 1em;
+ margin-top: 1px;
+}
+.dj_ie6 .nihilo .dojoxGridArrowButtonNode {
+ background-image:url("../../../dijit/themes/nihilo/images/spriteArrows.gif");
+ margin-left: 0px;
+}
+
+.nihilo .dojoxGridSortUp .dojoxGridArrowButtonNode {
+ background-position: -21px;
+}
+.dijit_a11y .nihilo .dojoxGridArrowButtonNode {
+ display: none !important;
+}
+
+/* content */
+
+.nihilo .dojoxGridScrollbox {
+ background-color: #fefefe;
+}
+
+/* rowbar */
+
+.nihilo .dojoxGridRowbar {
+ border: none;
+ background: url(../../../dijit/themes/nihilo/images/titleBar.png) #e9e9e9 repeat-y right;
+ border-right: 1px solid #ccc;
+ padding: 0px;
+}
+
+.nihilo .dojoxGridRowbarInner {
+ border: none;
+ border-bottom: 1px solid #ccc;
+}
+
+.nihilo .dojoxGridRowbarOver {
+ background: url(../../../dijit/themes/nihilo/images/titleBarActive.png) #e9e9e9 repeat-y right;
+}
+
+.nihilo .dojoxGridRowbarSelected {
+ background: url(../../../dijit/themes/nihilo/images/titleBar.png) #D9E8F9 no-repeat center;
+ border-right: 1px solid #ccc;
+}
+
+/* rows */
+
+.nihilo .dojoxGridRow {
+ border: none;
+ background-color: white;
+}
+
+.nihilo .dojoxGridRowOver {
+ border-top-color: #ccc;
+ border-bottom-color: #ccc;
+}
+
+.nihilo .dojoxGridRowOver .dojoxGridCell {
+ background-color: #ffe284;
+}
+
+.nihilo .dojoxGridRowOdd {
+ background-color: #f2f5f9;
+}
+
+.nihilo .dojoxGridRowSelected {
+ background-color: #aec7e3;
+}
+
+.dijit_a11y .nihilo .dojoxGridRowSelected {
+ background-color: #aec7e3;
+ border-style: solid;
+}
+
+/* cells */
+
+.nihilo .dojoxGridCell {
+ border: 1px dotted #D5CDB5;
+ border-left-color: transparent;
+ border-top-color: transparent;
+}
+
+.dj_ff2 .nihilo .dojoxGridCell {
+ border-left-width: 0px;
+ border-top-width: 0px;
+}
+
+.dj_ie6 .nihilo .dojoxGridCell {
+ border: 1px solid white;
+ border-right: 1px solid #D5CDB5;
+}
+
+.nihilo .dojoxGridCellFocus {
+ border: 1px dashed darkblue;
+}
+
+.nihilo .dojoxGridCellOver {
+ border: 1px dotted #a6a6a6;
+}
+
+.nihilo .dojoxGridCellFocus.dojoxGridCellOver {
+ border: 1px dashed darkblue;
+}
+
+/* editing */
+
+/* FIXME: these colors are off! */
+.nihilo .dojoxGridRowEditing td {
+ /* background-color: #F4FFF4; */
+ background-color: #ffe284;
+ /* padding: 0px 3px 0px 3px; */
+}
+
+.nihilo .dojoxGridRow-inserting td {
+ background-color: #F4FFF4;
+}
+.nihilo .dojoxGridRow-inflight td {
+ background-color: #F2F7B7;
+}
+.nihilo .dojoxGridRow-error td {
+ background-color: #F8B8B6;
+}
+
+/* Drag and Drop */
+
+.nihilo .dojoxGrid .dojoDndItemBefore {
+ border-left-color: #ffe284;
+}
+.nihilo .dojoxGrid .dojoDndItemAfter {
+ border-right-color: #ffe284;
+}
+
+
+/* Tree Grid */
+.nihilo .dojoxGridExpando {
+ float: left;
+ height: 18px;
+ width: 18px;
+ text-align: center;
+ margin-top: -3px;
+}
+.dijitRtl .nihilo .dojoxGridExpando {
+ float: right;
+}
+.nihilo .dojoxGridExpandoCell {
+ padding-top: 5px;
+}
+.nihilo .dojoxGridExpandoNode {
+ height: 18px;
+ background-image: url('../../../dijit/themes/nihilo/images/spriteTree.gif');
+}
+.nihilo .dojoxGridExpandoOpened .dojoxGridExpandoNode {
+ background: url('../../../dijit/themes/nihilo/images/spriteTree.gif') no-repeat -18px top;
+}
+.nihilo .dojoxGridExpandoLoading .dojoxGridExpandoNode {
+ background: url('../../../dijit/themes/nihilo/images/treeExpand_loading.gif');
+}
+.nihilo .dojoxGridTreeModel .dojoxGridNoChildren .dojoxGridExpando {
+ visibility: visible !important;
+ width: 18px !important;
+}
+.nihilo .dojoxGridTreeModel .dojoxGridNoChildren .dojoxGridExpandoNode {
+ background: url('../../../dijit/themes/nihilo/images/spriteTree.gif') no-repeat -36px top;
+}
+.nihilo .dojoxGridExpandoNodeInner {
+ visibility: hidden;
+}
+.dijit_a11y .dojoxGridExpandoNodeInner {
+ visibility: visible;
+}
+
+.nihilo .dojoxGridSummaryRow .dojoxGridCell {
+ border-top-color: #999;
+ border-top-style: solid;
+}
+.nihilo .dojoxGridSpacerCell,
+.nihilo .dojoxGridExpandoCell,
+.nihilo .dojoxGridSummaryRow .dojoxGridSpacerCell {
+ border-color: transparent;
+ border-right-color: #D5CDB5;
+}
+.nihilo .dojoxGridSummaryRow .dojoxGridTotalCell,
+.nihilo .dojoxGridRowCollapsed .dojoxGridExpandoCell,
+.nihilo .dojoxGridTreeModel .dojoxGridExpandoCell {
+ border-bottom-color: #D5CDB5;
+}
+.nihilo .dojoxGridSubRowAlt {
+ background-color: #F8F8F8;
+}
+.nihilo .dojoxGridRowOdd .dojoxGridSubRowAlt {
+ background-color: #EDEFF3;
+}
diff --git a/js/dojo-1.7.2/dojox/grid/resources/soriaGrid.css b/js/dojo-1.7.2/dojox/grid/resources/soriaGrid.css
new file mode 100644
index 0000000..330ddf3
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/resources/soriaGrid.css
@@ -0,0 +1,245 @@
+@import url("Grid.css");
+
+.soria .dojoxGrid {
+ background-color: #e9e9e9;
+ font-size: 0.85em; /* inherit font-family from dojo.css */
+}
+
+/* master messages */
+
+.soria .dojoxGridMasterMessages {
+ background-color: #fefefe;
+}
+
+/* header */
+
+.soria .dojoxGridHeader {
+ background-color: #e9e9e9;
+}
+
+.soria .dojoxGridHeader .dojoxGridCell {
+ border-width: 1px;
+ padding-bottom: 0px;
+ border-color: transparent #ACA899 #919191 transparent;
+ background: url(../../../dijit/themes/soria/images/titleBar.png) #e9e9e9 repeat-x top;
+ color: #000 !important;
+}
+
+.soria .dojoxGridHeader .dojoxGridCellOver {
+ background: url(../../../dijit/themes/soria/images/titleBarActive.png) #e9e9e9 repeat-x top;
+}
+
+.soria .dojoxGridHeader .dojoxGridCellFocus {
+ border-color: #ACA899 #919191;
+ border-style: dashed;
+}
+
+.soria .dojoxGridArrowButtonChar {
+ float: right;
+ display: none;
+}
+.soria .dojoxGridArrowButtonNode {
+ display: block !important;
+ padding-left: 0px;
+ float: right;
+ background:url("../../../dijit/themes/soria/images/spriteArrows.png") no-repeat left center;
+ margin-top: 2px;
+ width: 11px;
+ height: 1em;
+}
+.dj_ie6 .soria .dojoxGridArrowButtonNode {
+ background-image:url("../../../dijit/themes/soria/images/spriteArrows.gif");
+ margin-left: 0px;
+}
+
+.soria .dojoxGridSortUp .dojoxGridArrowButtonNode {
+ background-position: -21px;
+}
+.dijit_a11y .soria .dojoxGridArrowButtonNode {
+ display: none !important;
+}
+
+/* content */
+
+.soria .dojoxGridScrollbox {
+ background-color: #fefefe;
+}
+
+/* rowbar */
+
+.soria .dojoxGridRowbar {
+ border: none;
+ background: url(../../../dijit/themes/soria/images/titleBar.png) #e9e9e9 repeat-y right;
+ border-right: 1px solid #ccc;
+ padding: 0px;
+}
+
+.soria .dojoxGridRowbarInner {
+ border: none;
+ border-bottom: 1px solid #ccc;
+}
+
+.soria .dojoxGridRowbarOver {
+ background: url(../../../dijit/themes/soria/images/titleBarActive.png) #e9e9e9 repeat-y right;
+}
+
+.soria .dojoxGridRowbarSelected {
+ background: url(../../../dijit/themes/soria/images/titleBar.png) #D9E8F9 no-repeat center;
+ border-right: 1px solid #ccc;
+}
+
+/* rows */
+
+.soria .dojoxGridRow {
+ border: none;
+ background-color: white;
+}
+
+.soria .dojoxGridRowOver {
+ border-top-color: #ccc;
+ border-bottom-color: #ccc;
+}
+
+.soria .dojoxGridRowOver .dojoxGridCell {
+ background-color: #60a1ea;
+ color:#fff;
+}
+
+.soria .dojoxGridRowOver .dojoxGridCell .dijit {
+ color: #000;
+}
+
+.soria .dojoxGridRowOver .dojoxGridCell .dijitDisabled {
+ color: gray;
+}
+
+.soria .dojoxGridRowOdd {
+ background-color: #f2f5f9;
+}
+
+.soria .dojoxGridRowSelected {
+ background-color: #aec7e3;
+}
+
+.dijit_a11y .soria .dojoxGridRowSelected {
+ background-color: #aec7e3;
+ border-style: solid;
+}
+
+/* cells */
+
+.soria .dojoxGridCell {
+ border: 1px dotted #D5CDB5;
+ border-left-color: transparent;
+ border-top-color: transparent;
+}
+
+.dj_ff2 .soria .dojoxGridCell {
+ border-left-width: 0px;
+ border-top-width: 0px;
+}
+
+.dj_ie6 .soria .dojoxGridCell {
+ border: 1px solid white;
+ border-right: 1px solid #D5CDB5;
+}
+
+.soria .dojoxGridCellFocus {
+ border: 1px dashed darkblue;
+}
+
+.soria .dojoxGridCellOver {
+ border: 1px dotted #a6a6a6;
+}
+
+.soria .dojoxGridCellFocus.dojoxGridCellOver {
+ border: 1px dashed darkblue;
+}
+
+/* editing */
+
+/* FIXME: these colors are off! */
+.soria .dojoxGridRowEditing td {
+ /* background-color: #F4FFF4; */
+ background-color: #60a1ea;
+ /* padding: 0px 3px 0px 3px; */
+}
+
+.soria .dojoxGridRow-inserting td {
+ background-color: #F4FFF4;
+}
+.soria .dojoxGridRow-inflight td {
+ background-color: #F2F7B7;
+}
+.soria .dojoxGridRow-error td {
+ background-color: #F8B8B6;
+}
+
+/* Drag and Drop */
+
+.soria .dojoxGrid .dojoDndItemBefore {
+ border-left-color: #4B5AAA;
+}
+.soria .dojoxGrid .dojoDndItemAfter {
+ border-right-color: #4B5AAA;
+}
+
+/* Tree Grid */
+.soria .dojoxGridExpando {
+ float: left;
+ height: 18px;
+ width: 18px;
+ text-align: center;
+ margin-top: -3px;
+}
+.dijitRtl .soria .dojoxGridExpando {
+ float: right;
+}
+.soria .dojoxGridExpandoCell {
+ padding-top: 5px;
+}
+.soria .dojoxGridExpandoNode {
+ height: 18px;
+ background-image: url('../../../dijit/themes/soria/images/spriteTree.gif');
+}
+.soria .dojoxGridExpandoOpened .dojoxGridExpandoNode {
+ background: url('../../../dijit/themes/soria/images/spriteTree.gif') no-repeat -18px top;
+}
+.soria .dojoxGridExpandoLoading .dojoxGridExpandoNode {
+ background: url('../../../dijit/themes/soria/images/treeExpand_loading.gif');
+}
+.soria .dojoxGridTreeModel .dojoxGridNoChildren .dojoxGridExpando {
+ visibility: visible !important;
+ width: 18px !important;
+}
+.soria .dojoxGridTreeModel .dojoxGridNoChildren .dojoxGridExpandoNode {
+ background: url('../../../dijit/themes/soria/images/spriteTree.gif') no-repeat -36px top;
+}
+.soria .dojoxGridExpandoNodeInner {
+ visibility: hidden;
+}
+.dijit_a11y .dojoxGridExpandoNodeInner {
+ visibility: visible;
+}
+
+.soria .dojoxGridSummaryRow .dojoxGridCell {
+ border-top-color: #999;
+ border-top-style: solid;
+}
+.soria .dojoxGridSpacerCell,
+.soria .dojoxGridExpandoCell,
+.soria .dojoxGridSummaryRow .dojoxGridSpacerCell {
+ border-color: transparent;
+ border-right-color: #D5CDB5;
+}
+.soria .dojoxGridSummaryRow .dojoxGridTotalCell,
+.soria .dojoxGridRowCollapsed .dojoxGridExpandoCell,
+.soria .dojoxGridTreeModel .dojoxGridExpandoCell {
+ border-bottom-color: #D5CDB5;
+}
+.soria .dojoxGridSubRowAlt {
+ background-color: #F8F8F8;
+}
+.soria .dojoxGridRowOdd .dojoxGridSubRowAlt {
+ background-color: #EDEFF3;
+}
diff --git a/js/dojo-1.7.2/dojox/grid/resources/tundraGrid.css b/js/dojo-1.7.2/dojox/grid/resources/tundraGrid.css
new file mode 100644
index 0000000..18ba271
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/resources/tundraGrid.css
@@ -0,0 +1,268 @@
+@import url("Grid.css");
+
+.tundra .dojoxGrid {
+ background-color: #e9e9e9;
+ font-size: 0.85em; /* inherit font-family from dojo.css */
+}
+
+/* master messages */
+
+.tundra .dojoxGridMasterMessages {
+ background-color: #fefefe;
+}
+
+.tundra .dojoxGridLoading,
+.tundra .dojoxGridError {
+ background-position:left center;
+ background-repeat: no-repeat;
+ padding-left:25px;
+}
+
+.dijitRtl .tundra .dojoxGridLoading,
+.dijitRtl .tundra .dojoxGridError,
+.dijitRtl .tundra .dojoxGridNoData {
+ background-position:right;
+ padding-right:25px;
+ padding-left:0px;
+}
+
+.tundra .dojoxGridLoading {
+ background-image: url('../../../dijit/themes/tundra/images/loading.gif');
+}
+
+.tundra .dojoxGridError {
+ background-image: url('../../../dijit/themes/tundra/images/warning.png');
+}
+
+/* header */
+
+.tundra .dojoxGridHeader {
+ background-color: #e9e9e9;
+}
+
+.tundra .dojoxGridHeader .dojoxGridCell {
+ border-width: 1px;
+ padding-bottom: 0px;
+ border-color: transparent #ACA899 #919191 transparent;
+ background: url(../../../dijit/themes/tundra/images/tabEnabled.png) #e9e9e9 repeat-x top;
+ color: #000 !important;
+}
+
+.tundra .dojoxGridHeader .dojoxGridCellOver {
+ background: url(../../../dijit/themes/tundra/images/tabHover.png) #e9e9e9 repeat-x top;
+ color: #000 !important;
+}
+.tundra .dojoxGridHeader .dojoxGridCellFocus {
+ border-color: #ACA899 #919191;
+ border-style: dashed;
+}
+.tundra .dojoxGridArrowButtonChar {
+ float: right;
+ display: none;
+}
+.tundra .dojoxGridArrowButtonNode {
+ display: block !important;
+ padding-left: 0px;
+ float: right;
+ background:url("../../../dijit/themes/tundra/images/spriteArrows.png") no-repeat left center;
+ width: 7px;
+ height: 1em;
+ margin: 2px 4px 0px 5px;
+}
+.dj_ie6 .tundra .dojoxGridArrowButtonNode {
+ background-image:url("../../../dijit/themes/tundra/images/spriteArrows.gif");
+ margin-left: 0px;
+}
+
+.tundra .dojoxGridSortUp .dojoxGridArrowButtonNode {
+ background-position: -21px;
+}
+.dijit_a11y .tundra .dojoxGridArrowButtonNode {
+ display: none !important;
+}
+
+/* content */
+
+.tundra .dojoxGridScrollbox {
+ background-color: #fefefe;
+}
+
+/* rowbar */
+
+.tundra .dojoxGridRowbar {
+ border: none;
+ background: url(images/tabEnabled_rotated.png) #e9e9e9 repeat-y right;
+ border-right: 1px solid #ccc;
+ padding: 0px;
+}
+
+.tundra .dojoxGridRowbarInner {
+ border: none;
+ border-bottom: 1px solid #ccc;
+}
+
+.tundra .dojoxGridRowbarOver {
+ background: url(images/tabHover_rotated.png) #e9e9e9 repeat-y right;
+}
+
+.tundra .dojoxGridRowbarSelected {
+ background: url(../../../dijit/themes/tundra/images/tabDisabled.png) #D8E8F9 no-repeat center;
+ border-right: 1px solid #ccc;
+}
+
+/* rows */
+
+.tundra .dojoxGridRow {
+ border: none;
+ background-color: white;
+}
+
+.tundra .dojoxGridRowOver {
+ border-top-color: #ccc;
+ border-bottom-color: #ccc;
+}
+
+.tundra .dojoxGridRowOver .dojoxGridCell {
+ background-color: #60a1ea;
+ color:#fff;
+}
+
+.tundra .dojoxGridRowOver .dojoxGridCell .dijit {
+ color: #000;
+}
+
+.tundra .dojoxGridRowOver .dojoxGridCell .dijitDisabled {
+ color: gray;
+}
+
+.tundra .dojoxGridRowOdd {
+ background-color: #f2f5f9;
+}
+
+.tundra .dojoxGridRowSelected {
+ background-color: #aec7e3 !important;
+}
+
+.dijit_a11y .tundra .dojoxGridRowSelected {
+ background-color: #aec7e3;
+ border-style: solid;
+}
+
+/* cells */
+
+.tundra .dojoxGridCell {
+ border: 1px dotted #D5CDB5;
+ border-left-color: transparent;
+ border-top-color: transparent;
+}
+
+.dj_ff2 .tundra .dojoxGridCell {
+ border-left-width: 0px;
+ border-top-width: 0px;
+}
+
+.dj_ie6 .tundra .dojoxGridCell {
+ border: 1px solid white;
+ border-right: 1px solid #D5CDB5;
+}
+
+.tundra .dojoxGridCellFocus {
+ border: 1px dashed darkblue !important;
+}
+
+.tundra .dojoxGridCellOver {
+ border: 1px dotted #a6a6a6;
+}
+
+.tundra .dojoxGridCellFocus .dojoxGridCellOver {
+ border: 1px dashed darkblue !important;
+}
+
+/* editing */
+
+/* FIXME: these colors are off! */
+.tundra .dojoxGridRowEditing td {
+ /* background-color: #F4FFF4; */
+ background-color: #60a1ea;
+ /* padding: 0px 3px 0px 3px; */
+}
+
+.tundra .dojoxGridRow-inserting td {
+ background-color: #F4FFF4;
+}
+.tundra .dojoxGridRow-inflight td {
+ background-color: #F2F7B7;
+}
+.tundra .dojoxGridRow-error td {
+ background-color: #F8B8B6;
+}
+
+/* Drag and Drop */
+
+.tundra .dojoxGrid .dojoDndItemBefore {
+ border-left-color: #3559ac;
+}
+.tundra .dojoxGrid .dojoDndItemAfter {
+ border-right-color: #3559ac;
+}
+
+/* Tree Grid */
+.tundra .dojoxGridExpando {
+ float: left;
+ height: 18px;
+ width: 18px;
+ text-align: center;
+ margin-top: -3px;
+}
+.dijitRtl .tundra .dojoxGridExpando {
+ float: right;
+}
+.tundra .dojoxGridExpandoCell {
+ padding-top: 5px;
+}
+.tundra .dojoxGridExpandoNode {
+ height: 18px;
+ background-image: url('../../../dijit/themes/tundra/images/treeExpand_plus.gif');
+}
+.tundra .dojoxGridExpandoOpened .dojoxGridExpandoNode {
+ background-image: url('../../../dijit/themes/tundra/images/treeExpand_minus.gif');
+}
+.tundra .dojoxGridExpandoLoading .dojoxGridExpandoNode {
+ background-image: url('../../../dijit/themes/tundra/images/treeExpand_loading.gif');
+}
+.tundra .dojoxGridTreeModel .dojoxGridNoChildren .dojoxGridExpando {
+ visibility: visible !important;
+ width: 18px !important;
+}
+.tundra .dojoxGridTreeModel .dojoxGridNoChildren .dojoxGridExpandoNode {
+ background-image: url('../../../dijit/themes/tundra/images/treeExpand_leaf.gif');
+ background-position: -3px;
+}
+.tundra .dojoxGridExpandoNodeInner {
+ visibility: hidden;
+}
+.dijit_a11y .dojoxGridExpandoNodeInner {
+ visibility: visible;
+}
+
+.tundra .dojoxGridSummaryRow .dojoxGridCell {
+ border-top-color: #999;
+ border-top-style: solid;
+}
+.tundra .dojoxGridSpacerCell,
+.tundra .dojoxGridExpandoCell,
+.tundra .dojoxGridSummaryRow .dojoxGridSpacerCell {
+ border-color: transparent;
+ border-right-color: #D5CDB5;
+}
+.tundra .dojoxGridSummaryRow .dojoxGridTotalCell,
+.tundra .dojoxGridRowCollapsed .dojoxGridExpandoCell,
+.tundra .dojoxGridTreeModel .dojoxGridExpandoCell {
+ border-bottom-color: #D5CDB5;
+}
+.tundra .dojoxGridSubRowAlt {
+ background-color: #F8F8F8;
+}
+.tundra .dojoxGridRowOdd .dojoxGridSubRowAlt {
+ background-color: #EDEFF3;
+}
diff --git a/js/dojo-1.7.2/dojox/grid/util.js b/js/dojo-1.7.2/dojox/grid/util.js
new file mode 100644
index 0000000..b186c85
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/grid/util.js
@@ -0,0 +1,75 @@
+//>>built
+define("dojox/grid/util", [
+ "../main",
+ "dojo/_base/lang",
+ "dojo/dom"
+], function(dojox, lang, dom){
+
+// summary: grid utility library
+ var dgu = lang.getObject("grid.util", true, dojox);
+
+ dgu.na = '...';
+ dgu.rowIndexTag = "gridRowIndex";
+ dgu.gridViewTag = "gridView";
+
+
+ dgu.fire = function(ob, ev, args){
+ var fn = ob && ev && ob[ev];
+ return fn && (args ? fn.apply(ob, args) : ob[ev]());
+ };
+
+ dgu.setStyleHeightPx = function(inElement, inHeight){
+ if(inHeight >= 0){
+ var s = inElement.style;
+ var v = inHeight + 'px';
+ if(inElement && s['height'] != v){
+ s['height'] = v;
+ }
+ }
+ };
+
+ dgu.mouseEvents = [ 'mouseover', 'mouseout', /*'mousemove',*/ 'mousedown', 'mouseup', 'click', 'dblclick', 'contextmenu' ];
+
+ dgu.keyEvents = [ 'keyup', 'keydown', 'keypress' ];
+
+ dgu.funnelEvents = function(inNode, inObject, inMethod, inEvents){
+ var evts = (inEvents ? inEvents : dgu.mouseEvents.concat(dgu.keyEvents));
+ for (var i=0, l=evts.length; i<l; i++){
+ inObject.connect(inNode, 'on' + evts[i], inMethod);
+ }
+ };
+
+ dgu.removeNode = function(inNode){
+ inNode = dom.byId(inNode);
+ inNode && inNode.parentNode && inNode.parentNode.removeChild(inNode);
+ return inNode;
+ };
+
+ dgu.arrayCompare = function(inA, inB){
+ for(var i=0,l=inA.length; i<l; i++){
+ if(inA[i] != inB[i]){return false;}
+ }
+ return (inA.length == inB.length);
+ };
+
+ dgu.arrayInsert = function(inArray, inIndex, inValue){
+ if(inArray.length <= inIndex){
+ inArray[inIndex] = inValue;
+ }else{
+ inArray.splice(inIndex, 0, inValue);
+ }
+ };
+
+ dgu.arrayRemove = function(inArray, inIndex){
+ inArray.splice(inIndex, 1);
+ };
+
+ dgu.arraySwap = function(inArray, inI, inJ){
+ var cache = inArray[inI];
+ inArray[inI] = inArray[inJ];
+ inArray[inJ] = cache;
+ };
+
+ return dojox.grid.util;
+
+}); \ No newline at end of file